summaryrefslogtreecommitdiffstats
path: root/crypto/cms
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
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')
-rw-r--r--crypto/cms/cms_cd.c7
-rw-r--r--crypto/cms/cms_dd.c12
-rw-r--r--crypto/cms/cms_enc.c38
-rw-r--r--crypto/cms/cms_env.c126
-rw-r--r--crypto/cms/cms_ess.c47
-rw-r--r--crypto/cms/cms_io.c33
-rw-r--r--crypto/cms/cms_kari.c52
-rw-r--r--crypto/cms/cms_lib.c116
-rw-r--r--crypto/cms/cms_local.h49
-rw-r--r--crypto/cms/cms_pwri.c32
-rw-r--r--crypto/cms/cms_sd.c137
-rw-r--r--crypto/cms/cms_smime.c214
12 files changed, 618 insertions, 245 deletions
diff --git a/crypto/cms/cms_cd.c b/crypto/cms/cms_cd.c
index ac40275b63..c596eab2c2 100644
--- a/crypto/cms/cms_cd.c
+++ b/crypto/cms/cms_cd.c
@@ -21,10 +21,12 @@
/* CMS CompressedData Utilities */
-CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
+CMS_ContentInfo *cms_CompressedData_create(int comp_nid, OPENSSL_CTX *libctx,
+ const char *propq)
{
CMS_ContentInfo *cms;
CMS_CompressedData *cd;
+
/*
* Will need something cleverer if there is ever more than one
* compression algorithm or parameters have some meaning...
@@ -34,7 +36,7 @@ CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
return NULL;
}
- cms = CMS_ContentInfo_new();
+ cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
if (cms == NULL)
return NULL;
@@ -64,6 +66,7 @@ BIO *cms_CompressedData_init_bio(const CMS_ContentInfo *cms)
{
CMS_CompressedData *cd;
const ASN1_OBJECT *compoid;
+
if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) {
CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA);
diff --git a/crypto/cms/cms_dd.c b/crypto/cms/cms_dd.c
index 9da26476e0..2b2d970acd 100644
--- a/crypto/cms/cms_dd.c
+++ b/crypto/cms/cms_dd.c
@@ -17,11 +17,13 @@
/* CMS DigestedData Utilities */
-CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md,
+ OPENSSL_CTX *libctx, const char *propq)
{
CMS_ContentInfo *cms;
CMS_DigestedData *dd;
- cms = CMS_ContentInfo_new();
+
+ cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
if (cms == NULL)
return NULL;
@@ -47,9 +49,9 @@ CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
BIO *cms_DigestedData_init_bio(const CMS_ContentInfo *cms)
{
- CMS_DigestedData *dd;
- dd = cms->d.digestedData;
- return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
+ CMS_DigestedData *dd = cms->d.digestedData;
+
+ return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm, cms_get0_cmsctx(cms));
}
int cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, int verify)
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));
}
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c
index a5ef2ddee5..94961cd038 100644
--- a/crypto/cms/cms_env.c
+++ b/crypto/cms/cms_env.c
@@ -14,9 +14,10 @@
#include <openssl/err.h>
#include <openssl/cms.h>
#include <openssl/evp.h>
-#include "cms_local.h"
#include "crypto/asn1.h"
#include "crypto/evp.h"
+#include "crypto/x509.h"
+#include "cms_local.h"
DEFINE_STACK_OF(CMS_RecipientInfo)
DEFINE_STACK_OF(CMS_RevocationInfoChoice)
@@ -94,6 +95,37 @@ STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
return env->recipientInfos;
}
+void cms_RecipientInfos_set_cmsctx(CMS_ContentInfo *cms)
+{
+ int i;
+ CMS_RecipientInfo *ri;
+ const CMS_CTX *ctx = cms_get0_cmsctx(cms);
+ STACK_OF(CMS_RecipientInfo) *rinfos = CMS_get0_RecipientInfos(cms);
+
+ for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) {
+ ri = sk_CMS_RecipientInfo_value(rinfos, i);
+ if (ri != NULL) {
+ switch (ri->type) {
+ case CMS_RECIPINFO_AGREE:
+ ri->d.kari->cms_ctx = ctx;
+ break;
+ case CMS_RECIPINFO_TRANS:
+ ri->d.ktri->cms_ctx = ctx;
+ x509_set0_libctx(ri->d.ktri->recip, ctx->libctx, ctx->propq);
+ break;
+ case CMS_RECIPINFO_KEK:
+ ri->d.kekri->cms_ctx = ctx;
+ break;
+ case CMS_RECIPINFO_PASS:
+ ri->d.pwri->cms_ctx = ctx;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
{
return ri->type;
@@ -108,26 +140,35 @@ EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
return NULL;
}
-CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
+CMS_ContentInfo *CMS_EnvelopedData_create_with_libctx(const EVP_CIPHER *cipher,
+ OPENSSL_CTX *libctx,
+ const char *propq)
{
CMS_ContentInfo *cms;
CMS_EnvelopedData *env;
- cms = CMS_ContentInfo_new();
+
+ cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
if (cms == NULL)
goto merr;
env = cms_enveloped_data_init(cms);
if (env == NULL)
goto merr;
- if (!cms_EncryptedContent_init(env->encryptedContentInfo,
- cipher, NULL, 0))
+
+ if (!cms_EncryptedContent_init(env->encryptedContentInfo, cipher, NULL, 0,
+ cms_get0_cmsctx(cms)))
goto merr;
return cms;
merr:
CMS_ContentInfo_free(cms);
- CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
+ CMSerr(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
+{
+ return CMS_EnvelopedData_create_with_libctx(cipher, NULL, NULL);
+}
+
int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain)
{
CMS_EnvelopedData *env = NULL;
@@ -174,7 +215,8 @@ int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain)
/* Initialise a ktri based on passed certificate and key */
static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
- EVP_PKEY *pk, unsigned int flags)
+ EVP_PKEY *pk, unsigned int flags,
+ const CMS_CTX *ctx)
{
CMS_KeyTransRecipientInfo *ktri;
int idtype;
@@ -185,6 +227,7 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
ri->type = CMS_RECIPINFO_TRANS;
ktri = ri->d.ktri;
+ ktri->cms_ctx = ctx;
if (flags & CMS_USE_KEYID) {
ktri->version = 2;
@@ -199,7 +242,7 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
* structure.
*/
- if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype))
+ if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype, ctx))
return 0;
X509_up_ref(recip);
@@ -209,7 +252,8 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
ktri->recip = recip;
if (flags & CMS_KEY_PARAM) {
- ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
+ ktri->pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ktri->pkey,
+ ctx->propq);
if (ktri->pctx == NULL)
return 0;
if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
@@ -230,6 +274,8 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip,
CMS_RecipientInfo *ri = NULL;
CMS_EnvelopedData *env;
EVP_PKEY *pk = NULL;
+ const CMS_CTX *ctx = cms_get0_cmsctx(cms);
+
env = cms_get0_enveloped(cms);
if (!env)
goto err;
@@ -248,12 +294,13 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip,
switch (cms_pkey_get_ri_type(pk)) {
case CMS_RECIPINFO_TRANS:
- if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags))
+ if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags, ctx))
goto err;
break;
case CMS_RECIPINFO_AGREE:
- if (!cms_RecipientInfo_kari_init(ri, recip, pk, originator, originatorPrivKey, flags))
+ if (!cms_RecipientInfo_kari_init(ri, recip, pk, originator,
+ originatorPrivKey, flags, ctx))
goto err;
break;
@@ -352,6 +399,7 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms,
EVP_PKEY_CTX *pctx;
unsigned char *ek = NULL;
size_t eklen;
+ const CMS_CTX *ctx = cms_get0_cmsctx(cms);
int ret = 0;
@@ -368,7 +416,7 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms,
if (!cms_env_asn1_ctrl(ri, 0))
goto err;
} else {
- pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
+ pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ktri->pkey, ctx->propq);
if (pctx == NULL)
return 0;
@@ -405,7 +453,6 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms,
ktri->pctx = NULL;
OPENSSL_free(ek);
return ret;
-
}
/* Decrypt content key from KTRI */
@@ -419,7 +466,10 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
size_t eklen;
int ret = 0;
size_t fixlen = 0;
+ EVP_CIPHER *ciph = NULL;
CMS_EncryptedContentInfo *ec;
+ const CMS_CTX *ctx = cms_get0_cmsctx(cms);
+
ec = cms->d.envelopedData->encryptedContentInfo;
if (ktri->pkey == NULL) {
@@ -430,19 +480,21 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
if (cms->d.envelopedData->encryptedContentInfo->havenocert
&& !cms->d.envelopedData->encryptedContentInfo->debug) {
X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
- const EVP_CIPHER *ciph = EVP_get_cipherbyobj(calg->algorithm);
+ const char *name = OBJ_nid2sn(OBJ_obj2nid(calg->algorithm));
+ ciph = EVP_CIPHER_fetch(ctx->libctx, name, ctx->propq);
if (ciph == NULL) {
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_UNKNOWN_CIPHER);
return 0;
}
fixlen = EVP_CIPHER_key_length(ciph);
+ EVP_CIPHER_free(ciph);
}
- ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
+ ktri->pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, ctx->propq);
if (ktri->pctx == NULL)
- return 0;
+ goto err;
if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
goto err;
@@ -627,7 +679,6 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
err:
M_ASN1_free_of(ri, CMS_RecipientInfo);
return NULL;
-
}
int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
@@ -679,20 +730,24 @@ int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
return 1;
}
-static const EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen)
+static EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen, const CMS_CTX *ctx)
{
+ const char *alg = NULL;
+
switch(keylen) {
case 16:
- return EVP_aes_128_wrap();
-
+ alg = "AES-128-WRAP";
+ break;
case 24:
- return EVP_aes_192_wrap();
-
+ alg = "AES-192-WRAP";
+ break;
case 32:
- return EVP_aes_256_wrap();
+ alg = "AES-256-WRAP";
+ break;
+ default:
+ return NULL;
}
-
- return NULL;
+ return EVP_CIPHER_fetch(ctx->libctx, alg, ctx->propq);
}
@@ -706,9 +761,10 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms,
unsigned char *wkey = NULL;
int wkeylen;
int r = 0;
- const EVP_CIPHER *cipher = NULL;
+ EVP_CIPHER *cipher = NULL;
int outlen = 0;
EVP_CIPHER_CTX *ctx = NULL;
+ const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms);
ec = cms->d.envelopedData->encryptedContentInfo;
@@ -719,7 +775,7 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms,
return 0;
}
- cipher = cms_get_key_wrap_cipher(kekri->keylen);
+ cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx);
if (cipher == NULL) {
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_INVALID_KEY_LENGTH);
goto err;
@@ -756,12 +812,12 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms,
r = 1;
err:
+ EVP_CIPHER_free(cipher);
if (!r)
OPENSSL_free(wkey);
EVP_CIPHER_CTX_free(ctx);
return r;
-
}
/* Decrypt content key in KEK recipient info */
@@ -774,9 +830,10 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
unsigned char *ukey = NULL;
int ukeylen;
int r = 0, wrap_nid;
- const EVP_CIPHER *cipher = NULL;
+ EVP_CIPHER *cipher = NULL;
int outlen = 0;
EVP_CIPHER_CTX *ctx = NULL;
+ const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms);
ec = cms->d.envelopedData->encryptedContentInfo;
@@ -802,7 +859,7 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
goto err;
}
- cipher = cms_get_key_wrap_cipher(kekri->keylen);
+ cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx);
if (cipher == NULL) {
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_INVALID_KEY_LENGTH);
goto err;
@@ -836,12 +893,12 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
r = 1;
err:
+ EVP_CIPHER_free(cipher);
if (!r)
OPENSSL_free(ukey);
EVP_CIPHER_CTX_free(ctx);
return r;
-
}
int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
@@ -951,7 +1008,7 @@ static void cms_env_set_version(CMS_EnvelopedData *env)
static BIO *cms_EnvelopedData_Decryption_init_bio(CMS_ContentInfo *cms)
{
CMS_EncryptedContentInfo *ec = cms->d.envelopedData->encryptedContentInfo;
- BIO *contentBio = cms_EncryptedContent_init_bio(ec);
+ BIO *contentBio = cms_EncryptedContent_init_bio(ec, cms_get0_cmsctx(cms));
EVP_CIPHER_CTX *ctx = NULL;
if (contentBio == NULL)
@@ -986,7 +1043,7 @@ static BIO *cms_EnvelopedData_Encryption_init_bio(CMS_ContentInfo *cms)
/* Get BIO first to set up key */
ec = cms->d.envelopedData->encryptedContentInfo;
- ret = cms_EncryptedContent_init_bio(ec);
+ ret = cms_EncryptedContent_init_bio(ec, cms_get0_cmsctx(cms));
/* If error end of processing */
if (!ret)
@@ -1051,7 +1108,8 @@ int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type)
if (pk->ameth != NULL && pk->ameth->pkey_ctrl != NULL) {
int i, r;
- i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED, ri_type, &r);
+ i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED,
+ ri_type, &r);
if (i > 0)
return r;
}
diff --git a/crypto/cms/cms_ess.c b/crypto/cms/cms_ess.c
index e3604f7db8..3e545b7add 100644
--- a/crypto/cms/cms_ess.c
+++ b/crypto/cms/cms_ess.c
@@ -15,9 +15,10 @@
#include <openssl/err.h>
#include <openssl/cms.h>
#include <openssl/ess.h>
-#include "cms_local.h"
#include "crypto/ess.h"
#include "crypto/cms.h"
+#include "crypto/x509.h"
+#include "cms_local.h"
DEFINE_STACK_OF(GENERAL_NAMES)
DEFINE_STACK_OF(CMS_SignerInfo)
@@ -119,11 +120,10 @@ int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain)
return ret;
}
-CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
- int allorfirst,
- STACK_OF(GENERAL_NAMES)
- *receiptList, STACK_OF(GENERAL_NAMES)
- *receiptsTo)
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0_with_libctx(
+ unsigned char *id, int idlen, int allorfirst,
+ STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo,
+ OPENSSL_CTX *libctx, const char *propq)
{
CMS_ReceiptRequest *rr;
@@ -135,14 +135,14 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
else {
if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
goto merr;
- if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0)
+ if (RAND_bytes_ex(libctx, rr->signedContentIdentifier->data, 32) <= 0)
goto err;
}
sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
rr->receiptsTo = receiptsTo;
- if (receiptList) {
+ if (receiptList != NULL) {
rr->receiptsFrom->type = 1;
rr->receiptsFrom->d.receiptList = receiptList;
} else {
@@ -153,7 +153,7 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
return rr;
merr:
- CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);
+ CMSerr(0, ERR_R_MALLOC_FAILURE);
err:
CMS_ReceiptRequest_free(rr);
@@ -161,6 +161,15 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
}
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(
+ unsigned char *id, int idlen, int allorfirst,
+ STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo)
+{
+ return CMS_ReceiptRequest_create0_with_libctx(id, idlen, allorfirst,
+ receiptList, receiptsTo,
+ NULL, NULL);
+}
+
int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
{
unsigned char *rrder = NULL;
@@ -192,20 +201,20 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
STACK_OF(GENERAL_NAMES) **plist,
STACK_OF(GENERAL_NAMES) **prto)
{
- if (pcid)
+ if (pcid != NULL)
*pcid = rr->signedContentIdentifier;
if (rr->receiptsFrom->type == 0) {
- if (pallorfirst)
+ if (pallorfirst != NULL)
*pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
- if (plist)
+ if (plist != NULL)
*plist = NULL;
} else {
- if (pallorfirst)
+ if (pallorfirst != NULL)
*pallorfirst = -1;
- if (plist)
+ if (plist != NULL)
*plist = rr->receiptsFrom->d.receiptList;
}
- if (prto)
+ if (prto != NULL)
*prto = rr->receiptsTo;
}
@@ -214,13 +223,13 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
static int cms_msgSigDigest(CMS_SignerInfo *si,
unsigned char *dig, unsigned int *diglen)
{
- const EVP_MD *md;
+ const EVP_MD *md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
- md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
if (md == NULL)
return 0;
- if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
- si->signedAttrs, dig, diglen))
+ if (!asn1_item_digest_with_libctx(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
+ si->signedAttrs, dig, diglen,
+ si->cms_ctx->libctx, si->cms_ctx->propq))
return 0;
return 1;
}
diff --git a/crypto/cms/cms_io.c b/crypto/cms/cms_io.c
index ef72164181..70a7c652e9 100644
--- a/crypto/cms/cms_io.c
+++ b/crypto/cms/cms_io.c
@@ -35,7 +35,12 @@ int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
{
- return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
+ CMS_ContentInfo *ci;
+
+ ci = ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
+ if (ci != NULL && cms != NULL)
+ cms_resolve_libctx(ci);
+ return ci;
}
int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
@@ -71,19 +76,33 @@ int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
STACK_OF(X509_ALGOR) *mdalgs;
int ctype_nid = OBJ_obj2nid(cms->contentType);
int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
+ const CMS_CTX *ctx = cms_get0_cmsctx(cms);
+
if (ctype_nid == NID_pkcs7_signed)
mdalgs = cms->d.signedData->digestAlgorithms;
else
mdalgs = NULL;
- return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
- ctype_nid, econt_nid, mdalgs,
- ASN1_ITEM_rptr(CMS_ContentInfo));
+ return SMIME_write_ASN1_with_libctx(bio, (ASN1_VALUE *)cms, data, flags,
+ ctype_nid, econt_nid, mdalgs,
+ ASN1_ITEM_rptr(CMS_ContentInfo),
+ cms_ctx_get0_libctx(ctx),
+ cms_ctx_get0_propq(ctx));
+}
+
+CMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, BIO **bcont, CMS_ContentInfo **cms)
+{
+ CMS_ContentInfo *ci;
+
+ ci = (CMS_ContentInfo *)SMIME_read_ASN1_ex(bio, bcont,
+ ASN1_ITEM_rptr(CMS_ContentInfo),
+ (ASN1_VALUE **)cms);
+ if (ci != NULL && cms != NULL)
+ cms_resolve_libctx(ci);
+ return ci;
}
CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
{
- return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
- ASN1_ITEM_rptr
- (CMS_ContentInfo));
+ return SMIME_read_CMS_ex(bio, bcont, NULL);
}
diff --git a/crypto/cms/cms_kari.c b/crypto/cms/cms_kari.c
index 30d38b5fd6..97b601b3bc 100644
--- a/crypto/cms/cms_kari.c
+++ b/crypto/cms/cms_kari.c
@@ -64,6 +64,7 @@ int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
ASN1_INTEGER **sno)
{
CMS_OriginatorIdentifierOrKey *oik;
+
if (ri->type != CMS_RECIPINFO_AGREE) {
CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID,
CMS_R_NOT_KEY_AGREEMENT);
@@ -101,6 +102,7 @@ int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
{
CMS_OriginatorIdentifierOrKey *oik;
+
if (ri->type != CMS_RECIPINFO_AGREE) {
CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP,
CMS_R_NOT_KEY_AGREEMENT);
@@ -121,6 +123,7 @@ int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
X509_NAME **issuer, ASN1_INTEGER **sno)
{
CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
+
if (rid->type == CMS_REK_ISSUER_SERIAL) {
if (issuer)
*issuer = rid->d.issuerAndSerialNumber->issuer;
@@ -152,6 +155,7 @@ int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
X509 *cert)
{
CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
+
if (rid->type == CMS_REK_ISSUER_SERIAL)
return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
else if (rid->type == CMS_REK_KEYIDENTIFIER)
@@ -170,7 +174,8 @@ int CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo *ri, EVP_PKEY *p
if (pk == NULL)
return 1;
- pctx = EVP_PKEY_CTX_new(pk, NULL);
+ pctx = EVP_PKEY_CTX_new_from_pkey(kari->cms_ctx->libctx, pk,
+ kari->cms_ctx->propq);
if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0)
goto err;
@@ -215,6 +220,7 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
int rv = 0;
unsigned char *out = NULL;
int outlen;
+
keklen = EVP_CIPHER_CTX_key_length(kari->ctx);
if (keklen > EVP_MAX_KEY_LENGTH)
return 0;
@@ -303,8 +309,9 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *ekey = NULL;
int rv = 0;
+ const CMS_CTX *ctx = kari->cms_ctx;
- pctx = EVP_PKEY_CTX_new(pk, NULL);
+ pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pk, ctx->propq);
if (pctx == NULL)
goto err;
if (EVP_PKEY_keygen_init(pctx) <= 0)
@@ -312,7 +319,7 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
goto err;
EVP_PKEY_CTX_free(pctx);
- pctx = EVP_PKEY_CTX_new(ekey, NULL);
+ pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ekey, ctx->propq);
if (pctx == NULL)
goto err;
if (EVP_PKEY_derive_init(pctx) <= 0)
@@ -327,12 +334,14 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
}
/* Set originator private key and initialise context based on it */
-static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari, EVP_PKEY *originatorPrivKey )
+static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari,
+ EVP_PKEY *originatorPrivKey )
{
EVP_PKEY_CTX *pctx = NULL;
int rv = 0;
+ const CMS_CTX *ctx = kari->cms_ctx;
- pctx = EVP_PKEY_CTX_new(originatorPrivKey, NULL);
+ pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, originatorPrivKey, ctx->propq);
if (pctx == NULL)
goto err;
if (EVP_PKEY_derive_init(pctx) <= 0)
@@ -348,18 +357,22 @@ static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari,
/* Initialise a kari based on passed certificate and key */
-int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *recipPubKey, X509 * originator, EVP_PKEY *originatorPrivKey, unsigned int flags)
+int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
+ EVP_PKEY *recipPubKey, X509 *originator,
+ EVP_PKEY *originatorPrivKey, unsigned int flags,
+ const CMS_CTX *ctx)
{
CMS_KeyAgreeRecipientInfo *kari;
CMS_RecipientEncryptedKey *rek = NULL;
ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
- if (!ri->d.kari)
+ if (ri->d.kari == NULL)
return 0;
ri->type = CMS_RECIPINFO_AGREE;
kari = ri->d.kari;
kari->version = 3;
+ kari->cms_ctx = ctx;
rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
if (rek == NULL)
@@ -419,8 +432,11 @@ int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *r
static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
const EVP_CIPHER *cipher)
{
+ const CMS_CTX *cms_ctx = kari->cms_ctx;
EVP_CIPHER_CTX *ctx = kari->ctx;
const EVP_CIPHER *kekcipher;
+ EVP_CIPHER *fetched_kekcipher;
+ const char *kekcipher_name;
int keylen;
int ret;
@@ -444,8 +460,8 @@ static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
if (kekcipher != NULL) {
if (EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
return 0;
-
- return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL);
+ kekcipher_name = EVP_CIPHER_name(kekcipher);
+ goto enc;
}
}
@@ -455,16 +471,23 @@ static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
*/
#ifndef OPENSSL_NO_DES
if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc)
- kekcipher = EVP_des_ede3_wrap();
+ kekcipher_name = SN_id_smime_alg_CMS3DESwrap;
else
#endif
if (keylen <= 16)
- kekcipher = EVP_aes_128_wrap();
+ kekcipher_name = SN_id_aes128_wrap;
else if (keylen <= 24)
- kekcipher = EVP_aes_192_wrap();
+ kekcipher_name = SN_id_aes192_wrap;
else
- kekcipher = EVP_aes_256_wrap();
- return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL);<