1 /* $OpenBSD: cms_env.c,v 1.28 2024/11/01 18:42:10 tb Exp $ */ 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 <stdlib.h> 56 #include <string.h> 57 58 #include <openssl/aes.h> 59 #include <openssl/asn1.h> 60 #include <openssl/bio.h> 61 #include <openssl/cms.h> 62 #include <openssl/err.h> 63 #include <openssl/evp.h> 64 #include <openssl/objects.h> 65 #include <openssl/x509.h> 66 67 #include "cms_local.h" 68 #include "evp_local.h" 69 70 /* CMS EnvelopedData Utilities */ 71 72 CMS_EnvelopedData * 73 cms_get0_enveloped(CMS_ContentInfo *cms) 74 { 75 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { 76 CMSerror(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); 77 return NULL; 78 } 79 return cms->d.envelopedData; 80 } 81 82 static CMS_EnvelopedData * 83 cms_enveloped_data_init(CMS_ContentInfo *cms) 84 { 85 if (cms->d.other == NULL) { 86 cms->d.envelopedData = (CMS_EnvelopedData *)ASN1_item_new(&CMS_EnvelopedData_it); 87 if (!cms->d.envelopedData) { 88 CMSerror(ERR_R_MALLOC_FAILURE); 89 return NULL; 90 } 91 cms->d.envelopedData->version = 0; 92 cms->d.envelopedData->encryptedContentInfo->contentType = 93 OBJ_nid2obj(NID_pkcs7_data); 94 ASN1_OBJECT_free(cms->contentType); 95 cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); 96 return cms->d.envelopedData; 97 } 98 return cms_get0_enveloped(cms); 99 } 100 101 int 102 cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) 103 { 104 EVP_PKEY *pkey; 105 int i; 106 107 if (ri->type == CMS_RECIPINFO_TRANS) 108 pkey = ri->d.ktri->pkey; 109 else if (ri->type == CMS_RECIPINFO_AGREE) { 110 EVP_PKEY_CTX *pctx = ri->d.kari->pctx; 111 if (!pctx) 112 return 0; 113 pkey = EVP_PKEY_CTX_get0_pkey(pctx); 114 if (!pkey) 115 return 0; 116 } else 117 return 0; 118 if (!pkey->ameth || !pkey->ameth->pkey_ctrl) 119 return 1; 120 i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri); 121 if (i == -2) { 122 CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 123 return 0; 124 } 125 if (i <= 0) { 126 CMSerror(CMS_R_CTRL_FAILURE); 127 return 0; 128 } 129 130 return 1; 131 } 132 133 STACK_OF(CMS_RecipientInfo) * 134 CMS_get0_RecipientInfos(CMS_ContentInfo *cms) 135 { 136 CMS_EnvelopedData *env; 137 138 env = cms_get0_enveloped(cms); 139 if (!env) 140 return NULL; 141 142 return env->recipientInfos; 143 } 144 LCRYPTO_ALIAS(CMS_get0_RecipientInfos); 145 146 int 147 CMS_RecipientInfo_type(CMS_RecipientInfo *ri) 148 { 149 return ri->type; 150 } 151 LCRYPTO_ALIAS(CMS_RecipientInfo_type); 152 153 EVP_PKEY_CTX * 154 CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri) 155 { 156 if (ri->type == CMS_RECIPINFO_TRANS) 157 return ri->d.ktri->pctx; 158 else if (ri->type == CMS_RECIPINFO_AGREE) 159 return ri->d.kari->pctx; 160 161 return NULL; 162 } 163 LCRYPTO_ALIAS(CMS_RecipientInfo_get0_pkey_ctx); 164 165 CMS_ContentInfo * 166 CMS_EnvelopedData_create(const EVP_CIPHER *cipher) 167 { 168 CMS_ContentInfo *cms; 169 CMS_EnvelopedData *env; 170 171 cms = CMS_ContentInfo_new(); 172 if (cms == NULL) 173 goto merr; 174 env = cms_enveloped_data_init(cms); 175 if (env == NULL) 176 goto merr; 177 if (!cms_EncryptedContent_init(env->encryptedContentInfo, cipher, 178 NULL, 0)) 179 goto merr; 180 181 return cms; 182 183 merr: 184 CMS_ContentInfo_free(cms); 185 CMSerror(ERR_R_MALLOC_FAILURE); 186 return NULL; 187 } 188 LCRYPTO_ALIAS(CMS_EnvelopedData_create); 189 190 /* Key Transport Recipient Info (KTRI) routines */ 191 192 /* Initialise a ktri based on passed certificate and key */ 193 194 static int 195 cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *pk, 196 unsigned int flags) 197 { 198 CMS_KeyTransRecipientInfo *ktri; 199 int idtype; 200 201 ri->d.ktri = (CMS_KeyTransRecipientInfo *)ASN1_item_new(&CMS_KeyTransRecipientInfo_it); 202 if (!ri->d.ktri) 203 return 0; 204 ri->type = CMS_RECIPINFO_TRANS; 205 206 ktri = ri->d.ktri; 207 208 if (flags & CMS_USE_KEYID) { 209 ktri->version = 2; 210 idtype = CMS_RECIPINFO_KEYIDENTIFIER; 211 } else { 212 ktri->version = 0; 213 idtype = CMS_RECIPINFO_ISSUER_SERIAL; 214 } 215 216 /* 217 * Not a typo: RecipientIdentifier and SignerIdentifier are the same 218 * structure. 219 */ 220 221 if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype)) 222 return 0; 223 224 X509_up_ref(recip); 225 EVP_PKEY_up_ref(pk); 226 227 ktri->pkey = pk; 228 ktri->recip = recip; 229 230 if (flags & CMS_KEY_PARAM) { 231 ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); 232 if (ktri->pctx == NULL) 233 return 0; 234 if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0) 235 return 0; 236 } else if (!cms_env_asn1_ctrl(ri, 0)) 237 return 0; 238 239 return 1; 240 } 241 242 /* 243 * Add a recipient certificate using appropriate type of RecipientInfo 244 */ 245 246 CMS_RecipientInfo * 247 CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, unsigned int flags) 248 { 249 CMS_RecipientInfo *ri = NULL; 250 CMS_EnvelopedData *env; 251 EVP_PKEY *pk = NULL; 252 253 env = cms_get0_enveloped(cms); 254 if (!env) 255 goto err; 256 257 /* Initialize recipient info */ 258 ri = (CMS_RecipientInfo *)ASN1_item_new(&CMS_RecipientInfo_it); 259 if (!ri) 260 goto merr; 261 262 pk = X509_get0_pubkey(recip); 263 if (!pk) { 264 CMSerror(CMS_R_ERROR_GETTING_PUBLIC_KEY); 265 goto err; 266 } 267 268 switch (cms_pkey_get_ri_type(pk)) { 269 270 case CMS_RECIPINFO_TRANS: 271 if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags)) 272 goto err; 273 break; 274 275 case CMS_RECIPINFO_AGREE: 276 if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags)) 277 goto err; 278 break; 279 280 default: 281 CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 282 goto err; 283 284 } 285 286 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) 287 goto merr; 288 289 return ri; 290 291 merr: 292 CMSerror(ERR_R_MALLOC_FAILURE); 293 err: 294 ASN1_item_free((ASN1_VALUE *)ri, &CMS_RecipientInfo_it); 295 return NULL; 296 } 297 LCRYPTO_ALIAS(CMS_add1_recipient_cert); 298 299 int 300 CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, EVP_PKEY **pk, 301 X509 **recip, X509_ALGOR **palg) 302 { 303 CMS_KeyTransRecipientInfo *ktri; 304 305 if (ri->type != CMS_RECIPINFO_TRANS) { 306 CMSerror(CMS_R_NOT_KEY_TRANSPORT); 307 return 0; 308 } 309 310 ktri = ri->d.ktri; 311 312 if (pk) 313 *pk = ktri->pkey; 314 if (recip) 315 *recip = ktri->recip; 316 if (palg) 317 *palg = ktri->keyEncryptionAlgorithm; 318 319 return 1; 320 } 321 LCRYPTO_ALIAS(CMS_RecipientInfo_ktri_get0_algs); 322 323 int 324 CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, 325 ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno) 326 { 327 CMS_KeyTransRecipientInfo *ktri; 328 329 if (ri->type != CMS_RECIPINFO_TRANS) { 330 CMSerror(CMS_R_NOT_KEY_TRANSPORT); 331 return 0; 332 } 333 ktri = ri->d.ktri; 334 335 return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno); 336 } 337 LCRYPTO_ALIAS(CMS_RecipientInfo_ktri_get0_signer_id); 338 339 int 340 CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert) 341 { 342 if (ri->type != CMS_RECIPINFO_TRANS) { 343 CMSerror(CMS_R_NOT_KEY_TRANSPORT); 344 return -2; 345 } 346 347 return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); 348 } 349 LCRYPTO_ALIAS(CMS_RecipientInfo_ktri_cert_cmp); 350 351 int 352 CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) 353 { 354 if (ri->type != CMS_RECIPINFO_TRANS) { 355 CMSerror(CMS_R_NOT_KEY_TRANSPORT); 356 return 0; 357 } 358 EVP_PKEY_free(ri->d.ktri->pkey); 359 ri->d.ktri->pkey = pkey; 360 361 return 1; 362 } 363 LCRYPTO_ALIAS(CMS_RecipientInfo_set0_pkey); 364 365 /* Encrypt content key in key transport recipient info */ 366 367 static int 368 cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 369 { 370 CMS_KeyTransRecipientInfo *ktri; 371 CMS_EncryptedContentInfo *ec; 372 EVP_PKEY_CTX *pctx; 373 unsigned char *ek = NULL; 374 size_t eklen; 375 376 int ret = 0; 377 378 if (ri->type != CMS_RECIPINFO_TRANS) { 379 CMSerror(CMS_R_NOT_KEY_TRANSPORT); 380 return 0; 381 } 382 ktri = ri->d.ktri; 383 ec = cms->d.envelopedData->encryptedContentInfo; 384 385 pctx = ktri->pctx; 386 387 if (pctx) { 388 if (!cms_env_asn1_ctrl(ri, 0)) 389 goto err; 390 } else { 391 pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); 392 if (pctx == NULL) 393 return 0; 394 395 if (EVP_PKEY_encrypt_init(pctx) <= 0) 396 goto err; 397 } 398 399 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, 400 EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) { 401 CMSerror(CMS_R_CTRL_ERROR); 402 goto err; 403 } 404 405 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) 406 goto err; 407 408 ek = malloc(eklen); 409 410 if (ek == NULL) { 411 CMSerror(ERR_R_MALLOC_FAILURE); 412 goto err; 413 } 414 415 if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) 416 goto err; 417 418 ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); 419 ek = NULL; 420 421 ret = 1; 422 423 err: 424 EVP_PKEY_CTX_free(pctx); 425 ktri->pctx = NULL; 426 free(ek); 427 428 return ret; 429 } 430 431 /* Decrypt content key from KTRI */ 432 433 static int 434 cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 435 { 436 CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; 437 EVP_PKEY *pkey = ktri->pkey; 438 unsigned char *ek = NULL; 439 size_t eklen; 440 size_t fixlen = 0; 441 int ret = 0; 442 CMS_EncryptedContentInfo *ec; 443 444 ec = cms->d.envelopedData->encryptedContentInfo; 445 446 if (ktri->pkey == NULL) { 447 CMSerror(CMS_R_NO_PRIVATE_KEY); 448 return 0; 449 } 450 451 if (cms->d.envelopedData->encryptedContentInfo->havenocert && 452 !cms->d.envelopedData->encryptedContentInfo->debug) { 453 X509_ALGOR *calg = ec->contentEncryptionAlgorithm; 454 const EVP_CIPHER *ciph; 455 456 if ((ciph = EVP_get_cipherbyobj(calg->algorithm)) == NULL) { 457 CMSerror(CMS_R_UNKNOWN_CIPHER); 458 return 0; 459 } 460 461 fixlen = EVP_CIPHER_key_length(ciph); 462 } 463 464 ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); 465 if (ktri->pctx == NULL) 466 return 0; 467 468 if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) 469 goto err; 470 471 if (!cms_env_asn1_ctrl(ri, 1)) 472 goto err; 473 474 if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT, 475 EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) { 476 CMSerror(CMS_R_CTRL_ERROR); 477 goto err; 478 } 479 480 if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen, ktri->encryptedKey->data, 481 ktri->encryptedKey->length) <= 0 || eklen == 0 || 482 (fixlen != 0 && eklen != fixlen)) { 483 CMSerror(CMS_R_CMS_LIB); 484 goto err; 485 } 486 487 ek = malloc(eklen); 488 489 if (ek == NULL) { 490 CMSerror(ERR_R_MALLOC_FAILURE); 491 goto err; 492 } 493 494 if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen, ktri->encryptedKey->data, 495 ktri->encryptedKey->length) <= 0) { 496 CMSerror(CMS_R_CMS_LIB); 497 goto err; 498 } 499 500 ret = 1; 501 502 freezero(ec->key, ec->keylen); 503 ec->key = ek; 504 ec->keylen = eklen; 505 506 err: 507 EVP_PKEY_CTX_free(ktri->pctx); 508 ktri->pctx = NULL; 509 if (!ret) 510 free(ek); 511 512 return ret; 513 } 514 515 /* Key Encrypted Key (KEK) RecipientInfo routines */ 516 517 int 518 CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, const unsigned char *id, 519 size_t idlen) 520 { 521 ASN1_OCTET_STRING tmp_os; 522 CMS_KEKRecipientInfo *kekri; 523 524 if (ri->type != CMS_RECIPINFO_KEK) { 525 CMSerror(CMS_R_NOT_KEK); 526 return -2; 527 } 528 kekri = ri->d.kekri; 529 tmp_os.type = V_ASN1_OCTET_STRING; 530 tmp_os.flags = 0; 531 tmp_os.data = (unsigned char *)id; 532 tmp_os.length = (int)idlen; 533 534 return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier); 535 } 536 LCRYPTO_ALIAS(CMS_RecipientInfo_kekri_id_cmp); 537 538 /* For now hard code AES key wrap info */ 539 540 static size_t 541 aes_wrap_keylen(int nid) 542 { 543 switch (nid) { 544 case NID_id_aes128_wrap: 545 return 16; 546 547 case NID_id_aes192_wrap: 548 return 24; 549 550 case NID_id_aes256_wrap: 551 return 32; 552 553 default: 554 return 0; 555 } 556 } 557 558 CMS_RecipientInfo * 559 CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, unsigned char *key, 560 size_t keylen, unsigned char *id, size_t idlen, ASN1_GENERALIZEDTIME *date, 561 ASN1_OBJECT *otherTypeId, ASN1_TYPE *otherType) 562 { 563 CMS_RecipientInfo *ri = NULL; 564 CMS_EnvelopedData *env; 565 CMS_KEKRecipientInfo *kekri; 566 567 env = cms_get0_enveloped(cms); 568 if (!env) 569 goto err; 570 571 if (nid == NID_undef) { 572 switch (keylen) { 573 case 16: 574 nid = NID_id_aes128_wrap; 575 break; 576 577 case 24: 578 nid = NID_id_aes192_wrap; 579 break; 580 581 case 32: 582 nid = NID_id_aes256_wrap; 583 break; 584 585 default: 586 CMSerror(CMS_R_INVALID_KEY_LENGTH); 587 goto err; 588 } 589 590 } else { 591 592 size_t exp_keylen = aes_wrap_keylen(nid); 593 594 if (!exp_keylen) { 595 CMSerror(CMS_R_UNSUPPORTED_KEK_ALGORITHM); 596 goto err; 597 } 598 599 if (keylen != exp_keylen) { 600 CMSerror(CMS_R_INVALID_KEY_LENGTH); 601 goto err; 602 } 603 604 } 605 606 /* Initialize recipient info */ 607 ri = (CMS_RecipientInfo *)ASN1_item_new(&CMS_RecipientInfo_it); 608 if (!ri) 609 goto merr; 610 611 ri->d.kekri = (CMS_KEKRecipientInfo *)ASN1_item_new(&CMS_KEKRecipientInfo_it); 612 if (!ri->d.kekri) 613 goto merr; 614 ri->type = CMS_RECIPINFO_KEK; 615 616 kekri = ri->d.kekri; 617 618 if (otherTypeId) { 619 kekri->kekid->other = (CMS_OtherKeyAttribute *)ASN1_item_new(&CMS_OtherKeyAttribute_it); 620 if (kekri->kekid->other == NULL) 621 goto merr; 622 } 623 624 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) 625 goto merr; 626 627 /* After this point no calls can fail */ 628 629 kekri->version = 4; 630 631 kekri->key = key; 632 kekri->keylen = keylen; 633 634 ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen); 635 636 kekri->kekid->date = date; 637 638 if (kekri->kekid->other) { 639 kekri->kekid->other->keyAttrId = otherTypeId; 640 kekri->kekid->other->keyAttr = otherType; 641 } 642 643 X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, 644 OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); 645 646 return ri; 647 648 merr: 649 CMSerror(ERR_R_MALLOC_FAILURE); 650 err: 651 ASN1_item_free((ASN1_VALUE *)ri, &CMS_RecipientInfo_it); 652 return NULL; 653 } 654 LCRYPTO_ALIAS(CMS_add0_recipient_key); 655 656 int 657 CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, X509_ALGOR **palg, 658 ASN1_OCTET_STRING **pid, ASN1_GENERALIZEDTIME **pdate, 659 ASN1_OBJECT **potherid, ASN1_TYPE **pothertype) 660 { 661 CMS_KEKIdentifier *rkid; 662 663 if (ri->type != CMS_RECIPINFO_KEK) { 664 CMSerror(CMS_R_NOT_KEK); 665 return 0; 666 } 667 rkid = ri->d.kekri->kekid; 668 if (palg) 669 *palg = ri->d.kekri->keyEncryptionAlgorithm; 670 if (pid) 671 *pid = rkid->keyIdentifier; 672 if (pdate) 673 *pdate = rkid->date; 674 if (potherid) { 675 if (rkid->other) 676 *potherid = rkid->other->keyAttrId; 677 else 678 *potherid = NULL; 679 } 680 if (pothertype) { 681 if (rkid->other) 682 *pothertype = rkid->other->keyAttr; 683 else 684 *pothertype = NULL; 685 } 686 687 return 1; 688 } 689 LCRYPTO_ALIAS(CMS_RecipientInfo_kekri_get0_id); 690 691 int 692 CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, unsigned char *key, 693 size_t keylen) 694 { 695 CMS_KEKRecipientInfo *kekri; 696 697 if (ri->type != CMS_RECIPINFO_KEK) { 698 CMSerror(CMS_R_NOT_KEK); 699 return 0; 700 } 701 702 kekri = ri->d.kekri; 703 kekri->key = key; 704 kekri->keylen = keylen; 705 return 1; 706 } 707 LCRYPTO_ALIAS(CMS_RecipientInfo_set0_key); 708 709 /* Encrypt content key in KEK recipient info */ 710 711 static int 712 cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 713 { 714 CMS_EncryptedContentInfo *ec; 715 CMS_KEKRecipientInfo *kekri; 716 AES_KEY actx; 717 unsigned char *wkey = NULL; 718 int wkeylen; 719 int r = 0; 720 721 ec = cms->d.envelopedData->encryptedContentInfo; 722 kekri = ri->d.kekri; 723 724 if (!kekri->key) { 725 CMSerror(CMS_R_NO_KEY); 726 return 0; 727 } 728 729 if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) { 730 CMSerror(CMS_R_ERROR_SETTING_KEY); 731 goto err; 732 } 733 734 wkey = malloc(ec->keylen + 8); 735 if (wkey == NULL) { 736 CMSerror(ERR_R_MALLOC_FAILURE); 737 goto err; 738 } 739 740 wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); 741 if (wkeylen <= 0) { 742 CMSerror(CMS_R_WRAP_ERROR); 743 goto err; 744 } 745 746 ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen); 747 748 r = 1; 749 750 err: 751 if (!r) 752 free(wkey); 753 explicit_bzero(&actx, sizeof(actx)); 754 755 return r; 756 } 757 758 /* Decrypt content key in KEK recipient info */ 759 760 static int 761 cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 762 { 763 CMS_EncryptedContentInfo *ec; 764 CMS_KEKRecipientInfo *kekri; 765 AES_KEY actx; 766 unsigned char *ukey = NULL; 767 int ukeylen; 768 int r = 0, wrap_nid; 769 770 ec = cms->d.envelopedData->encryptedContentInfo; 771 kekri = ri->d.kekri; 772 773 if (!kekri->key) { 774 CMSerror(CMS_R_NO_KEY); 775 return 0; 776 } 777 778 wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); 779 if (aes_wrap_keylen(wrap_nid) != kekri->keylen) { 780 CMSerror(CMS_R_INVALID_KEY_LENGTH); 781 return 0; 782 } 783 784 /* If encrypted key length is invalid don't bother */ 785 786 if (kekri->encryptedKey->length < 16) { 787 CMSerror(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); 788 goto err; 789 } 790 791 if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) { 792 CMSerror(CMS_R_ERROR_SETTING_KEY); 793 goto err; 794 } 795 796 ukey = malloc(kekri->encryptedKey->length - 8); 797 if (ukey == NULL) { 798 CMSerror(ERR_R_MALLOC_FAILURE); 799 goto err; 800 } 801 802 ukeylen = AES_unwrap_key(&actx, NULL, ukey, kekri->encryptedKey->data, 803 kekri->encryptedKey->length); 804 805 if (ukeylen <= 0) { 806 CMSerror(CMS_R_UNWRAP_ERROR); 807 goto err; 808 } 809 810 freezero(ec->key, ec->keylen); 811 ec->key = ukey; 812 ec->keylen = ukeylen; 813 814 r = 1; 815 816 err: 817 818 if (!r) 819 free(ukey); 820 explicit_bzero(&actx, sizeof(actx)); 821 822 return r; 823 } 824 825 int 826 CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 827 { 828 switch (ri->type) { 829 case CMS_RECIPINFO_TRANS: 830 return cms_RecipientInfo_ktri_decrypt(cms, ri); 831 832 case CMS_RECIPINFO_KEK: 833 return cms_RecipientInfo_kekri_decrypt(cms, ri); 834 835 case CMS_RECIPINFO_PASS: 836 return cms_RecipientInfo_pwri_crypt(cms, ri, 0); 837 838 default: 839 CMSerror(CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE); 840 return 0; 841 } 842 } 843 LCRYPTO_ALIAS(CMS_RecipientInfo_decrypt); 844 845 int 846 CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 847 { 848 switch (ri->type) { 849 case CMS_RECIPINFO_TRANS: 850 return cms_RecipientInfo_ktri_encrypt(cms, ri); 851 852 case CMS_RECIPINFO_AGREE: 853 return cms_RecipientInfo_kari_encrypt(cms, ri); 854 855 case CMS_RECIPINFO_KEK: 856 return cms_RecipientInfo_kekri_encrypt(cms, ri); 857 858 case CMS_RECIPINFO_PASS: 859 return cms_RecipientInfo_pwri_crypt(cms, ri, 1); 860 861 default: 862 CMSerror(CMS_R_UNSUPPORTED_RECIPIENT_TYPE); 863 return 0; 864 } 865 } 866 LCRYPTO_ALIAS(CMS_RecipientInfo_encrypt); 867 868 /* Check structures and fixup version numbers (if necessary) */ 869 870 static void 871 cms_env_set_originfo_version(CMS_EnvelopedData *env) 872 { 873 CMS_OriginatorInfo *org = env->originatorInfo; 874 int i; 875 876 if (org == NULL) 877 return; 878 for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) { 879 CMS_CertificateChoices *cch; 880 881 cch = sk_CMS_CertificateChoices_value(org->certificates, i); 882 if (cch->type == CMS_CERTCHOICE_OTHER) { 883 env->version = 4; 884 return; 885 } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { 886 if (env->version < 3) 887 env->version = 3; 888 } 889 } 890 891 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) { 892 CMS_RevocationInfoChoice *rch; 893 894 rch = sk_CMS_RevocationInfoChoice_value(org->crls, i); 895 if (rch->type == CMS_REVCHOICE_OTHER) { 896 env->version = 4; 897 return; 898 } 899 } 900 } 901 902 static void 903 cms_env_set_version(CMS_EnvelopedData *env) 904 { 905 int i; 906 CMS_RecipientInfo *ri; 907 908 /* 909 * Can't set version higher than 4 so if 4 or more already nothing to do. 910 */ 911 if (env->version >= 4) 912 return; 913 914 cms_env_set_originfo_version(env); 915 916 if (env->version >= 3) 917 return; 918 919 for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) { 920 ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i); 921 if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) { 922 env->version = 3; 923 return; 924 } else if (ri->type != CMS_RECIPINFO_TRANS 925 || ri->d.ktri->version != 0) { 926 env->version = 2; 927 } 928 } 929 if (env->originatorInfo || env->unprotectedAttrs) 930 env->version = 2; 931 if (env->version == 2) 932 return; 933 env->version = 0; 934 } 935 936 BIO * 937 cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) 938 { 939 CMS_EncryptedContentInfo *ec; 940 STACK_OF(CMS_RecipientInfo) *rinfos; 941 CMS_RecipientInfo *ri; 942 int i, ok = 0; 943 BIO *ret; 944 945 /* Get BIO first to set up key */ 946 947 ec = cms->d.envelopedData->encryptedContentInfo; 948 ret = cms_EncryptedContent_init_bio(ec); 949 950 /* If error or no cipher end of processing */ 951 952 if (!ret || !ec->cipher) 953 return ret; 954 955 /* Now encrypt content key according to each RecipientInfo type */ 956 957 rinfos = cms->d.envelopedData->recipientInfos; 958 959 for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { 960 ri = sk_CMS_RecipientInfo_value(rinfos, i); 961 if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) { 962 CMSerror(CMS_R_ERROR_SETTING_RECIPIENTINFO); 963 goto err; 964 } 965 } 966 cms_env_set_version(cms->d.envelopedData); 967 968 ok = 1; 969 970 err: 971 ec->cipher = NULL; 972 freezero(ec->key, ec->keylen); 973 ec->key = NULL; 974 ec->keylen = 0; 975 if (ok) 976 return ret; 977 BIO_free(ret); 978 return NULL; 979 } 980 981 /* 982 * Get RecipientInfo type (if any) supported by a key (public or private). To 983 * retain compatibility with previous behaviour if the ctrl value isn't 984 * supported we assume key transport. 985 */ 986 int 987 cms_pkey_get_ri_type(EVP_PKEY *pk) 988 { 989 if (pk->ameth && pk->ameth->pkey_ctrl) { 990 int i, r; 991 i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r); 992 if (i > 0) 993 return r; 994 } 995 return CMS_RECIPINFO_TRANS; 996 } 997