X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fcms%2Fcms_enc.c;h=bebeaf29c7bad36efb75faad841cf6527e400f31;hp=f96c46f4e6cab070d78fabeadd5946242a484dca;hb=5762f7778da56b9502534fd236007b9a1b0244d9;hpb=a981e2adbcc0edafd7a4db6440b87018399f9919 diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c index f96c46f4e6..bebeaf29c7 100644 --- a/crypto/cms/cms_enc.c +++ b/crypto/cms/cms_enc.c @@ -59,7 +59,6 @@ #include #include #include "cms_lcl.h" -#include "asn1_locl.h" /* CMS EncryptedData Utilities */ @@ -74,6 +73,8 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) const EVP_CIPHER *ciph; X509_ALGOR *calg = ec->contentEncryptionAlgorithm; unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; + unsigned char *tkey = NULL; + size_t tkeylen = 0; int ok = 0; @@ -92,7 +93,14 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) BIO_get_cipher_ctx(b, &ctx); if (enc) + { ciph = ec->cipher; + /* If not keeping key set cipher to NULL so subsequent calls + * decrypt. + */ + if (ec->key) + ec->cipher = NULL; + } else { ciph = EVP_get_cipherbyobj(calg->algorithm); @@ -112,12 +120,10 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) goto err; } - if (enc) - calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); - if (enc) { int ivlen; + calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); /* Generate a random IV if we need one */ ivlen = EVP_CIPHER_CTX_iv_length(ctx); if (ivlen > 0) @@ -128,37 +134,62 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) } } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) - { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); - goto err; - } - - - if (enc && !ec->key) + goto err; + } + tkeylen = EVP_CIPHER_CTX_key_length(ctx); + /* Generate random session key */ + 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) + tkey = OPENSSL_malloc(tkeylen); + if (!tkey) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } - if (EVP_CIPHER_CTX_rand_key(ctx, ec->key) <= 0) + if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) goto err; - keep_key = 1; } - else if (ec->keylen != EVP_CIPHER_CTX_key_length(ctx)) + + if (!ec->key) + { + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + if (enc) + keep_key = 1; + else + ERR_clear_error(); + + } + + if (ec->keylen != tkeylen) { /* If necessary set key length */ if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_INVALID_KEY_LENGTH); - goto err; + /* Only reveal failure if debugging so we don't + * leak information which may be useful in MMA. + */ + if (enc || ec->debug) + { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_INVALID_KEY_LENGTH); + goto err; + } + else + { + /* Use random key */ + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + ERR_clear_error(); + } } } @@ -194,6 +225,11 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) OPENSSL_free(ec->key); ec->key = NULL; } + if (tkey) + { + OPENSSL_cleanse(tkey, tkeylen); + OPENSSL_free(tkey); + } if (ok) return b; BIO_free(b); @@ -252,7 +288,7 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms) { CMS_EncryptedData *enc = cms->d.encryptedData; - if (enc->unprotectedAttrs) + if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) enc->version = 2; return cms_EncryptedContent_init_bio(enc->encryptedContentInfo); }