summaryrefslogtreecommitdiffstats
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
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)
-rw-r--r--apps/cms.c123
-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
-rw-r--r--doc/man1/openssl-cms.pod.in3
-rw-r--r--doc/man3/CMS_EnvelopedData_create.pod22
-rw-r--r--doc/man3/CMS_encrypt.pod26
-rw-r--r--doc/man3/CMS_get1_ReceiptRequest.pod44
-rw-r--r--doc/man3/CMS_sign.pod31
-rw-r--r--doc/man3/SMIME_read_CMS.pod23
-rw-r--r--include/openssl/cms.h48
20 files changed, 843 insertions, 340 deletions
diff --git a/apps/cms.c b/apps/cms.c
index 2cb92ab85f..7e48cc1c82 100644
--- a/apps/cms.c
+++ b/apps/cms.c
@@ -32,9 +32,9 @@ DEFINE_STACK_OF_STRING()
static int save_certs(char *signerfile, STACK_OF(X509) *signers);
static int cms_cb(int ok, X509_STORE_CTX *ctx);
static void receipt_request_print(CMS_ContentInfo *cms);
-static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
- *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING)
- *rr_from);
+static CMS_ReceiptRequest *make_receipt_request(
+ STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
+ STACK_OF(OPENSSL_STRING) *rr_from, OPENSSL_CTX *libctx, const char *propq);
static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
STACK_OF(OPENSSL_STRING) *param);
@@ -89,7 +89,7 @@ typedef enum OPTION_choice {
OPT_RR_TO, OPT_AES128_WRAP, OPT_AES192_WRAP, OPT_AES256_WRAP,
OPT_3DES_WRAP, OPT_WRAP, OPT_ENGINE,
OPT_R_ENUM,
- OPT_PROV_ENUM,
+ OPT_PROV_ENUM, OPT_CONFIG,
OPT_V_ENUM,
OPT_CIPHER,
OPT_ORIGINATOR
@@ -124,6 +124,7 @@ const OPTIONS cms_options[] = {
# ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
# endif
+ OPT_CONFIG_OPTION,
OPT_SECTION("Action"),
{"encrypt", OPT_ENCRYPT, '-', "Encrypt message"},
@@ -236,8 +237,44 @@ const OPTIONS cms_options[] = {
{NULL}
};
+static CMS_ContentInfo *load_content_info(int informat, BIO *in, BIO **indata,
+ const char *name,
+ OPENSSL_CTX *libctx, const char *propq)
+{
+ CMS_ContentInfo *ret, *ci;
+
+ ret = CMS_ContentInfo_new_with_libctx(libctx, propq);
+ if (ret == NULL) {
+ BIO_printf(bio_err, "Error allocating CMS_contentinfo\n");
+ return NULL;
+ }
+ switch (informat) {
+ case FORMAT_SMIME:
+ ci = SMIME_read_CMS_ex(in, indata, &ret);
+ break;
+ case FORMAT_PEM:
+ ci = PEM_read_bio_CMS(in, &ret, NULL, NULL);
+ break;
+ case FORMAT_ASN1:
+ ci = d2i_CMS_bio(in, &ret);
+ break;
+ default:
+ BIO_printf(bio_err, "Bad input format for %s\n", name);
+ goto err;
+ }
+ if (ci == NULL) {
+ BIO_printf(bio_err, "Error reading %s Content Info\n", name);
+ goto err;
+ }
+ return ret;
+err:
+ CMS_ContentInfo_free(ret);
+ return NULL;
+}
+
int cms_main(int argc, char **argv)
{
+ CONF *conf = NULL;
ASN1_OBJECT *econtent_type = NULL;
BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
CMS_ContentInfo *cms = NULL, *rcms = NULL;
@@ -270,6 +307,8 @@ int cms_main(int argc, char **argv)
long ltmp;
const char *mime_eol = "\n";
OPTION_CHOICE o;
+ OPENSSL_CTX *libctx = app_get0_libctx();
+ const char *propq = app_get0_propq();
if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
return 1;
@@ -417,14 +456,14 @@ int cms_main(int argc, char **argv)
rr_allorfirst = 1;
break;
case OPT_RCTFORM:
- if (rctformat == FORMAT_SMIME)
- rcms = SMIME_read_CMS(rctin, NULL);
- else if (rctformat == FORMAT_PEM)
- rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
- else if (rctformat == FORMAT_ASN1)
+ if (rctformat == FORMAT_ASN1) {
if (!opt_format(opt_arg(),
OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat))
goto opthelp;
+ } else {
+ rcms = load_content_info(rctformat, rctin, NULL, "recipient",
+ libctx, propq);
+ }
break;
case OPT_CERTFILE:
certfile = opt_arg();
@@ -639,6 +678,11 @@ int cms_main(int argc, char **argv)
if (!opt_provider(o))
goto end;
break;
+ case OPT_CONFIG:
+ conf = app_load_config_modules(opt_arg());
+ if (conf == NULL)
+ goto end;
+ break;
case OPT_3DES_WRAP:
# ifndef OPENSSL_NO_DES
wrap_cipher = EVP_des_ede3_wrap();
@@ -830,21 +874,9 @@ int cms_main(int argc, char **argv)
goto end;
if (operation & SMIME_IP) {
- if (informat == FORMAT_SMIME) {
- cms = SMIME_read_CMS(in, &indata);
- } else if (informat == FORMAT_PEM) {
- cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
- } else if (informat == FORMAT_ASN1) {
- cms = d2i_CMS_bio(in, NULL);
- } else {
- BIO_printf(bio_err, "Bad input format for CMS file\n");
- goto end;
- }
-
- if (cms == NULL) {
- BIO_printf(bio_err, "Error reading S/MIME message\n");
+ cms = load_content_info(informat, in, &indata, "SMIME", libctx, propq);
+ if (cms == NULL)
goto end;
- }
if (contfile != NULL) {
BIO_free(indata);
if ((indata = BIO_new_file(contfile, "rb")) == NULL) {
@@ -872,21 +904,10 @@ int cms_main(int argc, char **argv)
goto end;
}
- if (rctformat == FORMAT_SMIME) {
- rcms = SMIME_read_CMS(rctin, NULL);
- } else if (rctformat == FORMAT_PEM) {
- rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
- } else if (rctformat == FORMAT_ASN1) {
- rcms = d2i_CMS_bio(rctin, NULL);
- } else {
- BIO_printf(bio_err, "Bad input format for receipt\n");
- goto end;
- }
-
- if (rcms == NULL) {
- BIO_printf(bio_err, "Error reading receipt\n");
+ rcms = load_content_info(rctformat, rctin, NULL, "recipient", libctx,
+ propq);
+ if (rcms == NULL)
goto end;
- }
}
out = bio_open_default(outfile, 'w', outformat);
@@ -905,15 +926,15 @@ int cms_main(int argc, char **argv)
ret = 3;
if (operation == SMIME_DATA_CREATE) {
- cms = CMS_data_create(in, flags);
+ cms = CMS_data_create_with_libctx(in, flags, libctx, propq);
} else if (operation == SMIME_DIGEST_CREATE) {
- cms = CMS_digest_create(in, sign_md, flags);
+ cms = CMS_digest_create_with_libctx(in, sign_md, flags, libctx, propq);
} else if (operation == SMIME_COMPRESS) {
cms = CMS_compress(in, -1, flags);
} else if (operation == SMIME_ENCRYPT) {
int i;
flags |= CMS_PARTIAL;
- cms = CMS_encrypt(NULL, in, cipher, flags);
+ cms = CMS_encrypt_with_libctx(NULL, in, cipher, flags, libctx, propq);
if (cms == NULL)
goto end;
for (i = 0; i < sk_X509_num(encerts); i++) {
@@ -978,8 +999,9 @@ int cms_main(int argc, char **argv)
goto end;
}
} else if (operation == SMIME_ENCRYPTED_ENCRYPT) {
- cms = CMS_EncryptedData_encrypt(in, cipher,
- secret_key, secret_keylen, flags);
+ cms = CMS_EncryptedData_encrypt_with_libctx(in, cipher, secret_key,
+ secret_keylen, flags,
+ libctx, propq);
} else if (operation == SMIME_SIGN_RECEIPT) {
CMS_ContentInfo *srcms = NULL;
@@ -1007,14 +1029,15 @@ int cms_main(int argc, char **argv)
flags |= CMS_STREAM;
}
flags |= CMS_PARTIAL;
- cms = CMS_sign(NULL, NULL, other, in, flags);
+ cms = CMS_sign_with_libctx(NULL, NULL, other, in, flags, libctx, propq);
if (cms == NULL)
goto end;
if (econtent_type != NULL)
CMS_set1_eContentType(cms, econtent_type);
if (rr_to != NULL) {
- rr = make_receipt_request(rr_to, rr_allorfirst, rr_from);
+ rr = make_receipt_request(rr_to, rr_allorfirst, rr_from, libctx,
+ propq);
if (rr == NULL) {
BIO_puts(bio_err,
"Signed Receipt Request Creation Error\n");
@@ -1231,6 +1254,7 @@ int cms_main(int argc, char **argv)
BIO_free(indata);
BIO_free_all(out);
OPENSSL_free(passin);
+ NCONF_free(conf);
return ret;
}
@@ -1367,9 +1391,10 @@ static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
return NULL;
}
-static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
- *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING)
- *rr_from)
+static CMS_ReceiptRequest *make_receipt_request(
+ STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
+ STACK_OF(OPENSSL_STRING) *rr_from,
+ OPENSSL_CTX *libctx, const char *propq)
{
STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL;
CMS_ReceiptRequest *rr;
@@ -1383,8 +1408,8 @@ static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
} else {
rct_from = NULL;
}
- rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
- rct_to);
+ rr = CMS_ReceiptRequest_create0_with_libctx(NULL, -1, rr_allorfirst,
+ rct_from, rct_to, libctx, propq);
return rr;
err:
sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free);
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 ch