diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-07-25 18:04:55 +1000 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2020-08-09 17:34:52 +1000 |
commit | c1669f41eab0e2d9a8c2498718d06b4cd48a9890 (patch) | |
tree | 00e024f0935dfa0c93e2f833e69b14bb77a819e4 /crypto/cms/cms_enc.c | |
parent | 82a7b2fb001e2ff50389d0894c276880b3bad336 (diff) |
Add libctx support to CMS.
-Public CMS methods that create a CMS_ContentInfo object now have variants that also add a libctx and propq.
This includes CMS_ContentInfo_new_with_libctx(), CMS_sign_with_libctx(), CMS_data_create_with_libctx(),
CMS_digest_create_with_libctx(), CMS_EncryptedData_encrypt_with_libctx(), CMS_EnvelopedData_create_with_libctx().
-Added CMS_ReceiptRequest_create0_with_libctx().
-Added SMIME_read_CMS_ex() so that a new CMS_ContentInfo object (created using CMS_ContentInfo_new_with_libctx()) can
be passed to the read.
-d2i_CMS_bio() has been modified so that after it loads the CMS_ContentInfo() it then resolves any subobjects that require
the libctx/propq (such as objects containing X509 certificates).
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11884)
Diffstat (limited to 'crypto/cms/cms_enc.c')
-rw-r--r-- | crypto/cms/cms_enc.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c index 3eb2f41a6a..e25453ec9c 100644 --- a/crypto/cms/cms_enc.c +++ b/crypto/cms/cms_enc.c @@ -20,19 +20,19 @@ /* Return BIO based on EncryptedContentInfo and key */ -BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) +BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, + const CMS_CTX *cms_ctx) { BIO *b; EVP_CIPHER_CTX *ctx; - const EVP_CIPHER *ciph; + EVP_CIPHER *fetched_ciph = NULL; + const EVP_CIPHER *cipher = NULL; X509_ALGOR *calg = ec->contentEncryptionAlgorithm; unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; unsigned char *tkey = NULL; int len; size_t tkeylen = 0; - int ok = 0; - int enc, keep_key = 0; enc = ec->cipher ? 1 : 0; @@ -46,26 +46,29 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) BIO_get_cipher_ctx(b, &ctx); if (enc) { - ciph = ec->cipher; + cipher = ec->cipher; /* * If not keeping key set cipher to NULL so subsequent calls decrypt. */ - if (ec->key) + if (ec->key != NULL) ec->cipher = NULL; } else { - ciph = EVP_get_cipherbyobj(calg->algorithm); - - if (!ciph) { + cipher = EVP_get_cipherbyobj(calg->algorithm); + } + if (cipher != NULL) { + fetched_ciph = EVP_CIPHER_fetch(cms_ctx->libctx, EVP_CIPHER_name(cipher), + cms_ctx->propq); + if (fetched_ciph == NULL) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); goto err; } } - - if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { + if (EVP_CipherInit_ex(ctx, fetched_ciph, NULL, NULL, NULL, enc) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } + EVP_CIPHER_free(fetched_ciph); if (enc) { int ivlen; @@ -73,7 +76,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) /* Generate a random IV if we need one */ ivlen = EVP_CIPHER_CTX_iv_length(ctx); if (ivlen > 0) { - if (RAND_bytes(iv, ivlen) <= 0) + if (RAND_bytes_ex(cms_ctx->libctx, iv, ivlen) <= 0) goto err; piv = iv; } @@ -169,7 +172,8 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, const EVP_CIPHER *cipher, - const unsigned char *key, size_t keylen) + const unsigned char *key, size_t keylen, + const CMS_CTX *cms_ctx) { ec->cipher = cipher; if (key) { @@ -180,7 +184,7 @@ int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, memcpy(ec->key, key, keylen); } ec->keylen = keylen; - if (cipher) + if (cipher != NULL) ec->contentType = OBJ_nid2obj(NID_pkcs7_data); return 1; } @@ -189,6 +193,7 @@ 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; @@ -206,7 +211,7 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, return 0; } ec = cms->d.encryptedData->encryptedContentInfo; - return cms_EncryptedContent_init(ec, ciph, key, keylen); + return cms_EncryptedContent_init(ec, ciph, key, keylen, cms_get0_cmsctx(cms)); } BIO *cms_EncryptedData_init_bio(const CMS_ContentInfo *cms) @@ -214,5 +219,6 @@ BIO *cms_EncryptedData_init_bio(const CMS_ContentInfo *cms) CMS_EncryptedData *enc = cms->d.encryptedData; if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) enc->version = 2; - return cms_EncryptedContent_init_bio(enc->encryptedContentInfo); + return cms_EncryptedContent_init_bio(enc->encryptedContentInfo, + cms_get0_cmsctx(cms)); } |