summaryrefslogtreecommitdiffstats
path: root/crypto/cms/cms_pwri.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_pwri.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_pwri.c')
-rw-r--r--crypto/cms/cms_pwri.c32
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)