X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fcms%2Fcms_enc.c;h=bebeaf29c7bad36efb75faad841cf6527e400f31;hb=5762f7778da56b9502534fd236007b9a1b0244d9;hp=fbf87b6735e2a62b974a9dd9323674a231bc14f2;hpb=e540d1cd77d4cf0edea74212a5e598d073ce2e67;p=oweals%2Fopenssl.git diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c index fbf87b6735..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,10 +73,12 @@ 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; - int enc; + int enc, keep_key = 0; enc = ec->cipher ? 1 : 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,21 +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, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + tkeylen = EVP_CIPHER_CTX_key_length(ctx); + /* Generate random session key */ + if (!enc || !ec->key) + { + tkey = OPENSSL_malloc(tkeylen); + if (!tkey) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + ERR_R_MALLOC_FAILURE); goto err; } + if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) + goto err; + } - /* If necessary set key length */ + if (!ec->key) + { + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + if (enc) + keep_key = 1; + else + ERR_clear_error(); + + } - if (ec->keylen != EVP_CIPHER_CTX_key_length(ctx)) + 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(); + } } } @@ -172,12 +219,17 @@ 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); ec->key = NULL; } + if (tkey) + { + OPENSSL_cleanse(tkey, tkeylen); + OPENSSL_free(tkey); + } if (ok) return b; BIO_free(b); @@ -189,13 +241,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 +258,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); @@ -227,13 +287,8 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms) { - CMS_EncryptedContentInfo *ec; - if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) - { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_INIT_BIO, - CMS_R_NOT_ENCRYPTED_DATA); - return NULL; - } - ec = cms->d.encryptedData->encryptedContentInfo; - return cms_EncryptedContent_init_bio(ec); + CMS_EncryptedData *enc = cms->d.encryptedData; + if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) + enc->version = 2; + return cms_EncryptedContent_init_bio(enc->encryptedContentInfo); }