LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/cms - cms_env.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 365 0.0 %
Date: 2015-10-10 Functions: 0 27 0.0 %

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

Generated by: LCOV version 1.10