1 /* $OpenBSD: pk7_doit.c,v 1.57 2024/11/30 10:01:31 tb Exp $ */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59 #include <stdio.h> 60 #include <stdlib.h> 61 #include <string.h> 62 63 #include <openssl/err.h> 64 #include <openssl/objects.h> 65 #include <openssl/x509.h> 66 #include <openssl/x509v3.h> 67 68 #include "evp_local.h" 69 #include "x509_local.h" 70 71 static int 72 PKCS7_type_is_other(PKCS7* p7) 73 { 74 int isOther = 1; 75 76 int nid = OBJ_obj2nid(p7->type); 77 78 switch (nid ) { 79 case NID_pkcs7_data: 80 case NID_pkcs7_signed: 81 case NID_pkcs7_enveloped: 82 case NID_pkcs7_signedAndEnveloped: 83 case NID_pkcs7_digest: 84 case NID_pkcs7_encrypted: 85 isOther = 0; 86 break; 87 default: 88 isOther = 1; 89 } 90 91 return isOther; 92 93 } 94 95 ASN1_OCTET_STRING * 96 PKCS7_get_octet_string(PKCS7 *p7) 97 { 98 if (PKCS7_type_is_data(p7)) 99 return p7->d.data; 100 if (PKCS7_type_is_other(p7) && p7->d.other && 101 (p7->d.other->type == V_ASN1_OCTET_STRING)) 102 return p7->d.other->value.octet_string; 103 return NULL; 104 } 105 106 static int 107 PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) 108 { 109 BIO *btmp; 110 const EVP_MD *md; 111 112 if ((btmp = BIO_new(BIO_f_md())) == NULL) { 113 PKCS7error(ERR_R_BIO_LIB); 114 goto err; 115 } 116 117 md = EVP_get_digestbyobj(alg->algorithm); 118 if (md == NULL) { 119 PKCS7error(PKCS7_R_UNKNOWN_DIGEST_TYPE); 120 goto err; 121 } 122 123 if (BIO_set_md(btmp, md) <= 0) { 124 PKCS7error(ERR_R_BIO_LIB); 125 goto err; 126 } 127 128 if (*pbio == NULL) 129 *pbio = btmp; 130 else if (!BIO_push(*pbio, btmp)) { 131 PKCS7error(ERR_R_BIO_LIB); 132 goto err; 133 } 134 btmp = NULL; 135 136 return 1; 137 138 err: 139 BIO_free(btmp); 140 return 0; 141 142 } 143 144 static int 145 pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, unsigned char *key, int keylen) 146 { 147 EVP_PKEY_CTX *pctx = NULL; 148 EVP_PKEY *pkey = NULL; 149 unsigned char *ek = NULL; 150 int ret = 0; 151 size_t eklen; 152 153 pkey = X509_get_pubkey(ri->cert); 154 if (!pkey) 155 return 0; 156 157 pctx = EVP_PKEY_CTX_new(pkey, NULL); 158 if (!pctx) 159 return 0; 160 161 if (EVP_PKEY_encrypt_init(pctx) <= 0) 162 goto err; 163 164 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, 165 EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) { 166 PKCS7error(PKCS7_R_CTRL_ERROR); 167 goto err; 168 } 169 170 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0) 171 goto err; 172 173 ek = malloc(eklen); 174 175 if (ek == NULL) { 176 PKCS7error(ERR_R_MALLOC_FAILURE); 177 goto err; 178 } 179 180 if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0) 181 goto err; 182 183 ASN1_STRING_set0(ri->enc_key, ek, eklen); 184 ek = NULL; 185 186 ret = 1; 187 188 err: 189 EVP_PKEY_free(pkey); 190 EVP_PKEY_CTX_free(pctx); 191 free(ek); 192 return ret; 193 } 194 195 196 static int 197 pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, PKCS7_RECIP_INFO *ri, 198 EVP_PKEY *pkey, size_t fixlen) 199 { 200 EVP_PKEY_CTX *pctx = NULL; 201 unsigned char *ek = NULL; 202 size_t eklen; 203 204 int ret = -1; 205 206 pctx = EVP_PKEY_CTX_new(pkey, NULL); 207 if (!pctx) 208 return -1; 209 210 if (EVP_PKEY_decrypt_init(pctx) <= 0) 211 goto err; 212 213 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, 214 EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) { 215 PKCS7error(PKCS7_R_CTRL_ERROR); 216 goto err; 217 } 218 219 if (EVP_PKEY_decrypt(pctx, NULL, &eklen, 220 ri->enc_key->data, ri->enc_key->length) <= 0) 221 goto err; 222 223 ek = malloc(eklen); 224 if (ek == NULL) { 225 PKCS7error(ERR_R_MALLOC_FAILURE); 226 goto err; 227 } 228 229 if (EVP_PKEY_decrypt(pctx, ek, &eklen, ri->enc_key->data, 230 ri->enc_key->length) <= 0 || eklen == 0 || 231 (fixlen != 0 && eklen != fixlen)) { 232 ret = 0; 233 PKCS7error(ERR_R_EVP_LIB); 234 goto err; 235 } 236 237 ret = 1; 238 239 freezero(*pek, *peklen); 240 241 *pek = ek; 242 *peklen = eklen; 243 244 err: 245 EVP_PKEY_CTX_free(pctx); 246 if (!ret && ek) 247 free(ek); 248 249 return ret; 250 } 251 252 BIO * 253 PKCS7_dataInit(PKCS7 *p7, BIO *bio) 254 { 255 int i; 256 BIO *out = NULL, *btmp = NULL; 257 X509_ALGOR *xa = NULL; 258 const EVP_CIPHER *evp_cipher = NULL; 259 STACK_OF(X509_ALGOR) *md_sk = NULL; 260 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; 261 X509_ALGOR *xalg = NULL; 262 PKCS7_RECIP_INFO *ri = NULL; 263 ASN1_OCTET_STRING *os = NULL; 264 265 if (p7 == NULL) { 266 PKCS7error(PKCS7_R_INVALID_NULL_POINTER); 267 return NULL; 268 } 269 270 /* 271 * The content field in the PKCS7 ContentInfo is optional, 272 * but that really only applies to inner content (precisely, 273 * detached signatures). 274 * 275 * When reading content, missing outer content is therefore 276 * treated as an error. 277 * 278 * When creating content, PKCS7_content_new() must be called 279 * before calling this method, so a NULL p7->d is always 280 * an error. 281 */ 282 if (p7->d.ptr == NULL) { 283 PKCS7error(PKCS7_R_NO_CONTENT); 284 return NULL; 285 } 286 287 i = OBJ_obj2nid(p7->type); 288 p7->state = PKCS7_S_HEADER; 289 290 switch (i) { 291 case NID_pkcs7_signed: 292 md_sk = p7->d.sign->md_algs; 293 os = PKCS7_get_octet_string(p7->d.sign->contents); 294 break; 295 case NID_pkcs7_signedAndEnveloped: 296 rsk = p7->d.signed_and_enveloped->recipientinfo; 297 md_sk = p7->d.signed_and_enveloped->md_algs; 298 xalg = p7->d.signed_and_enveloped->enc_data->algorithm; 299 evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; 300 if (evp_cipher == NULL) { 301 PKCS7error(PKCS7_R_CIPHER_NOT_INITIALIZED); 302 goto err; 303 } 304 break; 305 case NID_pkcs7_enveloped: 306 rsk = p7->d.enveloped->recipientinfo; 307 xalg = p7->d.enveloped->enc_data->algorithm; 308 evp_cipher = p7->d.enveloped->enc_data->cipher; 309 if (evp_cipher == NULL) { 310 PKCS7error(PKCS7_R_CIPHER_NOT_INITIALIZED); 311 goto err; 312 } 313 break; 314 case NID_pkcs7_digest: 315 xa = p7->d.digest->md; 316 os = PKCS7_get_octet_string(p7->d.digest->contents); 317 break; 318 case NID_pkcs7_data: 319 break; 320 default: 321 PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 322 goto err; 323 } 324 325 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) 326 if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) 327 goto err; 328 329 if (xa && !PKCS7_bio_add_digest(&out, xa)) 330 goto err; 331 332 if (evp_cipher != NULL) { 333 unsigned char key[EVP_MAX_KEY_LENGTH]; 334 unsigned char iv[EVP_MAX_IV_LENGTH]; 335 int keylen, ivlen; 336 EVP_CIPHER_CTX *ctx; 337 338 if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { 339 PKCS7error(ERR_R_BIO_LIB); 340 goto err; 341 } 342 BIO_get_cipher_ctx(btmp, &ctx); 343 keylen = EVP_CIPHER_key_length(evp_cipher); 344 ivlen = EVP_CIPHER_iv_length(evp_cipher); 345 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); 346 if (ivlen > 0) 347 arc4random_buf(iv, ivlen); 348 if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, 349 NULL, 1) <= 0) 350 goto err; 351 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) 352 goto err; 353 if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) 354 goto err; 355 356 if (ivlen > 0) { 357 if (xalg->parameter == NULL) { 358 xalg->parameter = ASN1_TYPE_new(); 359 if (xalg->parameter == NULL) 360 goto err; 361 } 362 if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) 363 goto err; 364 } 365 366 /* Lets do the pub key stuff :-) */ 367 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { 368 ri = sk_PKCS7_RECIP_INFO_value(rsk, i); 369 if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) 370 goto err; 371 } 372 explicit_bzero(key, keylen); 373 374 if (out == NULL) 375 out = btmp; 376 else 377 BIO_push(out, btmp); 378 btmp = NULL; 379 } 380 381 if (bio == NULL) { 382 if (PKCS7_is_detached(p7)) 383 bio = BIO_new(BIO_s_null()); 384 else if (os && os->length > 0) 385 bio = BIO_new_mem_buf(os->data, os->length); 386 if (bio == NULL) { 387 bio = BIO_new(BIO_s_mem()); 388 if (bio == NULL) 389 goto err; 390 BIO_set_mem_eof_return(bio, 0); 391 } 392 } 393 if (out) 394 BIO_push(out, bio); 395 else 396 out = bio; 397 bio = NULL; 398 if (0) { 399 err: 400 if (out != NULL) 401 BIO_free_all(out); 402 if (btmp != NULL) 403 BIO_free_all(btmp); 404 out = NULL; 405 } 406 return out; 407 } 408 LCRYPTO_ALIAS(PKCS7_dataInit); 409 410 static int 411 pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) 412 { 413 int ret; 414 415 ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, 416 pcert->cert_info->issuer); 417 if (ret) 418 return ret; 419 return ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, 420 ri->issuer_and_serial->serial); 421 } 422 423 /* int */ 424 BIO * 425 PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) 426 { 427 int i, j; 428 BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; 429 X509_ALGOR *xa; 430 ASN1_OCTET_STRING *data_body = NULL; 431 const EVP_MD *evp_md; 432 const EVP_CIPHER *evp_cipher = NULL; 433 EVP_CIPHER_CTX *evp_ctx = NULL; 434 X509_ALGOR *enc_alg = NULL; 435 STACK_OF(X509_ALGOR) *md_sk = NULL; 436 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; 437 PKCS7_RECIP_INFO *ri = NULL; 438 unsigned char *ek = NULL, *tkey = NULL; 439 int eklen = 0, tkeylen = 0; 440 441 if (p7 == NULL) { 442 PKCS7error(PKCS7_R_INVALID_NULL_POINTER); 443 return NULL; 444 } 445 446 if (p7->d.ptr == NULL) { 447 PKCS7error(PKCS7_R_NO_CONTENT); 448 return NULL; 449 } 450 451 i = OBJ_obj2nid(p7->type); 452 p7->state = PKCS7_S_HEADER; 453 454 switch (i) { 455 case NID_pkcs7_signed: 456 data_body = PKCS7_get_octet_string(p7->d.sign->contents); 457 md_sk = p7->d.sign->md_algs; 458 break; 459 case NID_pkcs7_signedAndEnveloped: 460 rsk = p7->d.signed_and_enveloped->recipientinfo; 461 md_sk = p7->d.signed_and_enveloped->md_algs; 462 data_body = p7->d.signed_and_enveloped->enc_data->enc_data; 463 enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; 464 evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); 465 if (evp_cipher == NULL) { 466 PKCS7error(PKCS7_R_UNSUPPORTED_CIPHER_TYPE); 467 goto err; 468 } 469 break; 470 case NID_pkcs7_enveloped: 471 rsk = p7->d.enveloped->recipientinfo; 472 enc_alg = p7->d.enveloped->enc_data->algorithm; 473 data_body = p7->d.enveloped->enc_data->enc_data; 474 evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); 475 if (evp_cipher == NULL) { 476 PKCS7error(PKCS7_R_UNSUPPORTED_CIPHER_TYPE); 477 goto err; 478 } 479 break; 480 default: 481 PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 482 goto err; 483 } 484 485 /* We will be checking the signature */ 486 if (md_sk != NULL) { 487 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { 488 xa = sk_X509_ALGOR_value(md_sk, i); 489 if ((btmp = BIO_new(BIO_f_md())) == NULL) { 490 PKCS7error(ERR_R_BIO_LIB); 491 goto err; 492 } 493 494 j = OBJ_obj2nid(xa->algorithm); 495 evp_md = EVP_get_digestbynid(j); 496 if (evp_md == NULL) { 497 PKCS7error(PKCS7_R_UNKNOWN_DIGEST_TYPE); 498 goto err; 499 } 500 501 if (BIO_set_md(btmp, evp_md) <= 0) { 502 PKCS7error(ERR_R_BIO_LIB); 503 goto err; 504 } 505 if (out == NULL) 506 out = btmp; 507 else 508 BIO_push(out, btmp); 509 btmp = NULL; 510 } 511 } 512 513 if (evp_cipher != NULL) { 514 if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { 515 PKCS7error(ERR_R_BIO_LIB); 516 goto err; 517 } 518 519 /* It was encrypted, we need to decrypt the secret key 520 * with the private key */ 521 522 /* Find the recipientInfo which matches the passed certificate 523 * (if any) 524 */ 525 if (pcert) { 526 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { 527 ri = sk_PKCS7_RECIP_INFO_value(rsk, i); 528 if (!pkcs7_cmp_ri(ri, pcert)) 529 break; 530 ri = NULL; 531 } 532 if (ri == NULL) { 533 PKCS7error(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); 534 goto err; 535 } 536 } 537 538 /* If we haven't got a certificate try each ri in turn */ 539 if (pcert == NULL) { 540 /* Always attempt to decrypt all rinfo even 541 * after success as a defence against MMA timing 542 * attacks. 543 */ 544 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { 545 ri = sk_PKCS7_RECIP_INFO_value(rsk, i); 546 547 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 548 EVP_CIPHER_key_length(evp_cipher)) < 0) 549 goto err; 550 ERR_clear_error(); 551 } 552 } else { 553 /* Only exit on fatal errors, not decrypt failure */ 554 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0) 555 goto err; 556 ERR_clear_error(); 557 } 558 559 evp_ctx = NULL; 560 BIO_get_cipher_ctx(etmp, &evp_ctx); 561 if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, 562 NULL, 0) <= 0) 563 goto err; 564 if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) 565 goto err; 566 /* Generate random key as MMA defence */ 567 tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); 568 tkey = malloc(tkeylen); 569 if (!tkey) 570 goto err; 571 if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) 572 goto err; 573 if (ek == NULL) { 574 ek = tkey; 575 eklen = tkeylen; 576 tkey = NULL; 577 } 578 579 if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { 580 /* Some S/MIME clients don't use the same key 581 * and effective key length. The key length is 582 * determined by the size of the decrypted RSA key. 583 */ 584 if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { 585 /* Use random key as MMA defence */ 586 freezero(ek, eklen); 587 ek = tkey; 588 eklen = tkeylen; 589 tkey = NULL; 590 } 591 } 592 /* Clear errors so we don't leak information useful in MMA */ 593 ERR_clear_error(); 594 if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0) 595 goto err; 596 597 freezero(ek, eklen); 598 ek = NULL; 599 freezero(tkey, tkeylen); 600 tkey = NULL; 601 602 if (out == NULL) 603 out = etmp; 604 else 605 BIO_push(out, etmp); 606 etmp = NULL; 607 } 608 609 if (PKCS7_is_detached(p7) || (in_bio != NULL)) { 610 bio = in_bio; 611 } else { 612 if (data_body != NULL && data_body->length > 0) 613 bio = BIO_new_mem_buf(data_body->data, data_body->length); 614 else { 615 bio = BIO_new(BIO_s_mem()); 616 BIO_set_mem_eof_return(bio, 0); 617 } 618 if (bio == NULL) 619 goto err; 620 } 621 BIO_push(out, bio); 622 623 if (0) { 624 err: 625 freezero(ek, eklen); 626 freezero(tkey, tkeylen); 627 if (out != NULL) 628 BIO_free_all(out); 629 if (btmp != NULL) 630 BIO_free_all(btmp); 631 if (etmp != NULL) 632 BIO_free_all(etmp); 633 out = NULL; 634 } 635 return out; 636 } 637 LCRYPTO_ALIAS(PKCS7_dataDecode); 638 639 static BIO * 640 PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) 641 { 642 for (;;) { 643 bio = BIO_find_type(bio, BIO_TYPE_MD); 644 if (bio == NULL) { 645 PKCS7error(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 646 return NULL; 647 } 648 BIO_get_md_ctx(bio, pmd); 649 if (*pmd == NULL) { 650 PKCS7error(ERR_R_INTERNAL_ERROR); 651 return NULL; 652 } 653 if (EVP_MD_CTX_type(*pmd) == nid) 654 return bio; 655 bio = BIO_next(bio); 656 } 657 return NULL; 658 } 659 660 static int 661 do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) 662 { 663 unsigned char md_data[EVP_MAX_MD_SIZE]; 664 unsigned int md_len; 665 666 /* Add signing time if not already present */ 667 if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { 668 if (!PKCS7_add0_attrib_signing_time(si, NULL)) { 669 PKCS7error(ERR_R_MALLOC_FAILURE); 670 return 0; 671 } 672 } 673 674 /* Add digest */ 675 if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) { 676 PKCS7error(ERR_R_EVP_LIB); 677 return 0; 678 } 679 if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) { 680 PKCS7error(ERR_R_MALLOC_FAILURE); 681 return 0; 682 } 683 684 /* Now sign the attributes */ 685 if (!PKCS7_SIGNER_INFO_sign(si)) 686 return 0; 687 688 return 1; 689 } 690 691 692 int 693 PKCS7_dataFinal(PKCS7 *p7, BIO *bio) 694 { 695 int ret = 0; 696 int i, j; 697 BIO *btmp; 698 PKCS7_SIGNER_INFO *si; 699 EVP_MD_CTX *mdc, ctx_tmp; 700 STACK_OF(X509_ATTRIBUTE) *sk; 701 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; 702 ASN1_OCTET_STRING *os = NULL; 703 704 if (p7 == NULL) { 705 PKCS7error(PKCS7_R_INVALID_NULL_POINTER); 706 return 0; 707 } 708 709 if (p7->d.ptr == NULL) { 710 PKCS7error(PKCS7_R_NO_CONTENT); 711 return 0; 712 } 713 714 EVP_MD_CTX_legacy_clear(&ctx_tmp); 715 i = OBJ_obj2nid(p7->type); 716 p7->state = PKCS7_S_HEADER; 717 718 switch (i) { 719 case NID_pkcs7_data: 720 os = p7->d.data; 721 break; 722 case NID_pkcs7_signedAndEnveloped: 723 /* XXX */ 724 si_sk = p7->d.signed_and_enveloped->signer_info; 725 os = p7->d.signed_and_enveloped->enc_data->enc_data; 726 if (!os) { 727 os = ASN1_OCTET_STRING_new(); 728 if (!os) { 729 PKCS7error(ERR_R_MALLOC_FAILURE); 730 goto err; 731 } 732 p7->d.signed_and_enveloped->enc_data->enc_data = os; 733 } 734 break; 735 case NID_pkcs7_enveloped: 736 /* XXX */ 737 os = p7->d.enveloped->enc_data->enc_data; 738 if (!os) { 739 os = ASN1_OCTET_STRING_new(); 740 if (!os) { 741 PKCS7error(ERR_R_MALLOC_FAILURE); 742 goto err; 743 } 744 p7->d.enveloped->enc_data->enc_data = os; 745 } 746 break; 747 case NID_pkcs7_signed: 748 si_sk = p7->d.sign->signer_info; 749 os = PKCS7_get_octet_string(p7->d.sign->contents); 750 if (!PKCS7_is_detached(p7) && os == NULL) { 751 PKCS7error(PKCS7_R_DECODE_ERROR); 752 goto err; 753 } 754 /* If detached data then the content is excluded */ 755 if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { 756 ASN1_OCTET_STRING_free(os); 757 os = NULL; 758 p7->d.sign->contents->d.data = NULL; 759 } 760 break; 761 762 case NID_pkcs7_digest: 763 os = PKCS7_get_octet_string(p7->d.digest->contents); 764 if (os == NULL) { 765 PKCS7error(PKCS7_R_DECODE_ERROR); 766 goto err; 767 } 768 /* If detached data then the content is excluded */ 769 if (PKCS7_type_is_data(p7->d.digest->contents) && 770 p7->detached) { 771 ASN1_OCTET_STRING_free(os); 772 os = NULL; 773 p7->d.digest->contents->d.data = NULL; 774 } 775 break; 776 777 default: 778 PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 779 goto err; 780 } 781 782 if (si_sk != NULL) { 783 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) { 784 si = sk_PKCS7_SIGNER_INFO_value(si_sk, i); 785 if (si->pkey == NULL) 786 continue; 787 788 j = OBJ_obj2nid(si->digest_alg->algorithm); 789 790 if ((btmp = PKCS7_find_digest(&mdc, bio, j)) == NULL) 791 goto err; 792 793 /* We now have the EVP_MD_CTX, lets do the 794 * signing. */ 795 if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc)) 796 goto err; 797 798 sk = si->auth_attr; 799 800 /* If there are attributes, we add the digest 801 * attribute and only sign the attributes */ 802 if (sk_X509_ATTRIBUTE_num(sk) > 0) { 803 if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) 804 goto err; 805 } else { 806 unsigned char *abuf = NULL; 807 unsigned int abuflen; 808 abuflen = EVP_PKEY_size(si->pkey); 809 abuf = malloc(abuflen); 810 if (!abuf) 811 goto err; 812 813 if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, 814 si->pkey)) { 815 PKCS7error(ERR_R_EVP_LIB); 816 free(abuf); 817 goto err; 818 } 819 ASN1_STRING_set0(si->enc_digest, abuf, abuflen); 820 } 821 } 822 } else if (i == NID_pkcs7_digest) { 823 unsigned char md_data[EVP_MAX_MD_SIZE]; 824 unsigned int md_len; 825 826 if (!PKCS7_find_digest(&mdc, bio, 827 OBJ_obj2nid(p7->d.digest->md->algorithm))) 828 goto err; 829 if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) 830 goto err; 831 if (ASN1_STRING_set(p7->d.digest->digest, md_data, 832 md_len) == 0) 833 goto err; 834 } 835 836 if (!PKCS7_is_detached(p7)) { 837 /* 838 * NOTE: only reach os == NULL here because detached 839 * digested data support is broken? 840 */ 841 if (os == NULL) 842 goto err; 843 if (!(os->flags & ASN1_STRING_FLAG_NDEF)) { 844 char *cont; 845 long contlen; 846 847 btmp = BIO_find_type(bio, BIO_TYPE_MEM); 848 if (btmp == NULL) { 849 PKCS7error(PKCS7_R_UNABLE_TO_FIND_MEM_BIO); 850 goto err; 851 } 852 contlen = BIO_get_mem_data(btmp, &cont); 853 /* 854 * Mark the BIO read only then we can use its copy 855 * of the data instead of making an extra copy. 856 */ 857 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); 858 BIO_set_mem_eof_return(btmp, 0); 859 ASN1_STRING_set0(os, (unsigned char *)cont, contlen); 860 } 861 } 862 ret = 1; 863 err: 864 EVP_MD_CTX_cleanup(&ctx_tmp); 865 return ret; 866 } 867 LCRYPTO_ALIAS(PKCS7_dataFinal); 868 869 int 870 PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) 871 { 872 EVP_MD_CTX mctx; 873 EVP_PKEY_CTX *pctx; 874 unsigned char *abuf = NULL; 875 int alen; 876 size_t siglen; 877 const EVP_MD *md = NULL; 878 879 md = EVP_get_digestbyobj(si->digest_alg->algorithm); 880 if (md == NULL) 881 return 0; 882 883 EVP_MD_CTX_legacy_clear(&mctx); 884 if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) 885 goto err; 886 887 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 888 EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { 889 PKCS7error(PKCS7_R_CTRL_ERROR); 890 goto err; 891 } 892 893 alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, 894 &PKCS7_ATTR_SIGN_it); 895 if (!abuf) 896 goto err; 897 if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) 898 goto err; 899 free(abuf); 900 abuf = NULL; 901 if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) 902 goto err; 903 abuf = malloc(siglen); 904 if (!abuf) 905 goto err; 906 if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) 907 goto err; 908 909 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 910 EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { 911 PKCS7error(PKCS7_R_CTRL_ERROR); 912 goto err; 913 } 914 915 EVP_MD_CTX_cleanup(&mctx); 916 917 ASN1_STRING_set0(si->enc_digest, abuf, siglen); 918 919 return 1; 920 921 err: 922 free(abuf); 923 EVP_MD_CTX_cleanup(&mctx); 924 return 0; 925 } 926 LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_sign); 927 928 int 929 PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, 930 PKCS7 *p7, PKCS7_SIGNER_INFO *si) 931 { 932 PKCS7_ISSUER_AND_SERIAL *ias; 933 int ret = 0, i; 934 STACK_OF(X509) *cert; 935 X509 *x509; 936 937 if (p7 == NULL) { 938 PKCS7error(PKCS7_R_INVALID_NULL_POINTER); 939 return 0; 940 } 941 942 if (p7->d.ptr == NULL) { 943 PKCS7error(PKCS7_R_NO_CONTENT); 944 return 0; 945 } 946 947 if (PKCS7_type_is_signed(p7)) { 948 cert = p7->d.sign->cert; 949 } else if (PKCS7_type_is_signedAndEnveloped(p7)) { 950 cert = p7->d.signed_and_enveloped->cert; 951 } else { 952 PKCS7error(PKCS7_R_WRONG_PKCS7_TYPE); 953 goto err; 954 } 955 /* XXXX */ 956 ias = si->issuer_and_serial; 957 958 x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial); 959 960 /* were we able to find the cert in passed to us */ 961 if (x509 == NULL) { 962 PKCS7error(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); 963 goto err; 964 } 965 966 /* Lets verify */ 967 if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { 968 PKCS7error(ERR_R_X509_LIB); 969 goto err; 970 } 971 if (X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN) == 0) { 972 X509_STORE_CTX_cleanup(ctx); 973 goto err; 974 } 975 i = X509_verify_cert(ctx); 976 if (i <= 0) { 977 PKCS7error(ERR_R_X509_LIB); 978 X509_STORE_CTX_cleanup(ctx); 979 goto err; 980 } 981 X509_STORE_CTX_cleanup(ctx); 982 983 return PKCS7_signatureVerify(bio, p7, si, x509); 984 err: 985 986 return ret; 987 } 988 LCRYPTO_ALIAS(PKCS7_dataVerify); 989 990 int 991 PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, X509 *x509) 992 { 993 ASN1_OCTET_STRING *os; 994 EVP_MD_CTX mdc_tmp, *mdc; 995 int ret = 0, i; 996 int md_type; 997 STACK_OF(X509_ATTRIBUTE) *sk; 998 BIO *btmp; 999 EVP_PKEY *pkey; 1000 1001 EVP_MD_CTX_legacy_clear(&mdc_tmp); 1002 1003 if (!PKCS7_type_is_signed(p7) && 1004 !PKCS7_type_is_signedAndEnveloped(p7)) { 1005 PKCS7error(PKCS7_R_WRONG_PKCS7_TYPE); 1006 goto err; 1007 } 1008 1009 md_type = OBJ_obj2nid(si->digest_alg->algorithm); 1010 1011 btmp = bio; 1012 for (;;) { 1013 if ((btmp == NULL) || 1014 ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) { 1015 PKCS7error(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1016 goto err; 1017 } 1018 BIO_get_md_ctx(btmp, &mdc); 1019 if (mdc == NULL) { 1020 PKCS7error(ERR_R_INTERNAL_ERROR); 1021 goto err; 1022 } 1023 if (EVP_MD_CTX_type(mdc) == md_type) 1024 break; 1025 /* Workaround for some broken clients that put the signature 1026 * OID instead of the digest OID in digest_alg->algorithm 1027 */ 1028 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) 1029 break; 1030 btmp = BIO_next(btmp); 1031 } 1032 1033 /* mdc is the digest ctx that we want, unless there are attributes, 1034 * in which case the digest is the signed attributes */ 1035 if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc)) 1036 goto err; 1037 1038 sk = si->auth_attr; 1039 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { 1040 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; 1041 unsigned int md_len; 1042 int alen; 1043 ASN1_OCTET_STRING *message_digest; 1044 1045 if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len)) 1046 goto err; 1047 message_digest = PKCS7_digest_from_attributes(sk); 1048 if (!message_digest) { 1049 PKCS7error(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1050 goto err; 1051 } 1052 if ((message_digest->length != (int)md_len) || 1053 (memcmp(message_digest->data, md_dat, md_len))) { 1054 PKCS7error(PKCS7_R_DIGEST_FAILURE); 1055 ret = -1; 1056 goto err; 1057 } 1058 1059 if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), 1060 NULL)) 1061 goto err; 1062 1063 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, 1064 &PKCS7_ATTR_VERIFY_it); 1065 if (alen <= 0) { 1066 PKCS7error(ERR_R_ASN1_LIB); 1067 ret = -1; 1068 goto err; 1069 } 1070 if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) 1071 goto err; 1072 1073 free(abuf); 1074 } 1075 1076 os = si->enc_digest; 1077 pkey = X509_get_pubkey(x509); 1078 if (!pkey) { 1079 ret = -1; 1080 goto err; 1081 } 1082 1083 i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); 1084 EVP_PKEY_free(pkey); 1085 if (i <= 0) { 1086 PKCS7error(PKCS7_R_SIGNATURE_FAILURE); 1087 ret = -1; 1088 goto err; 1089 } else 1090 ret = 1; 1091 err: 1092 EVP_MD_CTX_cleanup(&mdc_tmp); 1093 return ret; 1094 } 1095 LCRYPTO_ALIAS(PKCS7_signatureVerify); 1096 1097 PKCS7_ISSUER_AND_SERIAL * 1098 PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) 1099 { 1100 STACK_OF(PKCS7_RECIP_INFO) *rsk; 1101 PKCS7_RECIP_INFO *ri; 1102 int i; 1103 1104 i = OBJ_obj2nid(p7->type); 1105 if (i != NID_pkcs7_signedAndEnveloped) 1106 return NULL; 1107 if (p7->d.signed_and_enveloped == NULL) 1108 return NULL; 1109 rsk = p7->d.signed_and_enveloped->recipientinfo; 1110 if (rsk == NULL) 1111 return NULL; 1112 ri = sk_PKCS7_RECIP_INFO_value(rsk, 0); 1113 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) 1114 return NULL; 1115 ri = sk_PKCS7_RECIP_INFO_value(rsk, idx); 1116 return ri->issuer_and_serial; 1117 } 1118 LCRYPTO_ALIAS(PKCS7_get_issuer_and_serial); 1119 1120 static ASN1_TYPE * 1121 get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) 1122 { 1123 int i; 1124 X509_ATTRIBUTE *xa; 1125 ASN1_OBJECT *o; 1126 1127 o = OBJ_nid2obj(nid); 1128 if (!o || !sk) 1129 return NULL; 1130 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1131 xa = sk_X509_ATTRIBUTE_value(sk, i); 1132 if (OBJ_cmp(xa->object, o) == 0) 1133 return sk_ASN1_TYPE_value(xa->set, 0); 1134 } 1135 return NULL; 1136 } 1137 1138 ASN1_TYPE * 1139 PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) 1140 { 1141 return get_attribute(si->auth_attr, nid); 1142 } 1143 LCRYPTO_ALIAS(PKCS7_get_signed_attribute); 1144 1145 ASN1_TYPE * 1146 PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) 1147 { 1148 return get_attribute(si->unauth_attr, nid); 1149 } 1150 LCRYPTO_ALIAS(PKCS7_get_attribute); 1151 1152 ASN1_OCTET_STRING * 1153 PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) 1154 { 1155 ASN1_TYPE *astype; 1156 1157 if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) 1158 return NULL; 1159 if (astype->type != V_ASN1_OCTET_STRING) 1160 return NULL; 1161 return astype->value.octet_string; 1162 } 1163 LCRYPTO_ALIAS(PKCS7_digest_from_attributes); 1164 1165 int 1166 PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, 1167 STACK_OF(X509_ATTRIBUTE) *sk) 1168 { 1169 int i; 1170 1171 if (p7si->auth_attr != NULL) 1172 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, 1173 X509_ATTRIBUTE_free); 1174 p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk); 1175 if (p7si->auth_attr == NULL) 1176 return 0; 1177 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1178 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i, 1179 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk, i)))) 1180 == NULL) 1181 return 0; 1182 } 1183 return 1; 1184 } 1185 LCRYPTO_ALIAS(PKCS7_set_signed_attributes); 1186 1187 int 1188 PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk) 1189 { 1190 int i; 1191 1192 if (p7si->unauth_attr != NULL) 1193 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, 1194 X509_ATTRIBUTE_free); 1195 p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk); 1196 if (p7si->unauth_attr == NULL) 1197 return 0; 1198 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1199 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i, 1200 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk, i)))) 1201 == NULL) 1202 return 0; 1203 } 1204 return 1; 1205 } 1206 LCRYPTO_ALIAS(PKCS7_set_attributes); 1207 1208 static int 1209 add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, void *value) 1210 { 1211 X509_ATTRIBUTE *attr = NULL; 1212 1213 if (*sk == NULL) { 1214 *sk = sk_X509_ATTRIBUTE_new_null(); 1215 if (*sk == NULL) 1216 return 0; 1217 new_attrib: 1218 if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value))) 1219 return 0; 1220 if (!sk_X509_ATTRIBUTE_push(*sk, attr)) { 1221 X509_ATTRIBUTE_free(attr); 1222 return 0; 1223 } 1224 } else { 1225 int i; 1226 1227 for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) { 1228 attr = sk_X509_ATTRIBUTE_value(*sk, i); 1229 if (OBJ_obj2nid(attr->object) == nid) { 1230 X509_ATTRIBUTE_free(attr); 1231 attr = X509_ATTRIBUTE_create(nid, atrtype, 1232 value); 1233 if (attr == NULL) 1234 return 0; 1235 if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) { 1236 X509_ATTRIBUTE_free(attr); 1237 return 0; 1238 } 1239 goto end; 1240 } 1241 } 1242 goto new_attrib; 1243 } 1244 end: 1245 return 1; 1246 } 1247 1248 int 1249 PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1250 void *value) 1251 { 1252 return add_attribute(&(p7si->auth_attr), nid, atrtype, value); 1253 } 1254 LCRYPTO_ALIAS(PKCS7_add_signed_attribute); 1255 1256 int 1257 PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, void *value) 1258 { 1259 return add_attribute(&(p7si->unauth_attr), nid, atrtype, value); 1260 } 1261 LCRYPTO_ALIAS(PKCS7_add_attribute); 1262