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 | |
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)
-rw-r--r-- | apps/cms.c | 123 | ||||
-rw-r--r-- | crypto/cms/cms_cd.c | 7 | ||||
-rw-r--r-- | crypto/cms/cms_dd.c | 12 | ||||
-rw-r--r-- | crypto/cms/cms_enc.c | 38 | ||||
-rw-r--r-- | crypto/cms/cms_env.c | 126 | ||||
-rw-r--r-- | crypto/cms/cms_ess.c | 47 | ||||
-rw-r--r-- | crypto/cms/cms_io.c | 33 | ||||
-rw-r--r-- | crypto/cms/cms_kari.c | 52 | ||||
-rw-r--r-- | crypto/cms/cms_lib.c | 116 | ||||
-rw-r--r-- | crypto/cms/cms_local.h | 49 | ||||
-rw-r--r-- | crypto/cms/cms_pwri.c | 32 | ||||
-rw-r--r-- | crypto/cms/cms_sd.c | 137 | ||||
-rw-r--r-- | crypto/cms/cms_smime.c | 214 | ||||
-rw-r--r-- | doc/man1/openssl-cms.pod.in | 3 | ||||
-rw-r--r-- | doc/man3/CMS_EnvelopedData_create.pod | 22 | ||||
-rw-r--r-- | doc/man3/CMS_encrypt.pod | 26 | ||||
-rw-r--r-- | doc/man3/CMS_get1_ReceiptRequest.pod | 44 | ||||
-rw-r--r-- | doc/man3/CMS_sign.pod | 31 | ||||
-rw-r--r-- | doc/man3/SMIME_read_CMS.pod | 23 | ||||
-rw-r--r-- | include/openssl/cms.h | 48 |
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 |