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 | |
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')
-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 |
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);< |