1 /* 2 * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* Simple PKCS#7 processing functions */ 11 12 #include <stdio.h> 13 #include "internal/cryptlib.h" 14 #include <openssl/x509.h> 15 #include <openssl/x509v3.h> 16 17 18 #define BUFFERSIZE 4096 19 20 static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); 21 22 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, 23 BIO *data, int flags) 24 { 25 PKCS7 *p7; 26 int i; 27 28 if ((p7 = PKCS7_new()) == NULL) { 29 PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE); 30 return NULL; 31 } 32 33 if (!PKCS7_set_type(p7, NID_pkcs7_signed)) 34 goto err; 35 36 if (!PKCS7_content_new(p7, NID_pkcs7_data)) 37 goto err; 38 39 if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) { 40 PKCS7err(PKCS7_F_PKCS7_SIGN, PKCS7_R_PKCS7_ADD_SIGNER_ERROR); 41 goto err; 42 } 43 44 if (!(flags & PKCS7_NOCERTS)) { 45 for (i = 0; i < sk_X509_num(certs); i++) { 46 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) 47 goto err; 48 } 49 } 50 51 if (flags & PKCS7_DETACHED) 52 PKCS7_set_detached(p7, 1); 53 54 if (flags & (PKCS7_STREAM | PKCS7_PARTIAL)) 55 return p7; 56 57 if (PKCS7_final(p7, data, flags)) 58 return p7; 59 60 err: 61 PKCS7_free(p7); 62 return NULL; 63 } 64 65 int PKCS7_final(PKCS7 *p7, BIO *data, int flags) 66 { 67 BIO *p7bio; 68 int ret = 0; 69 70 if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) { 71 PKCS7err(PKCS7_F_PKCS7_FINAL, ERR_R_MALLOC_FAILURE); 72 return 0; 73 } 74 75 SMIME_crlf_copy(data, p7bio, flags); 76 77 (void)BIO_flush(p7bio); 78 79 if (!PKCS7_dataFinal(p7, p7bio)) { 80 PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN); 81 goto err; 82 } 83 84 ret = 1; 85 86 err: 87 BIO_free_all(p7bio); 88 89 return ret; 90 91 } 92 93 /* Check to see if a cipher exists and if so add S/MIME capabilities */ 94 95 static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) 96 { 97 if (EVP_get_cipherbynid(nid)) 98 return PKCS7_simple_smimecap(sk, nid, arg); 99 return 1; 100 } 101 102 static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) 103 { 104 if (EVP_get_digestbynid(nid)) 105 return PKCS7_simple_smimecap(sk, nid, arg); 106 return 1; 107 } 108 109 PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, 110 EVP_PKEY *pkey, const EVP_MD *md, 111 int flags) 112 { 113 PKCS7_SIGNER_INFO *si = NULL; 114 STACK_OF(X509_ALGOR) *smcap = NULL; 115 if (!X509_check_private_key(signcert, pkey)) { 116 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, 117 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 118 return NULL; 119 } 120 121 if ((si = PKCS7_add_signature(p7, signcert, pkey, md)) == NULL) { 122 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, 123 PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); 124 return NULL; 125 } 126 127 if (!(flags & PKCS7_NOCERTS)) { 128 if (!PKCS7_add_certificate(p7, signcert)) 129 goto err; 130 } 131 132 if (!(flags & PKCS7_NOATTR)) { 133 if (!PKCS7_add_attrib_content_type(si, NULL)) 134 goto err; 135 /* Add SMIMECapabilities */ 136 if (!(flags & PKCS7_NOSMIMECAP)) { 137 if ((smcap = sk_X509_ALGOR_new_null()) == NULL) { 138 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, ERR_R_MALLOC_FAILURE); 139 goto err; 140 } 141 if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) 142 || !add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1) 143 || !add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1) 144 || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) 145 || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) 146 || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) 147 || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) 148 || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) 149 || !add_cipher_smcap(smcap, NID_rc2_cbc, 128) 150 || !add_cipher_smcap(smcap, NID_rc2_cbc, 64) 151 || !add_cipher_smcap(smcap, NID_des_cbc, -1) 152 || !add_cipher_smcap(smcap, NID_rc2_cbc, 40) 153 || !PKCS7_add_attrib_smimecap(si, smcap)) 154 goto err; 155 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 156 smcap = NULL; 157 } 158 if (flags & PKCS7_REUSE_DIGEST) { 159 if (!pkcs7_copy_existing_digest(p7, si)) 160 goto err; 161 if (!(flags & PKCS7_PARTIAL) && !PKCS7_SIGNER_INFO_sign(si)) 162 goto err; 163 } 164 } 165 return si; 166 err: 167 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 168 return NULL; 169 } 170 171 /* 172 * Search for a digest matching SignerInfo digest type and if found copy 173 * across. 174 */ 175 176 static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) 177 { 178 int i; 179 STACK_OF(PKCS7_SIGNER_INFO) *sinfos; 180 PKCS7_SIGNER_INFO *sitmp; 181 ASN1_OCTET_STRING *osdig = NULL; 182 sinfos = PKCS7_get_signer_info(p7); 183 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { 184 sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i); 185 if (si == sitmp) 186 break; 187 if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0) 188 continue; 189 if (!OBJ_cmp(si->digest_alg->algorithm, sitmp->digest_alg->algorithm)) { 190 osdig = PKCS7_digest_from_attributes(sitmp->auth_attr); 191 break; 192 } 193 194 } 195 196 if (osdig) 197 return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); 198 199 PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, 200 PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); 201 return 0; 202 } 203 204 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, 205 BIO *indata, BIO *out, int flags) 206 { 207 STACK_OF(X509) *signers; 208 X509 *signer; 209 STACK_OF(PKCS7_SIGNER_INFO) *sinfos; 210 PKCS7_SIGNER_INFO *si; 211 X509_STORE_CTX *cert_ctx = NULL; 212 char *buf = NULL; 213 int i, j = 0, k, ret = 0; 214 BIO *p7bio = NULL; 215 BIO *tmpin = NULL, *tmpout = NULL; 216 217 if (!p7) { 218 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER); 219 return 0; 220 } 221 222 if (!PKCS7_type_is_signed(p7)) { 223 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE); 224 return 0; 225 } 226 227 /* Check for no data and no content: no data to verify signature */ 228 if (PKCS7_get_detached(p7) && !indata) { 229 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT); 230 return 0; 231 } 232 233 if (flags & PKCS7_NO_DUAL_CONTENT) { 234 /* 235 * This was originally "#if 0" because we thought that only old broken 236 * Netscape did this. It turns out that Authenticode uses this kind 237 * of "extended" PKCS7 format, and things like UEFI secure boot and 238 * tools like osslsigncode need it. In Authenticode the verification 239 * process is different, but the existing PKCs7 verification works. 240 */ 241 if (!PKCS7_get_detached(p7) && indata) { 242 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT); 243 return 0; 244 } 245 } 246 247 sinfos = PKCS7_get_signer_info(p7); 248 249 if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) { 250 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA); 251 return 0; 252 } 253 254 signers = PKCS7_get0_signers(p7, certs, flags); 255 if (!signers) 256 return 0; 257 258 /* Now verify the certificates */ 259 260 cert_ctx = X509_STORE_CTX_new(); 261 if (cert_ctx == NULL) 262 goto err; 263 if (!(flags & PKCS7_NOVERIFY)) 264 for (k = 0; k < sk_X509_num(signers); k++) { 265 signer = sk_X509_value(signers, k); 266 if (!(flags & PKCS7_NOCHAIN)) { 267 if (!X509_STORE_CTX_init(cert_ctx, store, signer, 268 p7->d.sign->cert)) { 269 PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); 270 goto err; 271 } 272 X509_STORE_CTX_set_default(cert_ctx, "smime_sign"); 273 } else if (!X509_STORE_CTX_init(cert_ctx, store, signer, NULL)) { 274 PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); 275 goto err; 276 } 277 if (!(flags & PKCS7_NOCRL)) 278 X509_STORE_CTX_set0_crls(cert_ctx, p7->d.sign->crl); 279 i = X509_verify_cert(cert_ctx); 280 if (i <= 0) 281 j = X509_STORE_CTX_get_error(cert_ctx); 282 X509_STORE_CTX_cleanup(cert_ctx); 283 if (i <= 0) { 284 PKCS7err(PKCS7_F_PKCS7_VERIFY, 285 PKCS7_R_CERTIFICATE_VERIFY_ERROR); 286 ERR_add_error_data(2, "Verify error:", 287 X509_verify_cert_error_string(j)); 288 goto err; 289 } 290 /* Check for revocation status here */ 291 } 292 293 /* 294 * Performance optimization: if the content is a memory BIO then store 295 * its contents in a temporary read only memory BIO. This avoids 296 * potentially large numbers of slow copies of data which will occur when 297 * reading from a read write memory BIO when signatures are calculated. 298 */ 299 300 if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) { 301 char *ptr; 302 long len; 303 len = BIO_get_mem_data(indata, &ptr); 304 tmpin = BIO_new_mem_buf(ptr, len); 305 if (tmpin == NULL) { 306 PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); 307 goto err; 308 } 309 } else 310 tmpin = indata; 311 312 if ((p7bio = PKCS7_dataInit(p7, tmpin)) == NULL) 313 goto err; 314 315 if (flags & PKCS7_TEXT) { 316 if ((tmpout = BIO_new(BIO_s_mem())) == NULL) { 317 PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); 318 goto err; 319 } 320 BIO_set_mem_eof_return(tmpout, 0); 321 } else 322 tmpout = out; 323 324 /* We now have to 'read' from p7bio to calculate digests etc. */ 325 if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) { 326 PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); 327 goto err; 328 } 329 for (;;) { 330 i = BIO_read(p7bio, buf, BUFFERSIZE); 331 if (i <= 0) 332 break; 333 if (tmpout) 334 BIO_write(tmpout, buf, i); 335 } 336 337 if (flags & PKCS7_TEXT) { 338 if (!SMIME_text(tmpout, out)) { 339 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SMIME_TEXT_ERROR); 340 BIO_free(tmpout); 341 goto err; 342 } 343 BIO_free(tmpout); 344 } 345 346 /* Now Verify All Signatures */ 347 if (!(flags & PKCS7_NOSIGS)) 348 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { 349 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); 350 signer = sk_X509_value(signers, i); 351 j = PKCS7_signatureVerify(p7bio, p7, si, signer); 352 if (j <= 0) { 353 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE); 354 goto err; 355 } 356 } 357 358 ret = 1; 359 360 err: 361 X509_STORE_CTX_free(cert_ctx); 362 OPENSSL_free(buf); 363 if (tmpin == indata) { 364 if (indata) 365 BIO_pop(p7bio); 366 } 367 BIO_free_all(p7bio); 368 sk_X509_free(signers); 369 return ret; 370 } 371 372 STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, 373 int flags) 374 { 375 STACK_OF(X509) *signers; 376 STACK_OF(PKCS7_SIGNER_INFO) *sinfos; 377 PKCS7_SIGNER_INFO *si; 378 PKCS7_ISSUER_AND_SERIAL *ias; 379 X509 *signer; 380 int i; 381 382 if (!p7) { 383 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_INVALID_NULL_POINTER); 384 return NULL; 385 } 386 387 if (!PKCS7_type_is_signed(p7)) { 388 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_WRONG_CONTENT_TYPE); 389 return NULL; 390 } 391 392 /* Collect all the signers together */ 393 394 sinfos = PKCS7_get_signer_info(p7); 395 396 if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { 397 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_NO_SIGNERS); 398 return 0; 399 } 400 401 if ((signers = sk_X509_new_null()) == NULL) { 402 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, ERR_R_MALLOC_FAILURE); 403 return NULL; 404 } 405 406 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { 407 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); 408 ias = si->issuer_and_serial; 409 signer = NULL; 410 /* If any certificates passed they take priority */ 411 if (certs) 412 signer = X509_find_by_issuer_and_serial(certs, 413 ias->issuer, ias->serial); 414 if (!signer && !(flags & PKCS7_NOINTERN) 415 && p7->d.sign->cert) 416 signer = 417 X509_find_by_issuer_and_serial(p7->d.sign->cert, 418 ias->issuer, ias->serial); 419 if (!signer) { 420 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, 421 PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); 422 sk_X509_free(signers); 423 return 0; 424 } 425 426 if (!sk_X509_push(signers, signer)) { 427 sk_X509_free(signers); 428 return NULL; 429 } 430 } 431 return signers; 432 } 433 434 /* Build a complete PKCS#7 enveloped data */ 435 436 PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, 437 int flags) 438 { 439 PKCS7 *p7; 440 BIO *p7bio = NULL; 441 int i; 442 X509 *x509; 443 if ((p7 = PKCS7_new()) == NULL) { 444 PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE); 445 return NULL; 446 } 447 448 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) 449 goto err; 450 if (!PKCS7_set_cipher(p7, cipher)) { 451 PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER); 452 goto err; 453 } 454 455 for (i = 0; i < sk_X509_num(certs); i++) { 456 x509 = sk_X509_value(certs, i); 457 if (!PKCS7_add_recipient(p7, x509)) { 458 PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_ADDING_RECIPIENT); 459 goto err; 460 } 461 } 462 463 if (flags & PKCS7_STREAM) 464 return p7; 465 466 if (PKCS7_final(p7, in, flags)) 467 return p7; 468 469 err: 470 471 BIO_free_all(p7bio); 472 PKCS7_free(p7); 473 return NULL; 474 475 } 476 477 int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) 478 { 479 BIO *tmpmem; 480 int ret = 0, i; 481 char *buf = NULL; 482 483 if (!p7) { 484 PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER); 485 return 0; 486 } 487 488 if (!PKCS7_type_is_enveloped(p7)) { 489 PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_WRONG_CONTENT_TYPE); 490 return 0; 491 } 492 493 if (cert && !X509_check_private_key(cert, pkey)) { 494 PKCS7err(PKCS7_F_PKCS7_DECRYPT, 495 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 496 return 0; 497 } 498 499 if ((tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert)) == NULL) { 500 PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR); 501 return 0; 502 } 503 504 if (flags & PKCS7_TEXT) { 505 BIO *tmpbuf, *bread; 506 /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ 507 if ((tmpbuf = BIO_new(BIO_f_buffer())) == NULL) { 508 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); 509 BIO_free_all(tmpmem); 510 return 0; 511 } 512 if ((bread = BIO_push(tmpbuf, tmpmem)) == NULL) { 513 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); 514 BIO_free_all(tmpbuf); 515 BIO_free_all(tmpmem); 516 return 0; 517 } 518 ret = SMIME_text(bread, data); 519 if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { 520 if (!BIO_get_cipher_status(tmpmem)) 521 ret = 0; 522 } 523 BIO_free_all(bread); 524 return ret; 525 } 526 if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) { 527 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); 528 goto err; 529 } 530 for (;;) { 531 i = BIO_read(tmpmem, buf, BUFFERSIZE); 532 if (i <= 0) { 533 ret = 1; 534 if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { 535 if (!BIO_get_cipher_status(tmpmem)) 536 ret = 0; 537 } 538 539 break; 540 } 541 if (BIO_write(data, buf, i) != i) { 542 break; 543 } 544 } 545 err: 546 OPENSSL_free(buf); 547 BIO_free_all(tmpmem); 548 return ret; 549 } 550