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