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_pwri.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_pwri.c')
-rw-r--r-- | crypto/cms/cms_pwri.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/crypto/cms/cms_pwri.c b/crypto/cms/cms_pwri.c index 4726165234..1ca5a7ee07 100644 --- a/crypto/cms/cms_pwri.c +++ b/crypto/cms/cms_pwri.c @@ -51,6 +51,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, X509_ALGOR *encalg = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; int ivlen; + const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms); env = cms_get0_enveloped(cms); if (!env) @@ -91,7 +92,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, 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; if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) { CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); @@ -125,6 +126,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, ri->type = CMS_RECIPINFO_PASS; pwri = ri->d.pwri; + pwri->cms_ctx = cms_ctx; /* Since this is overwritten, free up empty structure already there */ X509_ALGOR_free(pwri->keyEncryptionAlgorithm); pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); @@ -232,7 +234,7 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen, static int kek_wrap_key(unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen, - EVP_CIPHER_CTX *ctx) + EVP_CIPHER_CTX *ctx, const CMS_CTX *cms_ctx) { size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); size_t olen; @@ -260,7 +262,8 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen, memcpy(out + 4, in, inlen); /* Add random padding to end */ if (olen > inlen + 4 - && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0) + && RAND_bytes_ex(cms_ctx->libctx, out + 4 + inlen, + olen - 4 - inlen) <= 0) return 0; /* Encrypt twice */ if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen) @@ -275,17 +278,19 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen, /* Encrypt/Decrypt content key in PWRI recipient info */ -int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri, - int en_de) +int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, int en_de) { CMS_EncryptedContentInfo *ec; CMS_PasswordRecipientInfo *pwri; int r = 0; X509_ALGOR *algtmp, *kekalg = NULL; EVP_CIPHER_CTX *kekctx = NULL; - const EVP_CIPHER *kekcipher; + const char *name; + EVP_CIPHER *kekcipher; unsigned char *key = NULL; size_t keylen; + const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms); ec = cms->d.envelopedData->encryptedContentInfo; @@ -312,17 +317,18 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo * return 0; } - kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); + name = OBJ_nid2sn(OBJ_obj2nid(kekalg->algorithm)); + kekcipher = EVP_CIPHER_fetch(cms_ctx->libctx, name, cms_ctx->propq); - if (!kekcipher) { + if (kekcipher == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER); - return 0; + goto err; } kekctx = EVP_CIPHER_CTX_new(); if (kekctx == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); - return 0; + goto err; } /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de)) @@ -349,7 +355,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo * if (en_de) { - if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx)) + if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx, cms_ctx)) goto err; key = OPENSSL_malloc(keylen); @@ -357,7 +363,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo * if (key == NULL) goto err; - if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx)) + if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx, cms_ctx)) goto err; pwri->encryptedKey->data = key; pwri->encryptedKey->length = keylen; @@ -384,7 +390,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo * r = 1; err: - + EVP_CIPHER_free(kekcipher); EVP_CIPHER_CTX_free(kekctx); if (!r) |