Add function CMS_RecipientInfo_encrypt
[oweals/openssl.git] / crypto / cms / cms_env.c
index b3237d4b94e026a7d3808972f92e347456934db2..632dbae760affd481033e30f3a546f2cc68cf4b5 100644 (file)
 /* CMS EnvelopedData Utilities */
 
 DECLARE_ASN1_ITEM(CMS_EnvelopedData)
-DECLARE_ASN1_ITEM(CMS_RecipientInfo)
 DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
 DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
 DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
 
 DECLARE_STACK_OF(CMS_RecipientInfo)
 
-static CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
+CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
        {
        if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped)
                {
@@ -371,6 +370,8 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
        unsigned char *ek = NULL;
        size_t eklen;
        int ret = 0;
+       CMS_EncryptedContentInfo *ec;
+       ec = cms->d.envelopedData->encryptedContentInfo;
 
        if (ktri->pkey == NULL)
                {
@@ -417,8 +418,14 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
 
        ret = 1;
 
-       cms->d.envelopedData->encryptedContentInfo->key = ek;
-       cms->d.envelopedData->encryptedContentInfo->keylen = eklen;
+       if (ec->key)
+               {
+               OPENSSL_cleanse(ec->key, ec->keylen);
+               OPENSSL_free(ec->key);
+               }
+
+       ec->key = ek;
+       ec->keylen = eklen;
 
        err:
        if (pctx)
@@ -786,6 +793,9 @@ int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
                case CMS_RECIPINFO_KEK:
                return cms_RecipientInfo_kekri_decrypt(cms, ri);
 
+               case CMS_RECIPINFO_PASS:
+               return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
+
                default:
                CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
                        CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
@@ -793,12 +803,34 @@ int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
                }
        }
 
+int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
+       {
+       switch (ri->type)
+               {
+               case CMS_RECIPINFO_TRANS:
+               return cms_RecipientInfo_ktri_encrypt(cms, ri);
+
+               case CMS_RECIPINFO_KEK:
+               return cms_RecipientInfo_kekri_encrypt(cms, ri);
+               break;
+
+               case CMS_RECIPINFO_PASS:
+               return cms_RecipientInfo_pwri_crypt(cms, ri, 1);
+               break;
+
+               default:
+               CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT,
+                               CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
+               return 0;
+               }
+       }
+
 BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
        {
        CMS_EncryptedContentInfo *ec;
        STACK_OF(CMS_RecipientInfo) *rinfos;
        CMS_RecipientInfo *ri;
-       int i, r, ok = 0;
+       int i, ok = 0;
        BIO *ret;
 
        /* Get BIO first to set up key */
@@ -818,24 +850,7 @@ BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
        for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
                {
                ri = sk_CMS_RecipientInfo_value(rinfos, i);
-
-               switch (ri->type)
-                       {
-                       case CMS_RECIPINFO_TRANS:
-                       r = cms_RecipientInfo_ktri_encrypt(cms, ri);
-                       break;
-
-                       case CMS_RECIPINFO_KEK:
-                       r = cms_RecipientInfo_kekri_encrypt(cms, ri);
-                       break;
-
-                       default:
-                       CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
-                               CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
-                       goto err;
-                       }
-
-               if (r <= 0)
+               if (CMS_RecipientInfo_encrypt(cms, ri) <= 0)
                        {
                        CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
                                CMS_R_ERROR_SETTING_RECIPIENTINFO);