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