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