LCOV - code coverage report
Current view: top level - cms - cms_kari.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 137 208 65.9 %
Date: 2014-08-02 Functions: 12 14 85.7 %
Branches: 58 156 37.2 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/cms/cms_kari.c */
       2                 :            : /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
       3                 :            :  * project.
       4                 :            :  */
       5                 :            : /* ====================================================================
       6                 :            :  * Copyright (c) 2013 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                 :            : DECLARE_ASN1_ITEM(CMS_KeyAgreeRecipientInfo)
      66                 :            : DECLARE_ASN1_ITEM(CMS_RecipientEncryptedKey)
      67                 :            : DECLARE_ASN1_ITEM(CMS_OriginatorPublicKey)
      68                 :            : 
      69                 :            : /* Key Agreement Recipient Info (KARI) routines */
      70                 :            : 
      71                 :          8 : int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
      72                 :            :                                         X509_ALGOR **palg,
      73                 :            :                                         ASN1_OCTET_STRING **pukm)
      74                 :            :         {
      75         [ -  + ]:          8 :         if (ri->type != CMS_RECIPINFO_AGREE)
      76                 :            :                 {
      77                 :          0 :                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG,
      78                 :            :                         CMS_R_NOT_KEY_AGREEMENT);
      79                 :          0 :                 return 0;
      80                 :            :                 }
      81         [ +  - ]:          8 :         if (palg)
      82                 :          8 :                 *palg = ri->d.kari->keyEncryptionAlgorithm;
      83         [ +  - ]:          8 :         if (pukm)
      84                 :          8 :                 *pukm = ri->d.kari->ukm;
      85                 :            :         return 1;
      86                 :            :         }
      87                 :            : 
      88                 :            : /* Retrieve recipient encrypted keys from a kari */
      89                 :            : 
      90                 :          4 : STACK_OF(CMS_RecipientEncryptedKey) *CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri)
      91                 :            :         {
      92         [ -  + ]:          4 :         if (ri->type != CMS_RECIPINFO_AGREE)
      93                 :            :                 {
      94                 :          0 :                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS,
      95                 :            :                         CMS_R_NOT_KEY_AGREEMENT);
      96                 :          0 :                 return NULL;
      97                 :            :                 }
      98                 :          4 :         return ri->d.kari->recipientEncryptedKeys;
      99                 :            :         }
     100                 :            : 
     101                 :          8 : int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
     102                 :            :                                         X509_ALGOR **pubalg,
     103                 :            :                                         ASN1_BIT_STRING **pubkey,
     104                 :            :                                         ASN1_OCTET_STRING **keyid,
     105                 :            :                                         X509_NAME **issuer, ASN1_INTEGER **sno)
     106                 :            :         {
     107                 :            :         CMS_OriginatorIdentifierOrKey *oik;
     108         [ -  + ]:          8 :         if (ri->type != CMS_RECIPINFO_AGREE)
     109                 :            :                 {
     110                 :          0 :                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID,
     111                 :            :                         CMS_R_NOT_KEY_AGREEMENT);
     112                 :          0 :                 return 0;
     113                 :            :                 }
     114                 :          8 :         oik = ri->d.kari->originator;
     115         [ -  + ]:          8 :         if (issuer)
     116                 :          0 :                 *issuer = NULL;
     117         [ -  + ]:          8 :         if (sno)
     118                 :          0 :                 *sno = NULL;
     119         [ -  + ]:          8 :         if (keyid)
     120                 :          0 :                 *keyid = NULL;
     121         [ +  - ]:          8 :         if (pubalg)
     122                 :          8 :                 *pubalg = NULL;
     123         [ +  - ]:          8 :         if (pubkey)
     124                 :          8 :                 *pubkey = NULL;
     125         [ -  + ]:          8 :         if (oik->type == CMS_OIK_ISSUER_SERIAL)
     126                 :            :                 {
     127         [ #  # ]:          0 :                 if (issuer)
     128                 :          0 :                         *issuer = oik->d.issuerAndSerialNumber->issuer;
     129         [ #  # ]:          0 :                 if (sno)
     130                 :          0 :                         *sno = oik->d.issuerAndSerialNumber->serialNumber;
     131                 :            :                 }
     132         [ -  + ]:          8 :         else if (oik->type == CMS_OIK_KEYIDENTIFIER)
     133                 :            :                 {
     134         [ #  # ]:          0 :                 if (keyid)
     135                 :          0 :                         *keyid = oik->d.subjectKeyIdentifier;
     136                 :            :                 }
     137         [ +  - ]:          8 :         else if (oik->type == CMS_OIK_PUBKEY)
     138                 :            :                 {
     139         [ +  - ]:          8 :                 if (pubalg)
     140                 :          8 :                         *pubalg = oik->d.originatorKey->algorithm;
     141         [ +  - ]:          8 :                 if (pubkey)
     142                 :          8 :                         *pubkey = oik->d.originatorKey->publicKey;
     143                 :            :                 }
     144                 :            :         else
     145                 :            :                 return 0;
     146                 :            :         return 1;
     147                 :            :         }
     148                 :            : 
     149                 :          0 : int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
     150                 :            :         {
     151                 :            :         CMS_OriginatorIdentifierOrKey *oik;
     152         [ #  # ]:          0 :         if (ri->type != CMS_RECIPINFO_AGREE)
     153                 :            :                 {
     154                 :          0 :                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP,
     155                 :            :                         CMS_R_NOT_KEY_AGREEMENT);
     156                 :          0 :                 return -2;
     157                 :            :                 }
     158                 :          0 :         oik = ri->d.kari->originator;
     159         [ #  # ]:          0 :         if (oik->type == CMS_OIK_ISSUER_SERIAL)
     160                 :          0 :                 return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert);
     161         [ #  # ]:          0 :         else if (oik->type == CMS_OIK_KEYIDENTIFIER)
     162                 :          0 :                 return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert);
     163                 :            :         return -1;
     164                 :            :         }
     165                 :            : 
     166                 :          0 : int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
     167                 :            :                                         ASN1_OCTET_STRING **keyid,
     168                 :            :                                         ASN1_GENERALIZEDTIME **tm,
     169                 :            :                                         CMS_OtherKeyAttribute **other,
     170                 :            :                                         X509_NAME **issuer, ASN1_INTEGER **sno)
     171                 :            :         {
     172                 :          0 :         CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
     173         [ #  # ]:          0 :         if (rid->type == CMS_REK_ISSUER_SERIAL)
     174                 :            :                 {
     175         [ #  # ]:          0 :                 if (issuer)
     176                 :          0 :                         *issuer = rid->d.issuerAndSerialNumber->issuer;
     177         [ #  # ]:          0 :                 if (sno)
     178                 :          0 :                         *sno = rid->d.issuerAndSerialNumber->serialNumber;
     179         [ #  # ]:          0 :                 if (keyid)
     180                 :          0 :                         *keyid = NULL;
     181         [ #  # ]:          0 :                 if (tm)
     182                 :          0 :                         *tm = NULL;
     183         [ #  # ]:          0 :                 if (other)
     184                 :          0 :                         *other = NULL;
     185                 :            :                 }
     186         [ #  # ]:          0 :         else if (rid->type == CMS_REK_KEYIDENTIFIER)
     187                 :            :                 {
     188         [ #  # ]:          0 :                 if (keyid)
     189                 :          0 :                         *keyid = rid->d.rKeyId->subjectKeyIdentifier;
     190         [ #  # ]:          0 :                 if (tm)
     191                 :          0 :                         *tm = rid->d.rKeyId->date;
     192         [ #  # ]:          0 :                 if (other)
     193                 :          0 :                         *other = rid->d.rKeyId->other;
     194         [ #  # ]:          0 :                 if (issuer)
     195                 :          0 :                         *issuer = NULL;
     196         [ #  # ]:          0 :                 if (sno)
     197                 :          0 :                         *sno = NULL;
     198                 :            :                 }
     199                 :            :         else
     200                 :            :                 return 0;
     201                 :            :         return 1;
     202                 :            :         }
     203                 :            : 
     204                 :          4 : int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
     205                 :            :                                                 X509 *cert)
     206                 :            :         {
     207                 :          4 :         CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
     208         [ +  - ]:          4 :         if (rid->type == CMS_REK_ISSUER_SERIAL)
     209                 :          4 :                 return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
     210         [ #  # ]:          0 :         else if (rid->type == CMS_REK_KEYIDENTIFIER)
     211                 :          0 :                 return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert);
     212                 :            :         else
     213                 :            :                 return -1;
     214                 :            :         }
     215                 :            : 
     216                 :          8 : int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk)
     217                 :            :         {
     218                 :            :         EVP_PKEY_CTX *pctx;
     219                 :          8 :         CMS_KeyAgreeRecipientInfo *kari = ri->d.kari;
     220         [ -  + ]:          8 :         if (kari->pctx)
     221                 :            :                 {
     222                 :          0 :                 EVP_PKEY_CTX_free(kari->pctx);
     223                 :          0 :                 kari->pctx = NULL;
     224                 :            :                 }
     225         [ +  + ]:          8 :         if (!pk)
     226                 :            :                 return 1;
     227                 :          4 :         pctx = EVP_PKEY_CTX_new(pk, NULL);
     228 [ +  - ][ +  - ]:          4 :         if (!pctx || !EVP_PKEY_derive_init(pctx))
     229                 :            :                 goto err;
     230                 :          4 :         kari->pctx = pctx;
     231                 :          4 :         return 1;
     232                 :            :         err:
     233         [ #  # ]:          0 :         if (pctx)
     234                 :          0 :                 EVP_PKEY_CTX_free(pctx);
     235                 :            :         return 0;
     236                 :            :         }
     237                 :            : 
     238                 :          8 : EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri)
     239                 :            :         {
     240         [ +  - ]:          8 :         if (ri->type == CMS_RECIPINFO_AGREE)
     241                 :          8 :                 return &ri->d.kari->ctx;
     242                 :            :         return NULL;
     243                 :            :         }
     244                 :            : 
     245                 :            : /* Derive KEK and decrypt/encrypt with it to produce either the 
     246                 :            :  * original CEK or the encrypted CEK.
     247                 :            :  */
     248                 :            : 
     249                 :          8 : static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, 
     250                 :            :                         const unsigned char *in, size_t inlen,
     251                 :            :                         CMS_KeyAgreeRecipientInfo *kari, int enc)
     252                 :            :         {
     253                 :            :         /* Key encryption key */
     254                 :            :         unsigned char kek[EVP_MAX_KEY_LENGTH];
     255                 :            :         size_t keklen;
     256                 :          8 :         int rv = 0;
     257                 :          8 :         unsigned char *out = NULL;
     258                 :            :         int outlen;
     259                 :          8 :         keklen = EVP_CIPHER_CTX_key_length(&kari->ctx);
     260         [ +  - ]:          8 :         if (keklen > EVP_MAX_KEY_LENGTH)
     261                 :            :                 return 0;
     262                 :            :         /* Derive KEK */
     263         [ +  - ]:          8 :         if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0)
     264                 :            :                 goto err;
     265                 :            :         /* Set KEK in context */
     266         [ +  - ]:          8 :         if (!EVP_CipherInit_ex(&kari->ctx, NULL, NULL, kek, NULL, enc))
     267                 :            :                 goto err;
     268                 :            :         /* obtain output length of ciphered key */
     269         [ +  - ]:          8 :         if (!EVP_CipherUpdate(&kari->ctx, NULL, &outlen, in, inlen))
     270                 :            :                 goto err;
     271                 :          8 :         out = OPENSSL_malloc(outlen);
     272         [ +  - ]:          8 :         if (!out)
     273                 :            :                 goto err;
     274         [ +  - ]:          8 :         if (!EVP_CipherUpdate(&kari->ctx, out, &outlen, in, inlen))
     275                 :            :                 goto err;
     276                 :          8 :         *pout = out;
     277                 :          8 :         *poutlen = (size_t)outlen;
     278                 :          8 :         rv = 1;
     279                 :            : 
     280                 :            :         err:
     281                 :          8 :         OPENSSL_cleanse(kek, keklen);
     282         [ -  + ]:          8 :         if (!rv && out)
     283                 :          0 :                 OPENSSL_free(out);
     284                 :          8 :         EVP_CIPHER_CTX_cleanup(&kari->ctx);
     285                 :          8 :         EVP_PKEY_CTX_free(kari->pctx);
     286                 :          8 :         kari->pctx = NULL;
     287                 :          8 :         return rv;
     288                 :            :         }
     289                 :            : 
     290                 :          4 : int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
     291                 :            :                                                 CMS_RecipientEncryptedKey *rek)
     292                 :            :         {
     293                 :          4 :         int rv = 0;
     294                 :          4 :         unsigned char *enckey = NULL, *cek = NULL;
     295                 :            :         size_t enckeylen;
     296                 :            :         size_t ceklen;
     297                 :            :         CMS_EncryptedContentInfo *ec;
     298                 :          4 :         enckeylen = rek->encryptedKey->length;
     299                 :          4 :         enckey = rek->encryptedKey->data;
     300                 :            :         /* Setup all parameters to derive KEK */
     301         [ +  - ]:          4 :         if (!cms_env_asn1_ctrl(ri, 1))
     302                 :            :                 goto err;
     303                 :            :         /* Attempt to decrypt CEK */
     304         [ +  - ]:          4 :         if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0))
     305                 :            :                 goto err;
     306                 :          4 :         ec = cms->d.envelopedData->encryptedContentInfo;
     307         [ -  + ]:          4 :         if (ec->key)
     308                 :            :                 {
     309                 :          0 :                 OPENSSL_cleanse(ec->key, ec->keylen);
     310                 :          0 :                 OPENSSL_free(ec->key);
     311                 :            :                 }
     312                 :          4 :         ec->key = cek;
     313                 :          4 :         ec->keylen = ceklen;
     314                 :          4 :         cek = NULL;
     315                 :          4 :         rv = 1;
     316                 :            :         err:
     317         [ -  + ]:          4 :         if (cek)
     318                 :          0 :                 OPENSSL_free(cek);
     319                 :          4 :         return rv;
     320                 :            :         }
     321                 :            : 
     322                 :            : /* Create ephemeral key and initialise context based on it */
     323                 :          8 : static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
     324                 :            :                                                 EVP_PKEY *pk)
     325                 :            :         {
     326                 :          4 :         EVP_PKEY_CTX *pctx = NULL;
     327                 :          4 :         EVP_PKEY *ekey = NULL;
     328                 :          4 :         int rv = 0;
     329                 :          4 :         pctx = EVP_PKEY_CTX_new(pk, NULL);
     330         [ +  - ]:          4 :         if (!pctx)
     331                 :            :                 goto err;
     332         [ +  - ]:          4 :         if (EVP_PKEY_keygen_init(pctx) <= 0)
     333                 :            :                 goto err;
     334         [ +  - ]:          4 :         if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
     335                 :            :                 goto err;
     336                 :          4 :         EVP_PKEY_CTX_free(pctx);
     337                 :          4 :         pctx = EVP_PKEY_CTX_new(ekey, NULL);
     338         [ +  - ]:          4 :         if (!pctx)
     339                 :            :                 goto err;
     340         [ +  - ]:          4 :         if (EVP_PKEY_derive_init(pctx) <= 0)
     341                 :            :                 goto err;
     342                 :          4 :         kari->pctx = pctx;
     343                 :          4 :         rv = 1;
     344                 :            :         err:
     345         [ -  + ]:          4 :         if (!rv && pctx)
     346                 :          0 :                 EVP_PKEY_CTX_free(pctx);
     347         [ +  - ]:          4 :         if (ekey)
     348                 :          4 :                 EVP_PKEY_free(ekey);
     349                 :          4 :         return rv;
     350                 :            :         }
     351                 :            : 
     352                 :            : /* Initialise a ktri based on passed certificate and key */
     353                 :            : 
     354                 :          4 : int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
     355                 :            :                                 EVP_PKEY *pk, unsigned int flags)
     356                 :            :         {
     357                 :            :         CMS_KeyAgreeRecipientInfo *kari;
     358                 :          4 :         CMS_RecipientEncryptedKey *rek = NULL;
     359                 :            : 
     360                 :          4 :         ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
     361         [ +  - ]:          4 :         if (!ri->d.kari)
     362                 :            :                 return 0;
     363                 :          4 :         ri->type = CMS_RECIPINFO_AGREE;
     364                 :            : 
     365                 :          4 :         kari = ri->d.kari;
     366                 :          4 :         kari->version = 3;
     367                 :            : 
     368                 :          4 :         rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
     369         [ -  + ]:          4 :         if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek))
     370                 :            :                 {
     371                 :          0 :                 M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
     372                 :          0 :                 return 0;
     373                 :            :                 }
     374                 :            : 
     375         [ -  + ]:          4 :         if (flags & CMS_USE_KEYID)
     376                 :            :                 {
     377                 :          0 :                 rek->rid->type = CMS_REK_KEYIDENTIFIER;
     378         [ #  # ]:          0 :                 if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip))
     379                 :            :                         return 0;
     380                 :            :                 }
     381                 :            :         else
     382                 :            :                 {
     383                 :          4 :                 rek->rid->type = CMS_REK_ISSUER_SERIAL;
     384         [ +  - ]:          4 :                 if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip))
     385                 :            :                         return 0;
     386                 :            :                 }
     387                 :            : 
     388                 :            :         /* Create ephemeral key */
     389         [ +  - ]:          4 :         if (!cms_kari_create_ephemeral_key(kari, pk))
     390                 :            :                 return 0;
     391                 :            : 
     392                 :          4 :         CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
     393                 :          4 :         rek->pkey = pk;
     394                 :          4 :         return 1;
     395                 :            :         }
     396                 :            : 
     397                 :          4 : static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
     398                 :            :                                 const EVP_CIPHER *cipher)
     399                 :            :         {
     400                 :          4 :         EVP_CIPHER_CTX *ctx = &kari->ctx;
     401                 :            :         const EVP_CIPHER *kekcipher;
     402                 :          4 :         int keylen = EVP_CIPHER_key_length(cipher);
     403                 :            :         /* If a suitable wrap algorithm is already set nothing to do */
     404                 :          4 :         kekcipher = EVP_CIPHER_CTX_cipher(ctx);
     405                 :            : 
     406         [ -  + ]:          4 :         if (kekcipher)
     407                 :            :                 {
     408         [ #  # ]:          0 :                 if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE)
     409                 :            :                         return 0;
     410                 :          0 :                 return 1;
     411                 :            :                 }
     412                 :            :         /* Pick a cipher based on content encryption cipher. If it is
     413                 :            :          * DES3 use DES3 wrap otherwise use AES wrap similar to key
     414                 :            :          * size.
     415                 :            :          */
     416         [ +  + ]:          4 :         if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc)
     417                 :          1 :                 kekcipher = EVP_des_ede3_wrap();
     418         [ +  - ]:          3 :         else if (keylen <= 16)
     419                 :          3 :                 kekcipher = EVP_aes_128_wrap();
     420         [ #  # ]:          0 :         else if (keylen <= 24)
     421                 :          0 :                 kekcipher = EVP_aes_192_wrap();
     422                 :            :         else
     423                 :          0 :                 kekcipher = EVP_aes_256_wrap();
     424                 :          4 :         return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL);
     425                 :            :         }
     426                 :            : 
     427                 :            : /* Encrypt content key in key agreement recipient info */
     428                 :            : 
     429                 :          4 : int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
     430                 :            :         {
     431                 :            :         CMS_KeyAgreeRecipientInfo *kari;
     432                 :            :         CMS_EncryptedContentInfo *ec;
     433                 :            :         CMS_RecipientEncryptedKey *rek;
     434                 :            :         STACK_OF(CMS_RecipientEncryptedKey) *reks;
     435                 :            :         int i;
     436                 :            : 
     437         [ -  + ]:          4 :         if (ri->type != CMS_RECIPINFO_AGREE)
     438                 :            :                 {
     439                 :          0 :                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT,
     440                 :            :                         CMS_R_NOT_KEY_AGREEMENT);
     441                 :          0 :                 return 0;
     442                 :            :                 }
     443                 :          4 :         kari = ri->d.kari;
     444                 :          4 :         reks = kari->recipientEncryptedKeys;
     445                 :          4 :         ec = cms->d.envelopedData->encryptedContentInfo;
     446                 :            :         /* Initialise wrap algorithm parameters */
     447         [ +  - ]:          4 :         if (!cms_wrap_init(kari, ec->cipher))
     448                 :            :                 return 0;
     449                 :            :         /* If no orignator key set up initialise for ephemeral key
     450                 :            :          * the public key ASN1 structure will set the actual public
     451                 :            :          * key value.
     452                 :            :          */
     453         [ +  - ]:          4 :         if (kari->originator->type == -1)
     454                 :            :                 {
     455                 :          4 :                 CMS_OriginatorIdentifierOrKey *oik = kari->originator;
     456                 :          4 :                 oik->type = CMS_OIK_PUBKEY;
     457                 :          4 :                 oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey);
     458         [ +  - ]:          4 :                 if (!oik->d.originatorKey)
     459                 :            :                         return 0;
     460                 :            :                 }
     461                 :            :         /* Initialise KDF algorithm */
     462         [ +  - ]:          4 :         if (!cms_env_asn1_ctrl(ri, 0))
     463                 :            :                 return 0;
     464                 :            :         /* For each rek, derive KEK, encrypt CEK */
     465         [ +  + ]:          8 :         for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++)
     466                 :            :                 {
     467                 :            :                 unsigned char *enckey;
     468                 :            :                 size_t enckeylen;
     469                 :          4 :                 rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
     470         [ +  - ]:          4 :                 if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0)
     471                 :          0 :                         return 0;
     472         [ +  - ]:          4 :                 if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen,
     473                 :            :                                                                 kari, 1))
     474                 :            :                         return 0;
     475                 :          4 :                 ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen);
     476                 :            :                 }
     477                 :            : 
     478                 :            :         return 1;
     479                 :            : 
     480                 :            :         }

Generated by: LCOV version 1.9