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