cms_env.c revision 296341
1/* crypto/cms/cms_env.c */ 2/* 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4 * project. 5 */ 6/* ==================================================================== 7 * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * licensing@OpenSSL.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 */ 54 55#include "cryptlib.h" 56#include <openssl/asn1t.h> 57#include <openssl/pem.h> 58#include <openssl/x509v3.h> 59#include <openssl/err.h> 60#include <openssl/cms.h> 61#include <openssl/rand.h> 62#include <openssl/aes.h> 63#include "cms_lcl.h" 64#include "asn1_locl.h" 65 66/* CMS EnvelopedData Utilities */ 67 68DECLARE_ASN1_ITEM(CMS_EnvelopedData) 69DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) 70DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) 71DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute) 72 73DECLARE_STACK_OF(CMS_RecipientInfo) 74 75CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) 76{ 77 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { 78 CMSerr(CMS_F_CMS_GET0_ENVELOPED, 79 CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); 80 return NULL; 81 } 82 return cms->d.envelopedData; 83} 84 85static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) 86{ 87 if (cms->d.other == NULL) { 88 cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); 89 if (!cms->d.envelopedData) { 90 CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE); 91 return NULL; 92 } 93 cms->d.envelopedData->version = 0; 94 cms->d.envelopedData->encryptedContentInfo->contentType = 95 OBJ_nid2obj(NID_pkcs7_data); 96 ASN1_OBJECT_free(cms->contentType); 97 cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); 98 return cms->d.envelopedData; 99 } 100 return cms_get0_enveloped(cms); 101} 102 103STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms) 104{ 105 CMS_EnvelopedData *env; 106 env = cms_get0_enveloped(cms); 107 if (!env) 108 return NULL; 109 return env->recipientInfos; 110} 111 112int CMS_RecipientInfo_type(CMS_RecipientInfo *ri) 113{ 114 return ri->type; 115} 116 117CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) 118{ 119 CMS_ContentInfo *cms; 120 CMS_EnvelopedData *env; 121 cms = CMS_ContentInfo_new(); 122 if (!cms) 123 goto merr; 124 env = cms_enveloped_data_init(cms); 125 if (!env) 126 goto merr; 127 if (!cms_EncryptedContent_init(env->encryptedContentInfo, 128 cipher, NULL, 0)) 129 goto merr; 130 return cms; 131 merr: 132 if (cms) 133 CMS_ContentInfo_free(cms); 134 CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE); 135 return NULL; 136} 137 138/* Key Transport Recipient Info (KTRI) routines */ 139 140/* 141 * Add a recipient certificate. For now only handle key transport. If we ever 142 * handle key agreement will need updating. 143 */ 144 145CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, 146 X509 *recip, unsigned int flags) 147{ 148 CMS_RecipientInfo *ri = NULL; 149 CMS_KeyTransRecipientInfo *ktri; 150 CMS_EnvelopedData *env; 151 EVP_PKEY *pk = NULL; 152 int i, type; 153 env = cms_get0_enveloped(cms); 154 if (!env) 155 goto err; 156 157 /* Initialize recipient info */ 158 ri = M_ASN1_new_of(CMS_RecipientInfo); 159 if (!ri) 160 goto merr; 161 162 /* Initialize and add key transport recipient info */ 163 164 ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo); 165 if (!ri->d.ktri) 166 goto merr; 167 ri->type = CMS_RECIPINFO_TRANS; 168 169 ktri = ri->d.ktri; 170 171 X509_check_purpose(recip, -1, -1); 172 pk = X509_get_pubkey(recip); 173 if (!pk) { 174 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY); 175 goto err; 176 } 177 CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509); 178 ktri->pkey = pk; 179 ktri->recip = recip; 180 181 if (flags & CMS_USE_KEYID) { 182 ktri->version = 2; 183 if (env->version < 2) 184 env->version = 2; 185 type = CMS_RECIPINFO_KEYIDENTIFIER; 186 } else { 187 ktri->version = 0; 188 type = CMS_RECIPINFO_ISSUER_SERIAL; 189 } 190 191 /* 192 * Not a typo: RecipientIdentifier and SignerIdentifier are the same 193 * structure. 194 */ 195 196 if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) 197 goto err; 198 199 if (pk->ameth && pk->ameth->pkey_ctrl) { 200 i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE, 0, ri); 201 if (i == -2) { 202 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, 203 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 204 goto err; 205 } 206 if (i <= 0) { 207 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_CTRL_FAILURE); 208 goto err; 209 } 210 } 211 212 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) 213 goto merr; 214 215 return ri; 216 217 merr: 218 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); 219 err: 220 if (ri) 221 M_ASN1_free_of(ri, CMS_RecipientInfo); 222 return NULL; 223 224} 225 226int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, 227 EVP_PKEY **pk, X509 **recip, 228 X509_ALGOR **palg) 229{ 230 CMS_KeyTransRecipientInfo *ktri; 231 if (ri->type != CMS_RECIPINFO_TRANS) { 232 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS, 233 CMS_R_NOT_KEY_TRANSPORT); 234 return 0; 235 } 236 237 ktri = ri->d.ktri; 238 239 if (pk) 240 *pk = ktri->pkey; 241 if (recip) 242 *recip = ktri->recip; 243 if (palg) 244 *palg = ktri->keyEncryptionAlgorithm; 245 return 1; 246} 247 248int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, 249 ASN1_OCTET_STRING **keyid, 250 X509_NAME **issuer, 251 ASN1_INTEGER **sno) 252{ 253 CMS_KeyTransRecipientInfo *ktri; 254 if (ri->type != CMS_RECIPINFO_TRANS) { 255 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID, 256 CMS_R_NOT_KEY_TRANSPORT); 257 return 0; 258 } 259 ktri = ri->d.ktri; 260 261 return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno); 262} 263 264int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert) 265{ 266 if (ri->type != CMS_RECIPINFO_TRANS) { 267 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP, 268 CMS_R_NOT_KEY_TRANSPORT); 269 return -2; 270 } 271 return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); 272} 273 274int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) 275{ 276 if (ri->type != CMS_RECIPINFO_TRANS) { 277 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT); 278 return 0; 279 } 280 ri->d.ktri->pkey = pkey; 281 return 1; 282} 283 284/* Encrypt content key in key transport recipient info */ 285 286static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, 287 CMS_RecipientInfo *ri) 288{ 289 CMS_KeyTransRecipientInfo *ktri; 290 CMS_EncryptedContentInfo *ec; 291 EVP_PKEY_CTX *pctx = NULL; 292 unsigned char *ek = NULL; 293 size_t eklen; 294 295 int ret = 0; 296 297 if (ri->type != CMS_RECIPINFO_TRANS) { 298 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT); 299 return 0; 300 } 301 ktri = ri->d.ktri; 302 ec = cms->d.envelopedData->encryptedContentInfo; 303 304 pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); 305 if (!pctx) 306 return 0; 307 308 if (EVP_PKEY_encrypt_init(pctx) <= 0) 309 goto err; 310 311 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, 312 EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) { 313 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); 314 goto err; 315 } 316 317 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) 318 goto err; 319 320 ek = OPENSSL_malloc(eklen); 321 322 if (ek == NULL) { 323 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE); 324 goto err; 325 } 326 327 if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) 328 goto err; 329 330 ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); 331 ek = NULL; 332 333 ret = 1; 334 335 err: 336 if (pctx) 337 EVP_PKEY_CTX_free(pctx); 338 if (ek) 339 OPENSSL_free(ek); 340 return ret; 341 342} 343 344/* Decrypt content key from KTRI */ 345 346static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, 347 CMS_RecipientInfo *ri) 348{ 349 CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; 350 EVP_PKEY_CTX *pctx = NULL; 351 unsigned char *ek = NULL; 352 size_t eklen; 353 int ret = 0; 354 CMS_EncryptedContentInfo *ec; 355 ec = cms->d.envelopedData->encryptedContentInfo; 356 357 if (ktri->pkey == NULL) { 358 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY); 359 return 0; 360 } 361 362 pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); 363 if (!pctx) 364 return 0; 365 366 if (EVP_PKEY_decrypt_init(pctx) <= 0) 367 goto err; 368 369 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, 370 EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) { 371 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); 372 goto err; 373 } 374 375 if (EVP_PKEY_decrypt(pctx, NULL, &eklen, 376 ktri->encryptedKey->data, 377 ktri->encryptedKey->length) <= 0) 378 goto err; 379 380 ek = OPENSSL_malloc(eklen); 381 382 if (ek == NULL) { 383 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE); 384 goto err; 385 } 386 387 if (EVP_PKEY_decrypt(pctx, ek, &eklen, 388 ktri->encryptedKey->data, 389 ktri->encryptedKey->length) <= 0) { 390 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); 391 goto err; 392 } 393 394 ret = 1; 395 396 if (ec->key) { 397 OPENSSL_cleanse(ec->key, ec->keylen); 398 OPENSSL_free(ec->key); 399 } 400 401 ec->key = ek; 402 ec->keylen = eklen; 403 404 err: 405 if (pctx) 406 EVP_PKEY_CTX_free(pctx); 407 if (!ret && ek) 408 OPENSSL_free(ek); 409 410 return ret; 411} 412 413/* Key Encrypted Key (KEK) RecipientInfo routines */ 414 415int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, 416 const unsigned char *id, size_t idlen) 417{ 418 ASN1_OCTET_STRING tmp_os; 419 CMS_KEKRecipientInfo *kekri; 420 if (ri->type != CMS_RECIPINFO_KEK) { 421 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK); 422 return -2; 423 } 424 kekri = ri->d.kekri; 425 tmp_os.type = V_ASN1_OCTET_STRING; 426 tmp_os.flags = 0; 427 tmp_os.data = (unsigned char *)id; 428 tmp_os.length = (int)idlen; 429 return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier); 430} 431 432/* For now hard code AES key wrap info */ 433 434static size_t aes_wrap_keylen(int nid) 435{ 436 switch (nid) { 437 case NID_id_aes128_wrap: 438 return 16; 439 440 case NID_id_aes192_wrap: 441 return 24; 442 443 case NID_id_aes256_wrap: 444 return 32; 445 446 default: 447 return 0; 448 } 449} 450 451CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, 452 unsigned char *key, size_t keylen, 453 unsigned char *id, size_t idlen, 454 ASN1_GENERALIZEDTIME *date, 455 ASN1_OBJECT *otherTypeId, 456 ASN1_TYPE *otherType) 457{ 458 CMS_RecipientInfo *ri = NULL; 459 CMS_EnvelopedData *env; 460 CMS_KEKRecipientInfo *kekri; 461 env = cms_get0_enveloped(cms); 462 if (!env) 463 goto err; 464 465 if (nid == NID_undef) { 466 switch (keylen) { 467 case 16: 468 nid = NID_id_aes128_wrap; 469 break; 470 471 case 24: 472 nid = NID_id_aes192_wrap; 473 break; 474 475 case 32: 476 nid = NID_id_aes256_wrap; 477 break; 478 479 default: 480 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH); 481 goto err; 482 } 483 484 } else { 485 486 size_t exp_keylen = aes_wrap_keylen(nid); 487 488 if (!exp_keylen) { 489 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, 490 CMS_R_UNSUPPORTED_KEK_ALGORITHM); 491 goto err; 492 } 493 494 if (keylen != exp_keylen) { 495 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH); 496 goto err; 497 } 498 499 } 500 501 /* Initialize recipient info */ 502 ri = M_ASN1_new_of(CMS_RecipientInfo); 503 if (!ri) 504 goto merr; 505 506 ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo); 507 if (!ri->d.kekri) 508 goto merr; 509 ri->type = CMS_RECIPINFO_KEK; 510 511 kekri = ri->d.kekri; 512 513 if (otherTypeId) { 514 kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute); 515 if (kekri->kekid->other == NULL) 516 goto merr; 517 } 518 519 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) 520 goto merr; 521 522 /* After this point no calls can fail */ 523 524 kekri->version = 4; 525 526 kekri->key = key; 527 kekri->keylen = keylen; 528 529 ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen); 530 531 kekri->kekid->date = date; 532 533 if (kekri->kekid->other) { 534 kekri->kekid->other->keyAttrId = otherTypeId; 535 kekri->kekid->other->keyAttr = otherType; 536 } 537 538 X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, 539 OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); 540 541 return ri; 542 543 merr: 544 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE); 545 err: 546 if (ri) 547 M_ASN1_free_of(ri, CMS_RecipientInfo); 548 return NULL; 549 550} 551 552int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, 553 X509_ALGOR **palg, 554 ASN1_OCTET_STRING **pid, 555 ASN1_GENERALIZEDTIME **pdate, 556 ASN1_OBJECT **potherid, 557 ASN1_TYPE **pothertype) 558{ 559 CMS_KEKIdentifier *rkid; 560 if (ri->type != CMS_RECIPINFO_KEK) { 561 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK); 562 return 0; 563 } 564 rkid = ri->d.kekri->kekid; 565 if (palg) 566 *palg = ri->d.kekri->keyEncryptionAlgorithm; 567 if (pid) 568 *pid = rkid->keyIdentifier; 569 if (pdate) 570 *pdate = rkid->date; 571 if (potherid) { 572 if (rkid->other) 573 *potherid = rkid->other->keyAttrId; 574 else 575 *potherid = NULL; 576 } 577 if (pothertype) { 578 if (rkid->other) 579 *pothertype = rkid->other->keyAttr; 580 else 581 *pothertype = NULL; 582 } 583 return 1; 584} 585 586int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, 587 unsigned char *key, size_t keylen) 588{ 589 CMS_KEKRecipientInfo *kekri; 590 if (ri->type != CMS_RECIPINFO_KEK) { 591 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK); 592 return 0; 593 } 594 595 kekri = ri->d.kekri; 596 kekri->key = key; 597 kekri->keylen = keylen; 598 return 1; 599} 600 601/* Encrypt content key in KEK recipient info */ 602 603static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms, 604 CMS_RecipientInfo *ri) 605{ 606 CMS_EncryptedContentInfo *ec; 607 CMS_KEKRecipientInfo *kekri; 608 AES_KEY actx; 609 unsigned char *wkey = NULL; 610 int wkeylen; 611 int r = 0; 612 613 ec = cms->d.envelopedData->encryptedContentInfo; 614 615 kekri = ri->d.kekri; 616 617 if (!kekri->key) { 618 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY); 619 return 0; 620 } 621 622 if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) { 623 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, 624 CMS_R_ERROR_SETTING_KEY); 625 goto err; 626 } 627 628 wkey = OPENSSL_malloc(ec->keylen + 8); 629 630 if (!wkey) { 631 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE); 632 goto err; 633 } 634 635 wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); 636 637 if (wkeylen <= 0) { 638 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); 639 goto err; 640 } 641 642 ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen); 643 644 r = 1; 645 646 err: 647 648 if (!r && wkey) 649 OPENSSL_free(wkey); 650 OPENSSL_cleanse(&actx, sizeof(actx)); 651 652 return r; 653 654} 655 656/* Decrypt content key in KEK recipient info */ 657 658static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, 659 CMS_RecipientInfo *ri) 660{ 661 CMS_EncryptedContentInfo *ec; 662 CMS_KEKRecipientInfo *kekri; 663 AES_KEY actx; 664 unsigned char *ukey = NULL; 665 int ukeylen; 666 int r = 0, wrap_nid; 667 668 ec = cms->d.envelopedData->encryptedContentInfo; 669 670 kekri = ri->d.kekri; 671 672 if (!kekri->key) { 673 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY); 674 return 0; 675 } 676 677 wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); 678 if (aes_wrap_keylen(wrap_nid) != kekri->keylen) { 679 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, 680 CMS_R_INVALID_KEY_LENGTH); 681 return 0; 682 } 683 684 /* If encrypted key length is invalid don't bother */ 685 686 if (kekri->encryptedKey->length < 16) { 687 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, 688 CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); 689 goto err; 690 } 691 692 if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) { 693 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, 694 CMS_R_ERROR_SETTING_KEY); 695 goto err; 696 } 697 698 ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); 699 700 if (!ukey) { 701 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE); 702 goto err; 703 } 704 705 ukeylen = AES_unwrap_key(&actx, NULL, ukey, 706 kekri->encryptedKey->data, 707 kekri->encryptedKey->length); 708 709 if (ukeylen <= 0) { 710 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR); 711 goto err; 712 } 713 714 ec->key = ukey; 715 ec->keylen = ukeylen; 716 717 r = 1; 718 719 err: 720 721 if (!r && ukey) 722 OPENSSL_free(ukey); 723 OPENSSL_cleanse(&actx, sizeof(actx)); 724 725 return r; 726 727} 728 729int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 730{ 731 switch (ri->type) { 732 case CMS_RECIPINFO_TRANS: 733 return cms_RecipientInfo_ktri_decrypt(cms, ri); 734 735 case CMS_RECIPINFO_KEK: 736 return cms_RecipientInfo_kekri_decrypt(cms, ri); 737 738 case CMS_RECIPINFO_PASS: 739 return cms_RecipientInfo_pwri_crypt(cms, ri, 0); 740 741 default: 742 CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, 743 CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE); 744 return 0; 745 } 746} 747 748BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) 749{ 750 CMS_EncryptedContentInfo *ec; 751 STACK_OF(CMS_RecipientInfo) *rinfos; 752 CMS_RecipientInfo *ri; 753 int i, r, ok = 0; 754 BIO *ret; 755 756 /* Get BIO first to set up key */ 757 758 ec = cms->d.envelopedData->encryptedContentInfo; 759 ret = cms_EncryptedContent_init_bio(ec); 760 761 /* If error or no cipher end of processing */ 762 763 if (!ret || !ec->cipher) 764 return ret; 765 766 /* Now encrypt content key according to each RecipientInfo type */ 767 768 rinfos = cms->d.envelopedData->recipientInfos; 769 770 for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { 771 ri = sk_CMS_RecipientInfo_value(rinfos, i); 772 773 switch (ri->type) { 774 case CMS_RECIPINFO_TRANS: 775 r = cms_RecipientInfo_ktri_encrypt(cms, ri); 776 break; 777 778 case CMS_RECIPINFO_KEK: 779 r = cms_RecipientInfo_kekri_encrypt(cms, ri); 780 break; 781 782 case CMS_RECIPINFO_PASS: 783 r = cms_RecipientInfo_pwri_crypt(cms, ri, 1); 784 break; 785 786 default: 787 CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, 788 CMS_R_UNSUPPORTED_RECIPIENT_TYPE); 789 goto err; 790 } 791 792 if (r <= 0) { 793 CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, 794 CMS_R_ERROR_SETTING_RECIPIENTINFO); 795 goto err; 796 } 797 } 798 799 ok = 1; 800 801 err: 802 ec->cipher = NULL; 803 if (ec->key) { 804 OPENSSL_cleanse(ec->key, ec->keylen); 805 OPENSSL_free(ec->key); 806 ec->key = NULL; 807 ec->keylen = 0; 808 } 809 if (ok) 810 return ret; 811 BIO_free(ret); 812 return NULL; 813 814} 815