pk7_doit.c revision 296341
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 BIO_set_mem_eof_return(bio, 0); 660 } 661 if (bio == NULL) 662 goto err; 663# endif 664 } 665 BIO_push(out, bio); 666 bio = NULL; 667#endif 668 if (0) { 669 err: 670 if (ek) { 671 OPENSSL_cleanse(ek, eklen); 672 OPENSSL_free(ek); 673 } 674 if (tkey) { 675 OPENSSL_cleanse(tkey, tkeylen); 676 OPENSSL_free(tkey); 677 } 678 if (out != NULL) 679 BIO_free_all(out); 680 if (btmp != NULL) 681 BIO_free_all(btmp); 682 if (etmp != NULL) 683 BIO_free_all(etmp); 684 if (bio != NULL) 685 BIO_free_all(bio); 686 out = NULL; 687 } 688 return (out); 689} 690 691static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) 692{ 693 for (;;) { 694 bio = BIO_find_type(bio, BIO_TYPE_MD); 695 if (bio == NULL) { 696 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, 697 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 698 return NULL; 699 } 700 BIO_get_md_ctx(bio, pmd); 701 if (*pmd == NULL) { 702 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR); 703 return NULL; 704 } 705 if (EVP_MD_CTX_type(*pmd) == nid) 706 return bio; 707 bio = BIO_next(bio); 708 } 709 return NULL; 710} 711 712static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) 713{ 714 unsigned char md_data[EVP_MAX_MD_SIZE]; 715 unsigned int md_len; 716 717 /* Add signing time if not already present */ 718 if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { 719 if (!PKCS7_add0_attrib_signing_time(si, NULL)) { 720 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); 721 return 0; 722 } 723 } 724 725 /* Add digest */ 726 if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) { 727 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB); 728 return 0; 729 } 730 if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) { 731 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); 732 return 0; 733 } 734 735 /* Now sign the attributes */ 736 if (!PKCS7_SIGNER_INFO_sign(si)) 737 return 0; 738 739 return 1; 740} 741 742int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) 743{ 744 int ret = 0; 745 int i, j; 746 BIO *btmp; 747 PKCS7_SIGNER_INFO *si; 748 EVP_MD_CTX *mdc, ctx_tmp; 749 STACK_OF(X509_ATTRIBUTE) *sk; 750 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; 751 ASN1_OCTET_STRING *os = NULL; 752 753 if (p7 == NULL) { 754 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); 755 return 0; 756 } 757 758 if (p7->d.ptr == NULL) { 759 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); 760 return 0; 761 } 762 763 EVP_MD_CTX_init(&ctx_tmp); 764 i = OBJ_obj2nid(p7->type); 765 p7->state = PKCS7_S_HEADER; 766 767 switch (i) { 768 case NID_pkcs7_data: 769 os = p7->d.data; 770 break; 771 case NID_pkcs7_signedAndEnveloped: 772 /* XXXXXXXXXXXXXXXX */ 773 si_sk = p7->d.signed_and_enveloped->signer_info; 774 os = p7->d.signed_and_enveloped->enc_data->enc_data; 775 if (!os) { 776 os = M_ASN1_OCTET_STRING_new(); 777 if (!os) { 778 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); 779 goto err; 780 } 781 p7->d.signed_and_enveloped->enc_data->enc_data = os; 782 } 783 break; 784 case NID_pkcs7_enveloped: 785 /* XXXXXXXXXXXXXXXX */ 786 os = p7->d.enveloped->enc_data->enc_data; 787 if (!os) { 788 os = M_ASN1_OCTET_STRING_new(); 789 if (!os) { 790 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); 791 goto err; 792 } 793 p7->d.enveloped->enc_data->enc_data = os; 794 } 795 break; 796 case NID_pkcs7_signed: 797 si_sk = p7->d.sign->signer_info; 798 os = PKCS7_get_octet_string(p7->d.sign->contents); 799 /* If detached data then the content is excluded */ 800 if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { 801 M_ASN1_OCTET_STRING_free(os); 802 os = NULL; 803 p7->d.sign->contents->d.data = NULL; 804 } 805 break; 806 807 case NID_pkcs7_digest: 808 os = PKCS7_get_octet_string(p7->d.digest->contents); 809 /* If detached data then the content is excluded */ 810 if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) { 811 M_ASN1_OCTET_STRING_free(os); 812 os = NULL; 813 p7->d.digest->contents->d.data = NULL; 814 } 815 break; 816 817 default: 818 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 819 goto err; 820 } 821 822 if (si_sk != NULL) { 823 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) { 824 si = sk_PKCS7_SIGNER_INFO_value(si_sk, i); 825 if (si->pkey == NULL) 826 continue; 827 828 j = OBJ_obj2nid(si->digest_alg->algorithm); 829 830 btmp = bio; 831 832 btmp = PKCS7_find_digest(&mdc, btmp, j); 833 834 if (btmp == NULL) 835 goto err; 836 837 /* 838 * We now have the EVP_MD_CTX, lets do the signing. 839 */ 840 if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc)) 841 goto err; 842 843 sk = si->auth_attr; 844 845 /* 846 * If there are attributes, we add the digest attribute and only 847 * sign the attributes 848 */ 849 if (sk_X509_ATTRIBUTE_num(sk) > 0) { 850 if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) 851 goto err; 852 } else { 853 unsigned char *abuf = NULL; 854 unsigned int abuflen; 855 abuflen = EVP_PKEY_size(si->pkey); 856 abuf = OPENSSL_malloc(abuflen); 857 if (!abuf) 858 goto err; 859 860 if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) { 861 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); 862 goto err; 863 } 864 ASN1_STRING_set0(si->enc_digest, abuf, abuflen); 865 } 866 } 867 } else if (i == NID_pkcs7_digest) { 868 unsigned char md_data[EVP_MAX_MD_SIZE]; 869 unsigned int md_len; 870 if (!PKCS7_find_digest(&mdc, bio, 871 OBJ_obj2nid(p7->d.digest->md->algorithm))) 872 goto err; 873 if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) 874 goto err; 875 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); 876 } 877 878 if (!PKCS7_is_detached(p7)) { 879 /* 880 * NOTE(emilia): I think we only reach os == NULL here because detached 881 * digested data support is broken. 882 */ 883 if (os == NULL) 884 goto err; 885 if (!(os->flags & ASN1_STRING_FLAG_NDEF)) { 886 char *cont; 887 long contlen; 888 btmp = BIO_find_type(bio, BIO_TYPE_MEM); 889 if (btmp == NULL) { 890 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); 891 goto err; 892 } 893 contlen = BIO_get_mem_data(btmp, &cont); 894 /* 895 * Mark the BIO read only then we can use its copy of the data 896 * instead of making an extra copy. 897 */ 898 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); 899 BIO_set_mem_eof_return(btmp, 0); 900 ASN1_STRING_set0(os, (unsigned char *)cont, contlen); 901 } 902 } 903 ret = 1; 904 err: 905 EVP_MD_CTX_cleanup(&ctx_tmp); 906 return (ret); 907} 908 909int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) 910{ 911 EVP_MD_CTX mctx; 912 EVP_PKEY_CTX *pctx; 913 unsigned char *abuf = NULL; 914 int alen; 915 size_t siglen; 916 const EVP_MD *md = NULL; 917 918 md = EVP_get_digestbyobj(si->digest_alg->algorithm); 919 if (md == NULL) 920 return 0; 921 922 EVP_MD_CTX_init(&mctx); 923 if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) 924 goto err; 925 926 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 927 EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { 928 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); 929 goto err; 930 } 931 932 alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, 933 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); 934 if (!abuf) 935 goto err; 936 if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) 937 goto err; 938 OPENSSL_free(abuf); 939 abuf = NULL; 940 if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) 941 goto err; 942 abuf = OPENSSL_malloc(siglen); 943 if (!abuf) 944 goto err; 945 if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) 946 goto err; 947 948 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 949 EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { 950 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); 951 goto err; 952 } 953 954 EVP_MD_CTX_cleanup(&mctx); 955 956 ASN1_STRING_set0(si->enc_digest, abuf, siglen); 957 958 return 1; 959 960 err: 961 if (abuf) 962 OPENSSL_free(abuf); 963 EVP_MD_CTX_cleanup(&mctx); 964 return 0; 965 966} 967 968int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, 969 PKCS7 *p7, PKCS7_SIGNER_INFO *si) 970{ 971 PKCS7_ISSUER_AND_SERIAL *ias; 972 int ret = 0, i; 973 STACK_OF(X509) *cert; 974 X509 *x509; 975 976 if (p7 == NULL) { 977 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER); 978 return 0; 979 } 980 981 if (p7->d.ptr == NULL) { 982 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT); 983 return 0; 984 } 985 986 if (PKCS7_type_is_signed(p7)) { 987 cert = p7->d.sign->cert; 988 } else if (PKCS7_type_is_signedAndEnveloped(p7)) { 989 cert = p7->d.signed_and_enveloped->cert; 990 } else { 991 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); 992 goto err; 993 } 994 /* XXXXXXXXXXXXXXXXXXXXXXX */ 995 ias = si->issuer_and_serial; 996 997 x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial); 998 999 /* were we able to find the cert in passed to us */ 1000 if (x509 == NULL) { 1001 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, 1002 PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); 1003 goto err; 1004 } 1005 1006 /* Lets verify */ 1007 if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { 1008 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); 1009 goto err; 1010 } 1011 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); 1012 i = X509_verify_cert(ctx); 1013 if (i <= 0) { 1014 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); 1015 X509_STORE_CTX_cleanup(ctx); 1016 goto err; 1017 } 1018 X509_STORE_CTX_cleanup(ctx); 1019 1020 return PKCS7_signatureVerify(bio, p7, si, x509); 1021 err: 1022 return ret; 1023} 1024 1025int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, 1026 X509 *x509) 1027{ 1028 ASN1_OCTET_STRING *os; 1029 EVP_MD_CTX mdc_tmp, *mdc; 1030 int ret = 0, i; 1031 int md_type; 1032 STACK_OF(X509_ATTRIBUTE) *sk; 1033 BIO *btmp; 1034 EVP_PKEY *pkey; 1035 1036 EVP_MD_CTX_init(&mdc_tmp); 1037 1038 if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) { 1039 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); 1040 goto err; 1041 } 1042 1043 md_type = OBJ_obj2nid(si->digest_alg->algorithm); 1044 1045 btmp = bio; 1046 for (;;) { 1047 if ((btmp == NULL) || 1048 ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) { 1049 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1050 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1051 goto err; 1052 } 1053 BIO_get_md_ctx(btmp, &mdc); 1054 if (mdc == NULL) { 1055 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR); 1056 goto err; 1057 } 1058 if (EVP_MD_CTX_type(mdc) == md_type) 1059 break; 1060 /* 1061 * Workaround for some broken clients that put the signature OID 1062 * instead of the digest OID in digest_alg->algorithm 1063 */ 1064 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) 1065 break; 1066 btmp = BIO_next(btmp); 1067 } 1068 1069 /* 1070 * mdc is the digest ctx that we want, unless there are attributes, in 1071 * which case the digest is the signed attributes 1072 */ 1073 if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc)) 1074 goto err; 1075 1076 sk = si->auth_attr; 1077 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { 1078 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; 1079 unsigned int md_len; 1080 int alen; 1081 ASN1_OCTET_STRING *message_digest; 1082 1083 if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len)) 1084 goto err; 1085 message_digest = PKCS7_digest_from_attributes(sk); 1086 if (!message_digest) { 1087 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1088 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1089 goto err; 1090 } 1091 if ((message_digest->length != (int)md_len) || 1092 (memcmp(message_digest->data, md_dat, md_len))) { 1093#if 0 1094 { 1095 int ii; 1096 for (ii = 0; ii < message_digest->length; ii++) 1097 printf("%02X", message_digest->data[ii]); 1098 printf(" sent\n"); 1099 for (ii = 0; ii < md_len; ii++) 1100 printf("%02X", md_dat[ii]); 1101 printf(" calc\n"); 1102 } 1103#endif 1104 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE); 1105 ret = -1; 1106 goto err; 1107 } 1108 1109 if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL)) 1110 goto err; 1111 1112 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, 1113 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); 1114 if (alen <= 0) { 1115 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB); 1116 ret = -1; 1117 goto err; 1118 } 1119 if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) 1120 goto err; 1121 1122 OPENSSL_free(abuf); 1123 } 1124 1125 os = si->enc_digest; 1126 pkey = X509_get_pubkey(x509); 1127 if (!pkey) { 1128 ret = -1; 1129 goto err; 1130 } 1131 1132 i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); 1133 EVP_PKEY_free(pkey); 1134 if (i <= 0) { 1135 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); 1136 ret = -1; 1137 goto err; 1138 } else 1139 ret = 1; 1140 err: 1141 EVP_MD_CTX_cleanup(&mdc_tmp); 1142 return (ret); 1143} 1144 1145PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) 1146{ 1147 STACK_OF(PKCS7_RECIP_INFO) *rsk; 1148 PKCS7_RECIP_INFO *ri; 1149 int i; 1150 1151 i = OBJ_obj2nid(p7->type); 1152 if (i != NID_pkcs7_signedAndEnveloped) 1153 return NULL; 1154 if (p7->d.signed_and_enveloped == NULL) 1155 return NULL; 1156 rsk = p7->d.signed_and_enveloped->recipientinfo; 1157 if (rsk == NULL) 1158 return NULL; 1159 ri = sk_PKCS7_RECIP_INFO_value(rsk, 0); 1160 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) 1161 return (NULL); 1162 ri = sk_PKCS7_RECIP_INFO_value(rsk, idx); 1163 return (ri->issuer_and_serial); 1164} 1165 1166ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) 1167{ 1168 return (get_attribute(si->auth_attr, nid)); 1169} 1170 1171ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) 1172{ 1173 return (get_attribute(si->unauth_attr, nid)); 1174} 1175 1176static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) 1177{ 1178 int i; 1179 X509_ATTRIBUTE *xa; 1180 ASN1_OBJECT *o; 1181 1182 o = OBJ_nid2obj(nid); 1183 if (!o || !sk) 1184 return (NULL); 1185 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1186 xa = sk_X509_ATTRIBUTE_value(sk, i); 1187 if (OBJ_cmp(xa->object, o) == 0) { 1188 if (!xa->single && sk_ASN1_TYPE_num(xa->value.set)) 1189 return (sk_ASN1_TYPE_value(xa->value.set, 0)); 1190 else 1191 return (NULL); 1192 } 1193 } 1194 return (NULL); 1195} 1196 1197ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) 1198{ 1199 ASN1_TYPE *astype; 1200 if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) 1201 return NULL; 1202 return astype->value.octet_string; 1203} 1204 1205int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, 1206 STACK_OF(X509_ATTRIBUTE) *sk) 1207{ 1208 int i; 1209 1210 if (p7si->auth_attr != NULL) 1211 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free); 1212 p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk); 1213 if (p7si->auth_attr == NULL) 1214 return 0; 1215 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1216 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i, 1217 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value 1218 (sk, i)))) 1219 == NULL) 1220 return (0); 1221 } 1222 return (1); 1223} 1224 1225int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, 1226 STACK_OF(X509_ATTRIBUTE) *sk) 1227{ 1228 int i; 1229 1230 if (p7si->unauth_attr != NULL) 1231 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free); 1232 p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk); 1233 if (p7si->unauth_attr == NULL) 1234 return 0; 1235 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1236 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i, 1237 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value 1238 (sk, i)))) 1239 == NULL) 1240 return (0); 1241 } 1242 return (1); 1243} 1244 1245int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1246 void *value) 1247{ 1248 return (add_attribute(&(p7si->auth_attr), nid, atrtype, value)); 1249} 1250 1251int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1252 void *value) 1253{ 1254 return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value)); 1255} 1256 1257static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, 1258 void *value) 1259{ 1260 X509_ATTRIBUTE *attr = NULL; 1261 1262 if (*sk == NULL) { 1263 *sk = sk_X509_ATTRIBUTE_new_null(); 1264 if (*sk == NULL) 1265 return 0; 1266 new_attrib: 1267 if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value))) 1268 return 0; 1269 if (!sk_X509_ATTRIBUTE_push(*sk, attr)) { 1270 X509_ATTRIBUTE_free(attr); 1271 return 0; 1272 } 1273 } else { 1274 int i; 1275 1276 for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) { 1277 attr = sk_X509_ATTRIBUTE_value(*sk, i); 1278 if (OBJ_obj2nid(attr->object) == nid) { 1279 X509_ATTRIBUTE_free(attr); 1280 attr = X509_ATTRIBUTE_create(nid, atrtype, value); 1281 if (attr == NULL) 1282 return 0; 1283 if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) { 1284 X509_ATTRIBUTE_free(attr); 1285 return 0; 1286 } 1287 goto end; 1288 } 1289 } 1290 goto new_attrib; 1291 } 1292 end: 1293 return (1); 1294} 1295