1/* $OpenBSD: pk7_doit.c,v 1.56 2024/02/18 15:45:42 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 71static int 72PKCS7_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 95ASN1_OCTET_STRING * 96PKCS7_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 106static int 107PKCS7_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 138err: 139 BIO_free(btmp); 140 return 0; 141 142} 143 144static int 145pkcs7_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 188err: 189 EVP_PKEY_free(pkey); 190 EVP_PKEY_CTX_free(pctx); 191 free(ek); 192 return ret; 193} 194 195 196static int 197pkcs7_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 244err: 245 EVP_PKEY_CTX_free(pctx); 246 if (!ret && ek) 247 free(ek); 248 249 return ret; 250} 251 252BIO * 253PKCS7_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) { 399err: 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} 408LCRYPTO_ALIAS(PKCS7_dataInit); 409 410static int 411pkcs7_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 */ 424BIO * 425PKCS7_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) { 624err: 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} 637LCRYPTO_ALIAS(PKCS7_dataDecode); 638 639static BIO * 640PKCS7_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 660static int 661do_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 692int 693PKCS7_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 goto err; 817 } 818 ASN1_STRING_set0(si->enc_digest, abuf, abuflen); 819 } 820 } 821 } else if (i == NID_pkcs7_digest) { 822 unsigned char md_data[EVP_MAX_MD_SIZE]; 823 unsigned int md_len; 824 825 if (!PKCS7_find_digest(&mdc, bio, 826 OBJ_obj2nid(p7->d.digest->md->algorithm))) 827 goto err; 828 if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) 829 goto err; 830 if (ASN1_STRING_set(p7->d.digest->digest, md_data, 831 md_len) == 0) 832 goto err; 833 } 834 835 if (!PKCS7_is_detached(p7)) { 836 /* 837 * NOTE: only reach os == NULL here because detached 838 * digested data support is broken? 839 */ 840 if (os == NULL) 841 goto err; 842 if (!(os->flags & ASN1_STRING_FLAG_NDEF)) { 843 char *cont; 844 long contlen; 845 846 btmp = BIO_find_type(bio, BIO_TYPE_MEM); 847 if (btmp == NULL) { 848 PKCS7error(PKCS7_R_UNABLE_TO_FIND_MEM_BIO); 849 goto err; 850 } 851 contlen = BIO_get_mem_data(btmp, &cont); 852 /* 853 * Mark the BIO read only then we can use its copy 854 * of the data instead of making an extra copy. 855 */ 856 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); 857 BIO_set_mem_eof_return(btmp, 0); 858 ASN1_STRING_set0(os, (unsigned char *)cont, contlen); 859 } 860 } 861 ret = 1; 862err: 863 EVP_MD_CTX_cleanup(&ctx_tmp); 864 return ret; 865} 866LCRYPTO_ALIAS(PKCS7_dataFinal); 867 868int 869PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) 870{ 871 EVP_MD_CTX mctx; 872 EVP_PKEY_CTX *pctx; 873 unsigned char *abuf = NULL; 874 int alen; 875 size_t siglen; 876 const EVP_MD *md = NULL; 877 878 md = EVP_get_digestbyobj(si->digest_alg->algorithm); 879 if (md == NULL) 880 return 0; 881 882 EVP_MD_CTX_legacy_clear(&mctx); 883 if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) 884 goto err; 885 886 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 887 EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { 888 PKCS7error(PKCS7_R_CTRL_ERROR); 889 goto err; 890 } 891 892 alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, 893 &PKCS7_ATTR_SIGN_it); 894 if (!abuf) 895 goto err; 896 if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) 897 goto err; 898 free(abuf); 899 abuf = NULL; 900 if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) 901 goto err; 902 abuf = malloc(siglen); 903 if (!abuf) 904 goto err; 905 if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) 906 goto err; 907 908 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 909 EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { 910 PKCS7error(PKCS7_R_CTRL_ERROR); 911 goto err; 912 } 913 914 EVP_MD_CTX_cleanup(&mctx); 915 916 ASN1_STRING_set0(si->enc_digest, abuf, siglen); 917 918 return 1; 919 920err: 921 free(abuf); 922 EVP_MD_CTX_cleanup(&mctx); 923 return 0; 924} 925LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_sign); 926 927int 928PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, 929 PKCS7 *p7, PKCS7_SIGNER_INFO *si) 930{ 931 PKCS7_ISSUER_AND_SERIAL *ias; 932 int ret = 0, i; 933 STACK_OF(X509) *cert; 934 X509 *x509; 935 936 if (p7 == NULL) { 937 PKCS7error(PKCS7_R_INVALID_NULL_POINTER); 938 return 0; 939 } 940 941 if (p7->d.ptr == NULL) { 942 PKCS7error(PKCS7_R_NO_CONTENT); 943 return 0; 944 } 945 946 if (PKCS7_type_is_signed(p7)) { 947 cert = p7->d.sign->cert; 948 } else if (PKCS7_type_is_signedAndEnveloped(p7)) { 949 cert = p7->d.signed_and_enveloped->cert; 950 } else { 951 PKCS7error(PKCS7_R_WRONG_PKCS7_TYPE); 952 goto err; 953 } 954 /* XXXX */ 955 ias = si->issuer_and_serial; 956 957 x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial); 958 959 /* were we able to find the cert in passed to us */ 960 if (x509 == NULL) { 961 PKCS7error(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); 962 goto err; 963 } 964 965 /* Lets verify */ 966 if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { 967 PKCS7error(ERR_R_X509_LIB); 968 goto err; 969 } 970 if (X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN) == 0) { 971 X509_STORE_CTX_cleanup(ctx); 972 goto err; 973 } 974 i = X509_verify_cert(ctx); 975 if (i <= 0) { 976 PKCS7error(ERR_R_X509_LIB); 977 X509_STORE_CTX_cleanup(ctx); 978 goto err; 979 } 980 X509_STORE_CTX_cleanup(ctx); 981 982 return PKCS7_signatureVerify(bio, p7, si, x509); 983err: 984 985 return ret; 986} 987LCRYPTO_ALIAS(PKCS7_dataVerify); 988 989int 990PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, X509 *x509) 991{ 992 ASN1_OCTET_STRING *os; 993 EVP_MD_CTX mdc_tmp, *mdc; 994 int ret = 0, i; 995 int md_type; 996 STACK_OF(X509_ATTRIBUTE) *sk; 997 BIO *btmp; 998 EVP_PKEY *pkey; 999 1000 EVP_MD_CTX_legacy_clear(&mdc_tmp); 1001 1002 if (!PKCS7_type_is_signed(p7) && 1003 !PKCS7_type_is_signedAndEnveloped(p7)) { 1004 PKCS7error(PKCS7_R_WRONG_PKCS7_TYPE); 1005 goto err; 1006 } 1007 1008 md_type = OBJ_obj2nid(si->digest_alg->algorithm); 1009 1010 btmp = bio; 1011 for (;;) { 1012 if ((btmp == NULL) || 1013 ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) { 1014 PKCS7error(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1015 goto err; 1016 } 1017 BIO_get_md_ctx(btmp, &mdc); 1018 if (mdc == NULL) { 1019 PKCS7error(ERR_R_INTERNAL_ERROR); 1020 goto err; 1021 } 1022 if (EVP_MD_CTX_type(mdc) == md_type) 1023 break; 1024 /* Workaround for some broken clients that put the signature 1025 * OID instead of the digest OID in digest_alg->algorithm 1026 */ 1027 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) 1028 break; 1029 btmp = BIO_next(btmp); 1030 } 1031 1032 /* mdc is the digest ctx that we want, unless there are attributes, 1033 * in which case the digest is the signed attributes */ 1034 if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc)) 1035 goto err; 1036 1037 sk = si->auth_attr; 1038 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { 1039 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; 1040 unsigned int md_len; 1041 int alen; 1042 ASN1_OCTET_STRING *message_digest; 1043 1044 if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len)) 1045 goto err; 1046 message_digest = PKCS7_digest_from_attributes(sk); 1047 if (!message_digest) { 1048 PKCS7error(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1049 goto err; 1050 } 1051 if ((message_digest->length != (int)md_len) || 1052 (memcmp(message_digest->data, md_dat, md_len))) { 1053 PKCS7error(PKCS7_R_DIGEST_FAILURE); 1054 ret = -1; 1055 goto err; 1056 } 1057 1058 if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), 1059 NULL)) 1060 goto err; 1061 1062 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, 1063 &PKCS7_ATTR_VERIFY_it); 1064 if (alen <= 0) { 1065 PKCS7error(ERR_R_ASN1_LIB); 1066 ret = -1; 1067 goto err; 1068 } 1069 if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) 1070 goto err; 1071 1072 free(abuf); 1073 } 1074 1075 os = si->enc_digest; 1076 pkey = X509_get_pubkey(x509); 1077 if (!pkey) { 1078 ret = -1; 1079 goto err; 1080 } 1081 1082 i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); 1083 EVP_PKEY_free(pkey); 1084 if (i <= 0) { 1085 PKCS7error(PKCS7_R_SIGNATURE_FAILURE); 1086 ret = -1; 1087 goto err; 1088 } else 1089 ret = 1; 1090err: 1091 EVP_MD_CTX_cleanup(&mdc_tmp); 1092 return ret; 1093} 1094LCRYPTO_ALIAS(PKCS7_signatureVerify); 1095 1096PKCS7_ISSUER_AND_SERIAL * 1097PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) 1098{ 1099 STACK_OF(PKCS7_RECIP_INFO) *rsk; 1100 PKCS7_RECIP_INFO *ri; 1101 int i; 1102 1103 i = OBJ_obj2nid(p7->type); 1104 if (i != NID_pkcs7_signedAndEnveloped) 1105 return NULL; 1106 if (p7->d.signed_and_enveloped == NULL) 1107 return NULL; 1108 rsk = p7->d.signed_and_enveloped->recipientinfo; 1109 if (rsk == NULL) 1110 return NULL; 1111 ri = sk_PKCS7_RECIP_INFO_value(rsk, 0); 1112 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) 1113 return NULL; 1114 ri = sk_PKCS7_RECIP_INFO_value(rsk, idx); 1115 return ri->issuer_and_serial; 1116} 1117LCRYPTO_ALIAS(PKCS7_get_issuer_and_serial); 1118 1119static ASN1_TYPE * 1120get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) 1121{ 1122 int i; 1123 X509_ATTRIBUTE *xa; 1124 ASN1_OBJECT *o; 1125 1126 o = OBJ_nid2obj(nid); 1127 if (!o || !sk) 1128 return NULL; 1129 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1130 xa = sk_X509_ATTRIBUTE_value(sk, i); 1131 if (OBJ_cmp(xa->object, o) == 0) 1132 return sk_ASN1_TYPE_value(xa->set, 0); 1133 } 1134 return NULL; 1135} 1136 1137ASN1_TYPE * 1138PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) 1139{ 1140 return get_attribute(si->auth_attr, nid); 1141} 1142LCRYPTO_ALIAS(PKCS7_get_signed_attribute); 1143 1144ASN1_TYPE * 1145PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) 1146{ 1147 return get_attribute(si->unauth_attr, nid); 1148} 1149LCRYPTO_ALIAS(PKCS7_get_attribute); 1150 1151ASN1_OCTET_STRING * 1152PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) 1153{ 1154 ASN1_TYPE *astype; 1155 1156 if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) 1157 return NULL; 1158 if (astype->type != V_ASN1_OCTET_STRING) 1159 return NULL; 1160 return astype->value.octet_string; 1161} 1162LCRYPTO_ALIAS(PKCS7_digest_from_attributes); 1163 1164int 1165PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, 1166 STACK_OF(X509_ATTRIBUTE) *sk) 1167{ 1168 int i; 1169 1170 if (p7si->auth_attr != NULL) 1171 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, 1172 X509_ATTRIBUTE_free); 1173 p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk); 1174 if (p7si->auth_attr == NULL) 1175 return 0; 1176 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1177 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i, 1178 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk, i)))) 1179 == NULL) 1180 return 0; 1181 } 1182 return 1; 1183} 1184LCRYPTO_ALIAS(PKCS7_set_signed_attributes); 1185 1186int 1187PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk) 1188{ 1189 int i; 1190 1191 if (p7si->unauth_attr != NULL) 1192 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, 1193 X509_ATTRIBUTE_free); 1194 p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk); 1195 if (p7si->unauth_attr == NULL) 1196 return 0; 1197 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1198 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i, 1199 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk, i)))) 1200 == NULL) 1201 return 0; 1202 } 1203 return 1; 1204} 1205LCRYPTO_ALIAS(PKCS7_set_attributes); 1206 1207static int 1208add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, void *value) 1209{ 1210 X509_ATTRIBUTE *attr = NULL; 1211 1212 if (*sk == NULL) { 1213 *sk = sk_X509_ATTRIBUTE_new_null(); 1214 if (*sk == NULL) 1215 return 0; 1216new_attrib: 1217 if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value))) 1218 return 0; 1219 if (!sk_X509_ATTRIBUTE_push(*sk, attr)) { 1220 X509_ATTRIBUTE_free(attr); 1221 return 0; 1222 } 1223 } else { 1224 int i; 1225 1226 for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) { 1227 attr = sk_X509_ATTRIBUTE_value(*sk, i); 1228 if (OBJ_obj2nid(attr->object) == nid) { 1229 X509_ATTRIBUTE_free(attr); 1230 attr = X509_ATTRIBUTE_create(nid, atrtype, 1231 value); 1232 if (attr == NULL) 1233 return 0; 1234 if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) { 1235 X509_ATTRIBUTE_free(attr); 1236 return 0; 1237 } 1238 goto end; 1239 } 1240 } 1241 goto new_attrib; 1242 } 1243end: 1244 return 1; 1245} 1246 1247int 1248PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1249 void *value) 1250{ 1251 return add_attribute(&(p7si->auth_attr), nid, atrtype, value); 1252} 1253LCRYPTO_ALIAS(PKCS7_add_signed_attribute); 1254 1255int 1256PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, void *value) 1257{ 1258 return add_attribute(&(p7si->unauth_attr), nid, atrtype, value); 1259} 1260LCRYPTO_ALIAS(PKCS7_add_attribute); 1261