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