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