summaryrefslogtreecommitdiffstats
path: root/crypto/cms/cms_enc.c
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-07-25 18:04:55 +1000
committerShane Lontis <shane.lontis@oracle.com>2020-08-09 17:34:52 +1000
commitc1669f41eab0e2d9a8c2498718d06b4cd48a9890 (patch)
tree00e024f0935dfa0c93e2f833e69b14bb77a819e4 /crypto/cms/cms_enc.c
parent82a7b2fb001e2ff50389d0894c276880b3bad336 (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.c38
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));
}