Add support for random key generation: this will be needed by enveloped data.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 16 Mar 2008 13:05:03 +0000 (13:05 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 16 Mar 2008 13:05:03 +0000 (13:05 +0000)
crypto/cms/cms.h
crypto/cms/cms_enc.c
crypto/cms/cms_err.c

index 41f0e8687d7e06f18200bc699ffb0a602e0887ae..f5373cfd5026043d78281cea88fafe2f59536764 100644 (file)
@@ -352,6 +352,7 @@ void ERR_load_CMS_strings(void);
 #define CMS_R_NO_CONTENT                                116
 #define CMS_R_NO_DEFAULT_DIGEST                                 117
 #define CMS_R_NO_DIGEST_SET                             118
+#define CMS_R_NO_KEY                                    148
 #define CMS_R_NO_MATCHING_DIGEST                        119
 #define CMS_R_NO_MATCHING_RECIPIENT                     147
 #define CMS_R_NO_PRIVATE_KEY                            120
index a99ce1b5f24414e6438df7c4cbf30866e93ecdc3..f96c46f4e6cab070d78fabeadd5946242a484dca 100644 (file)
@@ -77,7 +77,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
 
        int ok = 0;
 
-       int enc;
+       int enc, keep_key = 0;
 
        enc = ec->cipher ? 1 : 0;
 
@@ -134,10 +134,26 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
                        goto err;
                        }
 
-       /* If necessary set key length */
 
-       if (ec->keylen != EVP_CIPHER_CTX_key_length(ctx))
+       if (enc && !ec->key)
                {
+               /* Generate random key */
+               if (!ec->keylen)
+                       ec->keylen = EVP_CIPHER_CTX_key_length(ctx);
+               ec->key = OPENSSL_malloc(ec->keylen);
+               if (!ec->key)
+                       {
+                       CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+                                                       ERR_R_MALLOC_FAILURE);
+                       goto err;
+                       }
+               if (EVP_CIPHER_CTX_rand_key(ctx, ec->key) <= 0)
+                       goto err;
+               keep_key = 1;
+               }
+       else if (ec->keylen != EVP_CIPHER_CTX_key_length(ctx))
+               {
+               /* If necessary set key length */
                if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0)
                        {
                        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
@@ -172,7 +188,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
        ok = 1;
 
        err:
-       if (ec->key)
+       if (ec->key && !keep_key)
                {
                OPENSSL_cleanse(ec->key, ec->keylen);
                OPENSSL_free(ec->key);
@@ -189,13 +205,16 @@ int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
                                const unsigned char *key, size_t keylen)
        {
        ec->cipher = cipher;
-       ec->key = OPENSSL_malloc(keylen);
-       if (!ec->key)
-               return 0;
+       if (key)
+               {
+               ec->key = OPENSSL_malloc(keylen);
+               if (!ec->key)
+                       return 0;
+               memcpy(ec->key, key, keylen);
+               }
+       ec->keylen = keylen;
        if (cipher)
                ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
-       memcpy(ec->key, key, keylen);
-       ec->keylen = keylen;
        return 1;
        }
 
@@ -203,6 +222,11 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
                                const unsigned char *key, size_t keylen)
        {
        CMS_EncryptedContentInfo *ec;
+       if (!key || !keylen)
+               {
+               CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
+               return 0;
+               }
        if (ciph)
                {
                cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
index 3baa40e5254ed4c140bc5fe54c2cda56cdb81eaa..047a3d0fab2745db3b8d8d9aee9fb69c1a61ef0a 100644 (file)
@@ -155,6 +155,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
 {ERR_REASON(CMS_R_NO_CONTENT)            ,"no content"},
 {ERR_REASON(CMS_R_NO_DEFAULT_DIGEST)     ,"no default digest"},
 {ERR_REASON(CMS_R_NO_DIGEST_SET)         ,"no digest set"},
+{ERR_REASON(CMS_R_NO_KEY)                ,"no key"},
 {ERR_REASON(CMS_R_NO_MATCHING_DIGEST)    ,"no matching digest"},
 {ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"},
 {ERR_REASON(CMS_R_NO_PRIVATE_KEY)        ,"no private key"},