summaryrefslogtreecommitdiffstats
path: root/crypto/cms
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2008-03-16 13:05:03 +0000
committerDr. Stephen Henson <steve@openssl.org>2008-03-16 13:05:03 +0000
commita981e2adbcc0edafd7a4db6440b87018399f9919 (patch)
tree583cf8a18d391e522564b4258e0ac0d39b6053bc /crypto/cms
parent88fce8539ff531952ebdd9c442c484531042a9ff (diff)
Add support for random key generation: this will be needed by enveloped data.
Diffstat (limited to 'crypto/cms')
-rw-r--r--crypto/cms/cms.h1
-rw-r--r--crypto/cms/cms_enc.c42
-rw-r--r--crypto/cms/cms_err.c1
3 files changed, 35 insertions, 9 deletions
diff --git a/crypto/cms/cms.h b/crypto/cms/cms.h
index 41f0e8687d..f5373cfd50 100644
--- a/crypto/cms/cms.h
+++ b/crypto/cms/cms.h
@@ -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
diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c
index a99ce1b5f2..f96c46f4e6 100644
--- a/crypto/cms/cms_enc.c
+++ b/crypto/cms/cms_enc.c
@@ -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);
diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c
index 3baa40e525..047a3d0fab 100644
--- a/crypto/cms/cms_err.c
+++ b/crypto/cms/cms_err.c
@@ -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"},