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