Add libctx support to CMS.
authorShane Lontis <shane.lontis@oracle.com>
Sat, 25 Jul 2020 08:04:55 +0000 (18:04 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Sun, 9 Aug 2020 07:34:52 +0000 (17:34 +1000)
-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)

20 files changed:
apps/cms.c
crypto/cms/cms_cd.c
crypto/cms/cms_dd.c
crypto/cms/cms_enc.c
crypto/cms/cms_env.c
crypto/cms/cms_ess.c
crypto/cms/cms_io.c
crypto/cms/cms_kari.c
crypto/cms/cms_lib.c
crypto/cms/cms_local.h
crypto/cms/cms_pwri.c
crypto/cms/cms_sd.c
crypto/cms/cms_smime.c
doc/man1/openssl-cms.pod.in
doc/man3/CMS_EnvelopedData_create.pod
doc/man3/CMS_encrypt.pod
doc/man3/CMS_get1_ReceiptRequest.pod
doc/man3/CMS_sign.pod
doc/man3/SMIME_read_CMS.pod
include/openssl/cms.h

index 2cb92ab85f4a447e690d5c06d5c93cfcdbd8116c..7e48cc1c82e67327110ec5eb06408f810bd51764 100644 (file)
@@ -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);
index ac40275b638016c95b2ea40eb3cfbaa050ef50a3..c596eab2c2f278d4c7f6712ab63ea4b69ac33136 100644 (file)
 
 /* 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);
index 9da26476e0faaff67696c03e46b1f8b74e31c6ce..2b2d970acd7f14b9b3d4e8c955fdfb62f2892ccf 100644 (file)
 
 /* 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)
index 3eb2f41a6a15ceabc5c3ab07e70ac9fdfda85f1a..e25453ec9cc15edc834a02cff43b99282b0e223c 100644 (file)
 
 /* 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));
 }
index a5ef2ddee5acec955b1e4c161ef0dd3887dcd0a1..94961cd038a5933406ebb97fe08ea23cf9b04e73 100644 (file)
 #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;
     }
index e3604f7db8ae8cc35730ababb97a995bc06a4f7c..3e545b7addcbf1536b8c7b594936e2f4e92472d7 100644 (file)
 #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;
 }
index ef721641817f9d09a2f0e660b2419477b28ed0b0..70a7c652e992ba1b0e01b474ef68875b4b52940a 100644 (file)
@@ -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);
 }
index 30d38b5fd606987c5331d8a8aa378fb0109796c3..97b601b3bcdaec67bf1058748dc941fdbbaef4c4 100644 (file)
@@ -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);
+        kekcipher_name = SN_id_aes256_wrap;
+enc:
+    fetched_kekcipher = EVP_CIPHER_fetch(cms_ctx->libctx, kekcipher_name,
+                                         cms_ctx->propq);
+    if (fetched_kekcipher == NULL)
+        return 0;
+    ret = EVP_EncryptInit_ex(ctx, fetched_kekcipher, NULL, NULL, NULL);
+    EVP_CIPHER_free(fetched_kekcipher);
+    return ret;
 }
 
 /* Encrypt content key in key agreement recipient info */
@@ -542,5 +565,4 @@ int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
     }
 
     return 1;
-
 }
index 6e2a20c4b3e1f798c0c5d4e3db541a107db928c5..61f965c6dc6f9633e2bc2e79101d9b69c773d957 100644 (file)
 #include <openssl/bio.h>
 #include <openssl/asn1.h>
 #include <openssl/cms.h>
+#include <openssl/cms.h>
+#include "crypto/x509.h"
 #include "cms_local.h"
 
+static STACK_OF(CMS_CertificateChoices)
+**cms_get0_certificate_choices(CMS_ContentInfo *cms);
+
 DEFINE_STACK_OF(CMS_RevocationInfoChoice)
 DEFINE_STACK_OF(X509)
 DEFINE_STACK_OF(X509_CRL)
 
-IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
 IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
 
+CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a,
+                                     const unsigned char **in, long len)
+{
+    CMS_ContentInfo *ci;
+
+    ci = (CMS_ContentInfo *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+                                          (CMS_ContentInfo_it()));
+    if (ci != NULL && a != NULL)
+        cms_resolve_libctx(ci);
+    return ci;
+}
+
+int i2d_CMS_ContentInfo(const CMS_ContentInfo *a, unsigned char **out)
+{
+    return ASN1_item_i2d((const ASN1_VALUE *)a, out, (CMS_ContentInfo_it()));
+}
+
+CMS_ContentInfo *CMS_ContentInfo_new_with_libctx(OPENSSL_CTX *libctx,
+                                                 const char *propq)
+{
+    CMS_ContentInfo *ci;
+
+    ci = (CMS_ContentInfo *)ASN1_item_new(ASN1_ITEM_rptr(CMS_ContentInfo));
+    if (ci != NULL) {
+        ci->ctx.libctx = libctx;
+        ci->ctx.propq = NULL;
+        if (propq != NULL) {
+            ci->ctx.propq = OPENSSL_strdup(propq);
+            if (ci->ctx.propq == NULL) {
+                CMS_ContentInfo_free(ci);
+                ci = NULL;
+                ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+            }
+        }
+    }
+    return ci;
+}
+
+CMS_ContentInfo *CMS_ContentInfo_new(void)
+{
+    return CMS_ContentInfo_new_with_libctx(NULL, NULL);
+}
+
+void CMS_ContentInfo_free(CMS_ContentInfo *cms)
+{
+    if (cms != NULL) {
+        OPENSSL_free(cms->ctx.propq);
+        ASN1_item_free((ASN1_VALUE *)cms, ASN1_ITEM_rptr(CMS_ContentInfo));
+    }
+}
+
+const CMS_CTX *cms_get0_cmsctx(const CMS_ContentInfo *cms)
+{
+    return cms != NULL ? &cms->ctx : NULL;
+}
+
+OPENSSL_CTX *cms_ctx_get0_libctx(const CMS_CTX *ctx)
+{
+    return ctx->libctx;
+}
+
+const char *cms_ctx_get0_propq(const CMS_CTX *ctx)
+{
+    return ctx->propq;
+}
+
+void cms_resolve_libctx(CMS_ContentInfo *ci)
+{
+    int i;
+    CMS_CertificateChoices *cch;
+    STACK_OF(CMS_CertificateChoices) **pcerts;
+    const CMS_CTX *ctx;
+
+    if (ci == NULL)
+        return;
+
+    ctx = cms_get0_cmsctx(ci);
+    cms_SignerInfos_set_cmsctx(ci);
+    cms_RecipientInfos_set_cmsctx(ci);
+
+    pcerts = cms_get0_certificate_choices(ci);
+    if (pcerts != NULL) {
+        for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
+            cch = sk_CMS_CertificateChoices_value(*pcerts, i);
+            if (cch->type == CMS_CERTCHOICE_CERT)
+                x509_set0_libctx(cch->d.certificate, ctx->libctx, ctx->propq);
+        }
+    }
+}
+
 const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms)
 {
     return cms->contentType;
 }
 
-CMS_ContentInfo *cms_Data_create(void)
+CMS_ContentInfo *cms_Data_create(OPENSSL_CTX *libctx, const char *propq)
 {
-    CMS_ContentInfo *cms;
-    cms = CMS_ContentInfo_new();
+    CMS_ContentInfo *cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
+
     if (cms != NULL) {
         cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
         /* Never detached */
@@ -295,14 +389,18 @@ int CMS_set_detached(CMS_ContentInfo *cms, int detached)
 
 /* Create a digest BIO from an X509_ALGOR structure */
 
-BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm,
+                                  const CMS_CTX *ctx)
 {
     BIO *mdbio = NULL;
     const ASN1_OBJECT *digestoid;
-    const EVP_MD *digest;
+    EVP_MD *digest = NULL;
+    const char *alg;
+
     X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
-    digest = EVP_get_digestbyobj(digestoid);
-    if (!digest) {
+    alg = OBJ_nid2sn(OBJ_obj2nid(digestoid));
+    digest = EVP_MD_fetch(ctx->libctx, alg, ctx->propq);
+    if (digest == NULL) {
         CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
                CMS_R_UNKNOWN_DIGEST_ALGORITHM);
         goto err;
@@ -312,8 +410,10 @@ BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
         CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR);
         goto err;
     }
+    EVP_MD_free(digest);
     return mdbio;
  err:
+    EVP_MD_free(digest);
     BIO_free(mdbio);
     return NULL;
 }
index 68c885622b7f1bc27e83adc59534b15ca52a89ce..4e85459a543a06508bc28fd3bd46a5bf109d2bb5 100644 (file)
@@ -43,6 +43,12 @@ typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
 typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
 typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
 typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;
+typedef struct CMS_CTX_st CMS_CTX;
+
+struct CMS_CTX_st {
+    OPENSSL_CTX *libctx;
+    char *propq;
+};
 
 struct CMS_ContentInfo_st {
     ASN1_OBJECT *contentType;
@@ -58,6 +64,7 @@ struct CMS_ContentInfo_st {
         /* Other types ... */
         void *otherData;
     } d;
+    CMS_CTX ctx;
 };
 
 DEFINE_STACK_OF(CMS_CertificateChoices)
@@ -92,6 +99,7 @@ struct CMS_SignerInfo_st {
     /* Digest and public key context for alternative parameters */
     EVP_MD_CTX *mctx;
     EVP_PKEY_CTX *pctx;
+    const CMS_CTX *cms_ctx;
 };
 
 struct CMS_SignerIdentifier_st {
@@ -152,6 +160,7 @@ struct CMS_KeyTransRecipientInfo_st {
     EVP_PKEY *pkey;
     /* Public key context for this operation */
     EVP_PKEY_CTX *pctx;
+    const CMS_CTX *cms_ctx;
 };
 
 struct CMS_KeyAgreeRecipientInfo_st {
@@ -164,6 +173,7 @@ struct CMS_KeyAgreeRecipientInfo_st {
     EVP_PKEY_CTX *pctx;
     /* Cipher context for CEK wrapping */
     EVP_CIPHER_CTX *ctx;
+    const CMS_CTX *cms_ctx;
 };
 
 struct CMS_OriginatorIdentifierOrKey_st {
@@ -209,6 +219,7 @@ struct CMS_KEKRecipientInfo_st {
     /* Extra info: symmetric key to use */
     unsigned char *key;
     size_t keylen;
+    const CMS_CTX *cms_ctx;
 };
 
 struct CMS_KEKIdentifier_st {
@@ -225,6 +236,7 @@ struct CMS_PasswordRecipientInfo_st {
     /* Extra info: password to use */
     unsigned char *pass;
     size_t passlen;
+    const CMS_CTX *cms_ctx;
 };
 
 struct CMS_OtherRecipientInfo_st {
@@ -363,27 +375,34 @@ DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
 # define CMS_OIK_PUBKEY                  2
 
 BIO *cms_content_bio(CMS_ContentInfo *cms);
+const CMS_CTX *cms_get0_cmsctx(const CMS_ContentInfo *cms);
+OPENSSL_CTX *cms_ctx_get0_libctx(const CMS_CTX *ctx);
+const char *cms_ctx_get0_propq(const CMS_CTX *ctx);
+void cms_resolve_libctx(CMS_ContentInfo *ci);
 
-CMS_ContentInfo *cms_Data_create(void);
+CMS_ContentInfo *cms_Data_create(OPENSSL_CTX *ctx, const char *propq);
 
-CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md,
+                                         OPENSSL_CTX *libctx, const char *propq);
 BIO *cms_DigestedData_init_bio(const CMS_ContentInfo *cms);
 int cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, int verify);
 
 BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
 int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
 int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert,
-                              int type);
+                              int type, const CMS_CTX *ctx);
 int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
                                         ASN1_OCTET_STRING **keyid,
                                         X509_NAME **issuer,
                                         ASN1_INTEGER **sno);
 int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
 
-CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
+CMS_ContentInfo *cms_CompressedData_create(int comp_nid, OPENSSL_CTX *libctx,
+                                           const char *propq);
 BIO *cms_CompressedData_init_bio(const CMS_ContentInfo *cms);
 
-BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm,
+                                  const CMS_CTX *ctx);
 int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
                                  X509_ALGOR *mdalg);
 
@@ -392,11 +411,13 @@ int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert);
 int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert);
 int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert);
 
-BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec,
+                                   const CMS_CTX *ctx);
 BIO *cms_EncryptedData_init_bio(const CMS_ContentInfo *cms);
 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 *ctx);
 
 int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
 int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
@@ -405,21 +426,29 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
 BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
 int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain);
 CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
+
+/* RecipientInfo routines */
 int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd);
 int cms_pkey_get_ri_type(EVP_PKEY *pk);
 int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type);
+
+void cms_RecipientInfos_set_cmsctx(CMS_ContentInfo *cms);
+
 /* KARI routines */
 int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
                                 EVP_PKEY *recipPubKey, X509 *originator,
-                                EVP_PKEY *originatorPrivKey, unsigned int flags);
+                                EVP_PKEY *originatorPrivKey, unsigned int flags,
+                                const CMS_CTX *ctx);
 int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
                                    CMS_RecipientInfo *ri);
 
 /* PWRI routines */
-int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
-                                 int en_de);
+int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
+                                 CMS_RecipientInfo *ri, int en_de);
 /* SignerInfo routines */
 int CMS_si_check_attributes(const CMS_SignerInfo *si);
+void cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms);
+
 
 /* ESS routines */
 int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain);
index 4726165234371b0586410c174542259692b261f3..1ca5a7ee07c1b4da4455a26de6f7589dab34c4b8 100644 (file)
@@ -51,6 +51,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
     X509_ALGOR *encalg = NULL;
     unsigned char iv[EVP_MAX_IV_LENGTH];
     int ivlen;
+    const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms);
 
     env = cms_get0_enveloped(cms);
     if (!env)
@@ -91,7 +92,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
     ivlen = EVP_CIPHER_CTX_iv_length(ctx);
 
     if (ivlen > 0) {
-        if (RAND_bytes(iv, ivlen) <= 0)
+        if (RAND_bytes_ex(cms_ctx->libctx, iv, ivlen) <= 0)
             goto err;
         if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) {
             CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
@@ -125,6 +126,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
     ri->type = CMS_RECIPINFO_PASS;
 
     pwri = ri->d.pwri;
+    pwri->cms_ctx = cms_ctx;
     /* Since this is overwritten, free up empty structure already there */
     X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
     pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
@@ -232,7 +234,7 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen,
 
 static int kek_wrap_key(unsigned char *out, size_t *outlen,
                         const unsigned char *in, size_t inlen,
-                        EVP_CIPHER_CTX *ctx)
+                        EVP_CIPHER_CTX *ctx, const CMS_CTX *cms_ctx)
 {
     size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
     size_t olen;
@@ -260,7 +262,8 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen,
         memcpy(out + 4, in, inlen);
         /* Add random padding to end */
         if (olen > inlen + 4
-            && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0)
+            && RAND_bytes_ex(cms_ctx->libctx, out + 4 + inlen,
+                             olen - 4 - inlen) <= 0)
             return 0;
         /* Encrypt twice */
         if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen)
@@ -275,17 +278,19 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen,
 
 /* Encrypt/Decrypt content key in PWRI recipient info */
 
-int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
-                                 int en_de)
+int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
+                                 CMS_RecipientInfo *ri, int en_de)
 {
     CMS_EncryptedContentInfo *ec;
     CMS_PasswordRecipientInfo *pwri;
     int r = 0;
     X509_ALGOR *algtmp, *kekalg = NULL;
     EVP_CIPHER_CTX *kekctx = NULL;
-    const EVP_CIPHER *kekcipher;
+    const char *name;
+    EVP_CIPHER *kekcipher;
     unsigned char *key = NULL;
     size_t keylen;
+    const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms);
 
     ec = cms->d.envelopedData->encryptedContentInfo;
 
@@ -312,17 +317,18 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *
         return 0;
     }
 
-    kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
+    name = OBJ_nid2sn(OBJ_obj2nid(kekalg->algorithm));
+    kekcipher = EVP_CIPHER_fetch(cms_ctx->libctx, name, cms_ctx->propq);
 
-    if (!kekcipher) {
+    if (kekcipher == NULL) {
         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER);
-        return 0;
+        goto err;
     }
 
     kekctx = EVP_CIPHER_CTX_new();
     if (kekctx == NULL) {
         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
-        return 0;
+        goto err;
     }
     /* Fixup cipher based on AlgorithmIdentifier to set IV etc */
     if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de))
@@ -349,7 +355,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *
 
     if (en_de) {
 
-        if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx))
+        if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx, cms_ctx))
             goto err;
 
         key = OPENSSL_malloc(keylen);
@@ -357,7 +363,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *
         if (key == NULL)
             goto err;
 
-        if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx))
+        if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx, cms_ctx))
             goto err;
         pwri->encryptedKey->data = key;
         pwri->encryptedKey->length = keylen;
@@ -384,7 +390,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *
     r = 1;
 
  err:
-
+    EVP_CIPHER_free(kekcipher);
     EVP_CIPHER_CTX_free(kekctx);
 
     if (!r)
index 54a836028fa759e9c2ff5e9a0df136ebc28142de..9b345de553d76ab77f4b341acbb153eb4fa91c52 100644 (file)
@@ -67,6 +67,7 @@ int CMS_SignedData_init(CMS_ContentInfo *cms)
         return 0;
 }
 
+
 /* Check structures and fixup version numbers (if necessary) */
 
 static void cms_sd_set_version(CMS_SignedData *sd)
@@ -146,9 +147,11 @@ static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
     STACK_OF(CMS_SignerInfo) *sinfos;
     CMS_SignerInfo *sitmp;
     int i;
+
     sinfos = CMS_get0_SignerInfos(cms);
     for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
         ASN1_OCTET_STRING *messageDigest;
+
         sitmp = sk_CMS_SignerInfo_value(sinfos, i);
         if (sitmp == si)
             continue;
@@ -178,7 +181,8 @@ static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
     return 0;
 }
 
-int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
+int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type,
+                              const CMS_CTX *ctx)
 {
     switch (type) {
     case CMS_SIGNERINFO_ISSUER_SERIAL:
@@ -233,6 +237,7 @@ static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
 {
     EVP_PKEY *pkey = si->pkey;
     int i;
+
     if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
         return 1;
     i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
@@ -255,6 +260,8 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
     CMS_SignerInfo *si = NULL;
     X509_ALGOR *alg;
     int i, type;
+    const CMS_CTX *ctx = cms_get0_cmsctx(cms);
+
     if (!X509_check_private_key(signer, pk)) {
         CMSerr(CMS_F_CMS_ADD1_SIGNER,
                CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
@@ -272,6 +279,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
     X509_up_ref(signer);
     EVP_PKEY_up_ref(pk);
 
+    si->cms_ctx = ctx;
     si->pkey = pk;
     si->signer = signer;
     si->mctx = EVP_MD_CTX_new();
@@ -292,7 +300,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
         si->version = 1;
     }
 
-    if (!cms_set1_SignerIdentifier(si->sid, signer, type))
+    if (!cms_set1_SignerIdentifier(si->sid, signer, type, ctx))
         goto err;
 
     if (md == NULL) {
@@ -311,6 +319,11 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
         goto err;
     }
 
+    if (md == NULL) {
+        CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
+        goto err;
+    }
+
     X509_ALGOR_set_md(si->digestAlgorithm, md);
 
     /* See if digest is present in digestAlgorithms */
@@ -395,15 +408,20 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
 
     if (flags & CMS_KEY_PARAM) {
         if (flags & CMS_NOATTR) {
-            si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL);
+            si->pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, si->pkey,
+                                                  ctx->propq);
             if (si->pctx == NULL)
                 goto err;
             if (EVP_PKEY_sign_init(si->pctx) <= 0)
                 goto err;
             if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
                 goto err;
-        } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <= 0)
+        } else if (EVP_DigestSignInit_with_libctx(si->mctx, &si->pctx,
+                                                  EVP_MD_name(md),
+                                                  ctx->libctx, ctx->propq,
+                                                  pk) <= 0) {
             goto err;
+        }
     }
 
     if (!sd->signerInfos)
@@ -421,16 +439,31 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
 
 }
 
+void cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms)
+{
+    int i;
+    CMS_SignerInfo *si;
+    STACK_OF(CMS_SignerInfo) *sinfos = CMS_get0_SignerInfos(cms);
+    const CMS_CTX *ctx = cms_get0_cmsctx(cms);
+
+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+        si = sk_CMS_SignerInfo_value(sinfos, i);
+        if (si != NULL)
+            si->cms_ctx = ctx;
+    }
+}
+
 static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
 {
     ASN1_TIME *tt;
     int r = 0;
-    if (t)
+
+    if (t != NULL)
         tt = t;
     else
         tt = X509_gmtime_adj(NULL, 0);
 
-    if (!tt)
+    if (tt == NULL)
         goto merr;
 
     if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
@@ -438,10 +471,8 @@ static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
         goto merr;
 
     r = 1;
-
  merr:
-
-    if (!t)
+    if (t == NULL)
         ASN1_TIME_free(tt);
 
     if (!r)
@@ -463,11 +494,9 @@ EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
 
 STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
 {
-    CMS_SignedData *sd;
-    sd = cms_get0_signed(cms);
-    if (!sd)
-        return NULL;
-    return sd->signerInfos;
+    CMS_SignedData *sd = cms_get0_signed(cms);
+
+    return sd != NULL ? sd->signerInfos : NULL;
 }
 
 STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
@@ -476,13 +505,14 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
     STACK_OF(CMS_SignerInfo) *sinfos;
     CMS_SignerInfo *si;
     int i;
+
     sinfos = CMS_get0_SignerInfos(cms);
     for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
         si = sk_CMS_SignerInfo_value(sinfos, i);
-        if (si->signer) {
-            if (!signers) {
+        if (si->signer != NULL) {
+            if (signers == NULL) {
                 signers = sk_X509_new_null();
-                if (!signers)
+                if (signers == NULL)
                     return NULL;
             }
             if (!sk_X509_push(signers, si->signer)) {
@@ -496,7 +526,7 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
 
 void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
 {
-    if (signer) {
+    if (signer != NULL) {
         X509_up_ref(signer);
         EVP_PKEY_free(si->pkey);
         si->pkey = X509_get_pubkey(signer);
@@ -527,13 +557,14 @@ int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
     X509 *x;
     int i, j;
     int ret = 0;
+
     sd = cms_get0_signed(cms);
-    if (!sd)
+    if (sd == NULL)
         return -1;
     certs = sd->certificates;
     for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
         si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
-        if (si->signer)
+        if (si->signer != NULL)
             continue;
 
         for (j = 0; j < sk_X509_num(scerts); j++) {
@@ -545,7 +576,7 @@ int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
             }
         }
 
-        if (si->signer || (flags & CMS_NOINTERN))
+        if (si->signer != NULL || (flags & CMS_NOINTERN))
             continue;
 
         for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) {
@@ -567,13 +598,13 @@ void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
                               X509 **signer, X509_ALGOR **pdig,
                               X509_ALGOR **psig)
 {
-    if (pk)
+    if (pk != NULL)
         *pk = si->pkey;
-    if (signer)
+    if (signer != NULL)
         *signer = si->signer;
-    if (pdig)
+    if (pdig != NULL)
         *pdig = si->digestAlgorithm;
-    if (psig)
+    if (psig != NULL)
         *psig = si->signatureAlgorithm;
 }
 
@@ -588,13 +619,14 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
     int r = 0;
     EVP_PKEY_CTX *pctx = NULL;
+    const CMS_CTX *ctx = cms_get0_cmsctx(cms);
 
     if (mctx == NULL) {
         CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
         return 0;
     }
 
-    if (!si->pkey) {
+    if (si->pkey == NULL) {
         CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
         goto err;
     }
@@ -612,6 +644,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
     if (CMS_signed_get_attr_count(si) >= 0) {
         unsigned char md[EVP_MAX_MD_SIZE];
         unsigned int mdlen;
+
         if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
             goto err;
         if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
@@ -628,6 +661,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
         size_t siglen;
         unsigned char md[EVP_MAX_MD_SIZE];
         unsigned int mdlen;
+
         pctx = si->pctx;
         if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
             goto err;
@@ -645,12 +679,14 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
     } else {
         unsigned char *sig;
         unsigned int siglen;
+
         sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
         if (sig == NULL) {
             CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
             goto err;
         }
-        if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) {
+        if (!EVP_SignFinal_with_libctx(mctx, sig, &siglen, si->pkey,
+                                       ctx->libctx, ctx->propq)) {
             CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR);
             OPENSSL_free(sig);
             goto err;
@@ -672,6 +708,7 @@ int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
     STACK_OF(CMS_SignerInfo) *sinfos;
     CMS_SignerInfo *si;
     int i;
+
     sinfos = CMS_get0_SignerInfos(cms);
     for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
         si = sk_CMS_SignerInfo_value(sinfos, i);
@@ -689,10 +726,10 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
     unsigned char *abuf = NULL;
     int alen;
     size_t siglen;
-    const EVP_MD *md = NULL;
+    const CMS_CTX *ctx = si->cms_ctx;
+    const char *md_name = OBJ_nid2sn(OBJ_obj2nid(si->digestAlgorithm->algorithm));
 
-    md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
-    if (md == NULL)
+    if (md_name == NULL)
         return 0;
 
     if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
@@ -707,7 +744,9 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
         pctx = si->pctx;
     else {
         EVP_MD_CTX_reset(mctx);
-        if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
+        if (EVP_DigestSignInit_with_libctx(mctx, &pctx,
+                                           md_name, ctx->libctx, ctx->propq,
+                                           si->pkey) <= 0)
             goto err;
         si->pctx = pctx;
     }
@@ -780,9 +819,11 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
     EVP_MD_CTX *mctx = NULL;
     unsigned char *abuf = NULL;
     int alen, r = -1;
-    const EVP_MD *md = NULL;
+    const char *name;
+    EVP_MD *md = NULL;
+    const CMS_CTX *ctx = si->cms_ctx;
 
-    if (!si->pkey) {
+    if (si->pkey == NULL) {
         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
         return -1;
     }
@@ -790,15 +831,18 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
     if (!CMS_si_check_attributes(si))
         return -1;
 
-    md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+    name = OBJ_nid2sn(OBJ_obj2nid(si->digestAlgorithm->algorithm));
+    md = EVP_MD_fetch(ctx->libctx, name, ctx->propq);
     if (md == NULL)
         return -1;
     if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) {
         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, ERR_R_MALLOC_FAILURE);
-        return -1;
+        goto err;
     }
     mctx = si->mctx;
-    if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
+    if (EVP_DigestVerifyInit_with_libctx(mctx, &si->pctx,
+                                         EVP_MD_name(md), ctx->libctx, NULL,
+                                         si->pkey) <= 0)
         goto err;
 
     if (!cms_sd_asn1_ctrl(si, 1))
@@ -819,6 +863,7 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
     if (r <= 0)
         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
  err:
+    EVP_MD_free(md);
     EVP_MD_CTX_reset(mctx);
     return r;
 }
@@ -830,19 +875,21 @@ BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
     int i;
     CMS_SignedData *sd;
     BIO *chain = NULL;
+
     sd = cms_get0_signed(cms);
-    if (!sd)
+    if (sd == NULL)
         return NULL;
     if (cms->d.signedData->encapContentInfo->partial)
         cms_sd_set_version(sd);
     for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
         X509_ALGOR *digestAlgorithm;
         BIO *mdbio;
+
         digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
-        mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
-        if (!mdbio)
+        mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm, cms_get0_cmsctx(cms));
+        if (mdbio == NULL)
             goto err;
-        if (chain)
+        if (chain != NULL)
             BIO_push(chain, mdbio);
         else
             chain = mdbio;
@@ -871,7 +918,7 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
         os = CMS_signed_get0_data_by_OBJ(si,
                                          OBJ_nid2obj(NID_pkcs9_messageDigest),
                                          -3, V_ASN1_OCTET_STRING);
-        if (!os) {
+        if (os == NULL) {
             CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
                    CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
             goto err;
@@ -889,7 +936,7 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
 
     /* If messageDigest found compare it */
 
-    if (os) {
+    if (os != NULL) {
         if (mlen != (unsigned int)os->length) {
             CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
                    CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
@@ -904,7 +951,9 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
             r = 1;
     } else {
         const EVP_MD *md = EVP_MD_CTX_md(mctx);
-        pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
+        const CMS_CTX *ctx = si->cms_ctx;
+
+        pkctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, si->pkey, ctx->propq);
         if (pkctx == NULL)
             goto err;
         if (EVP_PKEY_verify_init(pkctx) <= 0)
@@ -934,6 +983,7 @@ int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
 {
     unsigned char *smder = NULL;
     int smderlen, r;
+
     smderlen = i2d_X509_ALGORS(algs, &smder);
     if (smderlen <= 0)
         return 0;
@@ -948,6 +998,7 @@ int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
 {
     X509_ALGOR *alg;
     ASN1_INTEGER *key = NULL;
+
     if (keysize > 0) {
         key = ASN1_INTEGER_new();
         if (key == NULL || !ASN1_INTEGER_set(key, keysize)) {
index a83edce0f7e5e960db09f6c6781e60fd1373bfa8..11c9fed1a8c5a10e68f2892ee88e6d6e5036a1b5 100644 (file)
@@ -25,6 +25,7 @@ DEFINE_STACK_OF(CMS_RecipientInfo)
 static BIO *cms_get_text_bio(BIO *out, unsigned int flags)
 {
     BIO *rbio;
+
     if (out == NULL)
         rbio = BIO_new(BIO_s_null());
     else if (flags & CMS_TEXT) {
@@ -61,7 +62,7 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
             break;
         }
 
-        if (tmpout && (BIO_write(tmpout, buf, i) != i))
+        if (tmpout != NULL && (BIO_write(tmpout, buf, i) != i))
             goto err;
     }
 
@@ -73,7 +74,6 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
     }
 
     r = 1;
-
  err:
     if (tmpout != out)
         BIO_free(tmpout);
@@ -96,62 +96,73 @@ static void do_free_upto(BIO *f, BIO *upto)
 {
     if (upto != NULL) {
         BIO *tbio;
+
         do {
             tbio = BIO_pop(f);
             BIO_free(f);
             f = tbio;
         } while (f != NULL && f != upto);
-    } else
+    } else {
         BIO_free_all(f);
+    }
 }
 
 int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
 {
     BIO *cont;
     int r;
+
     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) {
         CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
         return 0;
     }
     cont = CMS_dataInit(cms, NULL);
-    if (!cont)
+    if (cont == NULL)
         return 0;
     r = cms_copy_content(out, cont, flags);
     BIO_free_all(cont);
     return r;
 }
 
-CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
+CMS_ContentInfo *CMS_data_create_with_libctx(BIO *in, unsigned int flags,
+                                             OPENSSL_CTX *libctx,
+                                             const char *propq)
 {
-    CMS_ContentInfo *cms;
-    cms = cms_Data_create();
-    if (!cms)
+    CMS_ContentInfo *cms = cms_Data_create(libctx, propq);
+
+    if (cms == NULL)
         return NULL;
 
     if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
         return cms;
 
     CMS_ContentInfo_free(cms);
-
     return NULL;
 }
 
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
+{
+    return CMS_data_create_with_libctx(in, flags, NULL, NULL);
+}
+
 int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
                       unsigned int flags)
 {
     BIO *cont;
     int r;
+
     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) {
         CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
         return 0;
     }
 
-    if (!dcont && !check_content(cms))
+    if (dcont == NULL && !check_content(cms))
         return 0;
 
     cont = CMS_dataInit(cms, dcont);
-    if (!cont)
+    if (cont == NULL)
         return 0;
+
     r = cms_copy_content(out, cont, flags);
     if (r)
         r = cms_DigestedData_do_final(cms, cont, 1);
@@ -159,14 +170,18 @@ int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
     return r;
 }
 
-CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
-                                   unsigned int flags)
+CMS_ContentInfo *CMS_digest_create_with_libctx(BIO *in,
+                                               const EVP_MD *md,
+                                               unsigned int flags,
+                                               OPENSSL_CTX *ctx,
+                                               const char *propq)
 {
     CMS_ContentInfo *cms;
-    if (!md)
+
+    if (md == NULL)
         md = EVP_sha1();
-    cms = cms_DigestedData_create(md);
-    if (!cms)
+    cms = cms_DigestedData_create(md, ctx, propq);
+    if (cms == NULL)
         return NULL;
 
     if (!(flags & CMS_DETACHED))
@@ -179,41 +194,53 @@ CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
     return NULL;
 }
 
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+                                   unsigned int flags)
+{
+    return CMS_digest_create_with_libctx(in, md, flags, NULL, NULL);
+}
+
 int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
                               const unsigned char *key, size_t keylen,
                               BIO *dcont, BIO *out, unsigned int flags)
 {
     BIO *cont;
     int r;
+
     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) {
         CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
                CMS_R_TYPE_NOT_ENCRYPTED_DATA);
         return 0;
     }
 
-    if (!dcont && !check_content(cms))
+    if (dcont == NULL && !check_content(cms))
         return 0;
 
     if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
         return 0;
     cont = CMS_dataInit(cms, dcont);
-    if (!cont)
+    if (cont == NULL)
         return 0;
     r = cms_copy_content(out, cont, flags);
     do_free_upto(cont, dcont);
     return r;
 }
 
-CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
-                                           const unsigned char *key,
-                                           size_t keylen, unsigned int flags)
+CMS_ContentInfo *CMS_EncryptedData_encrypt_with_libctx(BIO *in,
+                                                       const EVP_CIPHER *cipher,
+                                                       const unsigned char *key,
+                                                       size_t keylen,
+                                                       unsigned int flags,
+                                                       OPENSSL_CTX *libctx,
+                                                       const char *propq)
 {
     CMS_ContentInfo *cms;
-    if (!cipher) {
-        CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
+
+    if (cipher == NULL) {
+        CMSerr(0, CMS_R_NO_CIPHER);
         return NULL;
     }
-    cms = CMS_ContentInfo_new();
+    cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
     if (cms == NULL)
         return NULL;
     if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
@@ -230,16 +257,26 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
     return NULL;
 }
 
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+                                           const unsigned char *key,
+                                           size_t keylen, unsigned int flags)
+{
+    return CMS_EncryptedData_encrypt_with_libctx(in, cipher, key, keylen, flags,
+                                                 NULL, NULL);
+}
+
 static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
                                       X509_STORE *store,
                                       STACK_OF(X509) *certs,
                                       STACK_OF(X509_CRL) *crls,
-                                      STACK_OF(X509) **chain)
+                                      STACK_OF(X509) **chain,
+                                      const CMS_CTX *cms_ctx)
 {
-    X509_STORE_CTX *ctx = X509_STORE_CTX_new();
+    X509_STORE_CTX *ctx;
     X509 *signer;
     int i, j, r = 0;
 
+    ctx = X509_STORE_CTX_new_with_libctx(cms_ctx->libctx, cms_ctx->propq);
     if (ctx == NULL) {
         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
         goto err;
@@ -250,7 +287,7 @@ static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
         goto err;
     }
     X509_STORE_CTX_set_default(ctx, "smime_sign");
-    if (crls)
+    if (crls != NULL)
         X509_STORE_CTX_set0_crls(ctx, crls);
 
     i = X509_verify_cert(ctx);
@@ -285,11 +322,13 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
     int i, scount = 0, ret = 0;
     BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL;
     int cadesVerify = (flags & CMS_CADES) != 0;
+    const CMS_CTX *ctx = cms_get0_cmsctx(cms);
 
-    if (!dcont && !check_content(cms))
+    if (dcont == NULL && !check_content(cms))
         return 0;
-    if (dcont && !(flags & CMS_BINARY)) {
+    if (dcont != NULL && !(flags & CMS_BINARY)) {
         const ASN1_OBJECT *coid = CMS_get0_eContentType(cms);
+
         if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF)
             flags |= CMS_ASCIICRLF;
     }
@@ -337,7 +376,8 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
             si = sk_CMS_SignerInfo_value(sinfos, i);
 
             if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls,
-                                            si_chains ? &si_chains[i] : NULL))
+                                            si_chains ? &si_chains[i] : NULL,
+                                            ctx))
                 goto err;
         }
     }
@@ -367,17 +407,19 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
      * reading from a read write memory BIO when signatures are calculated.
      */
 
-    if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) {
+    if (dcont != NULL && (BIO_method_type(dcont) == BIO_TYPE_MEM)) {
         char *ptr;
         long len;
+
         len = BIO_get_mem_data(dcont, &ptr);
         tmpin = BIO_new_mem_buf(ptr, len);
         if (tmpin == NULL) {
             CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
             goto err2;
         }
-    } else
+    } else {
         tmpin = dcont;
+    }
     /*
      * If not binary mode and detached generate digests by *writing* through
      * the BIO. That makes it possible to canonicalise the input.
@@ -388,12 +430,12 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
          * included content doesn't override detached content.
          */
         tmpout = cms_get_text_bio(out, flags);
-        if (!tmpout) {
+        if (tmpout == NULL) {
             CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
             goto err;
         }
         cmsbio = CMS_dataInit(cms, tmpout);
-        if (!cmsbio)
+        if (cmsbio == NULL)
             goto err;
         /*
          * Don't use SMIME_TEXT for verify: it adds headers and we want to
@@ -409,7 +451,7 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
         }
     } else {
         cmsbio = CMS_dataInit(cms, tmpin);
-        if (!cmsbio)
+        if (cmsbio == NULL)
             goto err;
 
         if (!cms_copy_content(out, cmsbio, flags))
@@ -427,7 +469,6 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
     }
 
     ret = 1;
-
  err:
     if (!(flags & SMIME_BINARY) && dcont) {
         do_free_upto(cmsbio, tmpout);
@@ -460,6 +501,7 @@ int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
                        X509_STORE *store, unsigned int flags)
 {
     int r;
+
     flags &= ~(CMS_DETACHED | CMS_TEXT);
     r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
     if (r <= 0)
@@ -467,14 +509,15 @@ int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
     return cms_Receipt_verify(rcms, ocms);
 }
 
-CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
-                          STACK_OF(X509) *certs, BIO *data,
-                          unsigned int flags)
+CMS_ContentInfo *CMS_sign_with_libctx(X509 *signcert, EVP_PKEY *pkey,
+                                      STACK_OF(X509) *certs, BIO *data,
+                                      unsigned int flags,
+                                      OPENSSL_CTX *libctx, const char *propq)
 {
     CMS_ContentInfo *cms;
     int i;
 
-    cms = CMS_ContentInfo_new();
+    cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
     if (cms == NULL || !CMS_SignedData_init(cms))
         goto merr;
     if (flags & CMS_ASCIICRLF
@@ -482,13 +525,14 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
                                   OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF)))
         goto err;
 
-    if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) {
-        CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
+    if (pkey != NULL && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) {
+        CMSerr(0, CMS_R_ADD_SIGNER_ERROR);
         goto err;
     }
 
     for (i = 0; i < sk_X509_num(certs); i++) {
         X509 *x = sk_X509_value(certs, i);
+
         if (!CMS_add1_cert(cms, x))
             goto merr;
     }
@@ -503,13 +547,19 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
         goto err;
 
  merr:
-    CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
+    CMSerr(0, ERR_R_MALLOC_FAILURE);
 
  err:
     CMS_ContentInfo_free(cms);
     return NULL;
 }
 
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+                          BIO *data, unsigned int flags)
+{
+    return CMS_sign_with_libctx(signcert, pkey, certs, data, flags, NULL, NULL);
+}
+
 CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
                                   X509 *signcert, EVP_PKEY *pkey,
                                   STACK_OF(X509) *certs, unsigned int flags)
@@ -519,6 +569,7 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
     ASN1_OCTET_STRING **pos, *os;
     BIO *rct_cont = NULL;
     int r = 0;
+    const CMS_CTX *ctx = si->cms_ctx;
 
     flags &= ~(CMS_STREAM | CMS_TEXT);
     /* Not really detached but avoids content being allocated */
@@ -530,8 +581,9 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
 
     /* Initialize signed data */
 
-    cms = CMS_sign(NULL, NULL, certs, NULL, flags);
-    if (!cms)
+    cms = CMS_sign_with_libctx(NULL, NULL, certs, NULL, flags,
+                               ctx->libctx, ctx->propq);
+    if (cms == NULL)
         goto err;
 
     /* Set inner content type to signed receipt */
@@ -545,13 +597,12 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
     }
 
     os = cms_encode_Receipt(si);
-
-    if (!os)
+    if (os == NULL)
         goto err;
 
     /* Set content to digest */
     rct_cont = BIO_new_mem_buf(os->data, os->length);
-    if (!rct_cont)
+    if (rct_cont == NULL)
         goto err;
 
     /* Add msgSigDigest attribute */
@@ -578,19 +629,22 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
 
 }
 
-CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
-                             const EVP_CIPHER *cipher, unsigned int flags)
+CMS_ContentInfo *CMS_encrypt_with_libctx(STACK_OF(X509) *certs,
+                                         BIO *data, const EVP_CIPHER *cipher,
+                                         unsigned int flags,
+                                         OPENSSL_CTX *libctx, const char *propq)
 {
     CMS_ContentInfo *cms;
     int i;
     X509 *recip;
-    cms = CMS_EnvelopedData_create(cipher);
-    if (!cms)
+
+    cms = CMS_EnvelopedData_create_with_libctx(cipher, libctx, propq);
+    if (cms == NULL)
         goto merr;
     for (i = 0; i < sk_X509_num(certs); i++) {
         recip = sk_X509_value(certs, i);
         if (!CMS_add1_recipient_cert(cms, recip, flags)) {
-            CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
+            CMSerr(0, CMS_R_RECIPIENT_ERROR);
             goto err;
         }
     }
@@ -605,13 +659,20 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
         goto err;
 
  merr:
-    CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
+    CMSerr(0, ERR_R_MALLOC_FAILURE);
  err:
     CMS_ContentInfo_free(cms);
     return NULL;
 }
 
-static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
+                             const EVP_CIPHER *cipher, unsigned int flags)
+{
+    return CMS_encrypt_with_libctx(certs, data, cipher, flags, NULL, NULL);
+}
+
+static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms,
+                                       CMS_RecipientInfo *ri,
                                        EVP_PKEY *pk, X509 *cert, X509 *peer)
 {
     int i;
@@ -621,6 +682,7 @@ static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms, CMS_RecipientInfo *
     reks = CMS_RecipientInfo_kari_get0_reks(ri);
     for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
         int rv;
+
         rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
         if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert))
             continue;
@@ -639,14 +701,16 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
      return CMS_decrypt_set1_pkey_and_peer(cms, pk, cert, NULL);
 }
 
-int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, X509 *peer)
+int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk,
+                                   X509 *cert, X509 *peer)
 {
     STACK_OF(CMS_RecipientInfo) *ris;
     CMS_RecipientInfo *ri;
     int i, r, cms_pkey_ri_type;
     int debug = 0, match_ri = 0;
+
     ris = CMS_get0_RecipientInfos(cms);
-    if (ris)
+    if (ris != NULL)
         debug = cms->d.envelopedData->encryptedContentInfo->debug;
 
     cms_pkey_ri_type = cms_pkey_get_ri_type(pk);
@@ -675,12 +739,12 @@ int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cer
          * If we have a cert try matching RecipientInfo otherwise try them
          * all.
          */
-        else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
+        else if (cert == NULL|| !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
             EVP_PKEY_up_ref(pk);
             CMS_RecipientInfo_set0_pkey(ri, pk);
             r = CMS_RecipientInfo_decrypt(cms, ri);
             CMS_RecipientInfo_set0_pkey(ri, NULL);
-            if (cert) {
+            if (cert != NULL) {
                 /*
                  * If not debugging clear any error and return success to
                  * avoid leaking of information useful to MMA
@@ -704,7 +768,10 @@ int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cer
         }
     }
     /* If no cert, key transport and not debugging always return success */
-    if (cert == NULL && cms_pkey_ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) {
+    if (cert == NULL
+        && cms_pkey_ri_type == CMS_RECIPINFO_TRANS
+        && match_ri
+        && !debug) {
         ERR_clear_error();
         return 1;
     }
@@ -721,6 +788,7 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
     STACK_OF(CMS_RecipientInfo) *ris;
     CMS_RecipientInfo *ri;
     int i, r;
+
     ris = CMS_get0_RecipientInfos(cms);
     for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
         ri = sk_CMS_RecipientInfo_value(ris, i);
@@ -731,13 +799,13 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
          * If we have an id try matching RecipientInfo otherwise try them
          * all.
          */
-        if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) {
+        if (id == NULL || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) {
             CMS_RecipientInfo_set0_key(ri, key, keylen);
             r = CMS_RecipientInfo_decrypt(cms, ri);
             CMS_RecipientInfo_set0_key(ri, NULL, 0);
             if (r > 0)
                 return 1;
-            if (id) {
+            if (id != NULL) {
                 CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR);
                 return 0;
             }
@@ -756,6 +824,7 @@ int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
     STACK_OF(CMS_RecipientInfo) *ris;
     CMS_RecipientInfo *ri;
     int i, r;
+
     ris = CMS_get0_RecipientInfos(cms);
     for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
         ri = sk_CMS_RecipientInfo_value(ris, i);
@@ -783,13 +852,13 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
         CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
         return 0;
     }
-    if (!dcont && !check_content(cms))
+    if (dcont == NULL && !check_content(cms))
         return 0;
     if (flags & CMS_DEBUG_DECRYPT)
         cms->d.envelopedData->encryptedContentInfo->debug = 1;
     else
         cms->d.envelopedData->encryptedContentInfo->debug = 0;
-    if (!cert)
+    if (cert == NULL)
         cms->d.envelopedData->encryptedContentInfo->havenocert = 1;
     else
         cms->d.envelopedData->encryptedContentInfo->havenocert = 0;
@@ -815,7 +884,7 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
         return 0;
     }
 
-    SMIME_crlf_copy(data, cmsbio, flags);
+    ret = SMIME_crlf_copy(data, cmsbio, flags);
 
     (void)BIO_flush(cmsbio);
 
@@ -823,10 +892,7 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
         CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR);
         goto err;
     }
-
-    ret = 1;
-
- err:
+err:
     do_free_upto(cmsbio, dcont);
 
     return ret;
@@ -840,16 +906,17 @@ int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
 {
     BIO *cont;
     int r;
+
     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) {
         CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA);
         return 0;
     }
 
-    if (!dcont && !check_content(cms))
+    if (dcont == NULL && !check_content(cms))
         return 0;
 
     cont = CMS_dataInit(cms, dcont);
-    if (!cont)
+    if (cont == NULL)
         return 0;
     r = cms_copy_content(out, cont, flags);
     do_free_upto(cont, dcont);
@@ -859,10 +926,11 @@ int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
 CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
 {
     CMS_ContentInfo *cms;
+
     if (comp_nid <= 0)
         comp_nid = NID_zlib_compression;
-    cms = cms_CompressedData_create(comp_nid);
-    if (!cms)
+    cms = cms_CompressedData_create(comp_nid, NULL, NULL);
+    if (cms == NULL)
         return NULL;
 
     if (!(flags & CMS_DETACHED))
index 6ee411d550a439050050be73dd560be508436cd0..a72b4c9fa09496ce3c2b7d9bb8de14ca48955bf9 100644 (file)
@@ -83,6 +83,7 @@ B<openssl> B<cms>
 {- $OpenSSL::safe::opt_r_synopsis -}
 {- $OpenSSL::safe::opt_engine_synopsis -}
 {- $OpenSSL::safe::opt_provider_synopsis -}
+{- $OpenSSL::safe::opt_config_synopsis -}
 [I<recipient-cert> ...]
 
 =for openssl ifdef des-wrap engine
@@ -501,6 +502,8 @@ Any verification errors cause the command to exit.
 
 {- $OpenSSL::safe::opt_provider_item -}
 
+{- $OpenSSL::safe::opt_config_item -}
+
 =item I<recipient-cert> ...
 
 One or more certificates of message recipients: used when encrypting
index 625daa8029da7dff101fe747d4927bb3d3989167..e6903ea3f8da4b586e066db60286a263d19c0322 100644 (file)
@@ -2,20 +2,26 @@
 
 =head1 NAME
 
-CMS_EnvelopedData_create - Create CMS envelope
+CMS_EnvelopedData_create_with_libctx, CMS_EnvelopedData_create
+- Create CMS envelope
 
 =head1 SYNOPSIS
 
  #include <openssl/cms.h>
 
+ CMS_ContentInfo *CMS_EnvelopedData_create_with_libctx(const EVP_CIPHER *cipher,
+                                                       OPENSSL_CTX *libctx,
+                                                       const char *propq);
  CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
 
 =head1 DESCRIPTION
 
-CMS_EnvelopedData_create() creates a B<CMS_ContentInfo> structure with
-a type B<NID_pkcs7_enveloped>. B<cipher> is the symmetric cipher to use.
+CMS_EnvelopedData_create_with_libctx() creates a B<CMS_ContentInfo> structure with
+a type B<NID_pkcs7_enveloped>. I<cipher> is the symmetric cipher to use. The
+library context I<libctx> and the property query I<propq> are used when
+retrieving algorithms from providers.
 
-The algorithm passed in the B<cipher> parameter must support ASN1 encoding of
+The algorithm passed in the I<cipher> parameter must support ASN1 encoding of
 its parameters.
 
 The recipients can be added later using L<CMS_add1_recipient_cert(3)> or
@@ -24,6 +30,10 @@ L<CMS_add0_recipient_key(3)>.
 The B<CMS_ContentInfo> structure needs to be finalized using L<CMS_final(3)>
 and then freed using L<CMS_ContentInfo_free(3)>.
 
+CMS_EnvelopedData_create() is similar to CMS_EnvelopedData_create_with_libctx()
+but uses default values of NULL for the library context I<libctx> and the
+property query I<propq>.
+
 =head1 NOTES
 
 Although CMS_EnvelopedData_create() allocates a new B<CMS_ContentInfo>
@@ -40,6 +50,10 @@ Otherwise it returns a pointer to the newly allocated structure.
 
 L<ERR_get_error(3)>, L<CMS_encrypt(3)>, L<CMS_decrypt(3)>, L<CMS_final(3)>
 
+head1 HISTORY
+
+The CMS_EnvelopedData_create_with_libctx() method was added in OpenSSL 3.0.
+
 =head1 COPYRIGHT
 
 Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
index 1bc9fd041d7f93902a210420aea236626c55c798..211ec18d36962ebfbf52c8038d3ef2420c25d216 100644 (file)
@@ -2,20 +2,26 @@
 
 =head1 NAME
 
-CMS_encrypt - create a CMS envelopedData structure
+CMS_encrypt_with_libctx, CMS_encrypt - create a CMS envelopedData structure
 
 =head1 SYNOPSIS
 
  #include <openssl/cms.h>
 
+ CMS_ContentInfo *CMS_encrypt_with_libctx(STACK_OF(X509) *certs,
+                                          BIO *in, const EVP_CIPHER *cipher,
+                                          unsigned int flags,
+                                          OPENSSL_CTX *libctx, const char *propq);
  CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
                               const EVP_CIPHER *cipher, unsigned int flags);
 
 =head1 DESCRIPTION
 
-CMS_encrypt() creates and returns a CMS EnvelopedData structure. B<certs>
-is a list of recipient certificates. B<in> is the content to be encrypted.
-B<cipher> is the symmetric cipher to use. B<flags> is an optional set of flags.
+CMS_encrypt_with_libctx() creates and returns a CMS EnvelopedData structure.
+I<certs> is a list of recipient certificates. I<in> is the content to be
+encrypted. I<cipher> is the symmetric cipher to use. I<flags> is an optional set
+of flags. The library context I<libctx> and the property query I<propq> are used
+internally when retrieving algorithms from providers.
 
 Only certificates carrying RSA, Diffie-Hellman or EC keys are supported by this
 function.
@@ -75,10 +81,14 @@ and CMS_add0_recipient_key().
 The parameter B<certs> may be NULL if B<CMS_PARTIAL> is set and recipients
 added later using CMS_add1_recipient_cert() or CMS_add0_recipient_key().
 
+CMS_encrypt() is similar to CMS_encrypt_with_libctx() but uses default values of
+NULL for the library context I<libctx> and the property query I<propq>.
+
 =head1 RETURN VALUES
 
-CMS_encrypt() returns either a CMS_ContentInfo structure or NULL if an error
-occurred. The error can be obtained from ERR_get_error(3).
+CMS_encrypt_with_libctx() and CMS_encrypt() return either a CMS_ContentInfo
+structure or NULL if an error occurred. The error can be obtained from
+ERR_get_error(3).
 
 =head1 SEE ALSO
 
@@ -86,11 +96,13 @@ L<ERR_get_error(3)>, L<CMS_decrypt(3)>
 
 =head1 HISTORY
 
+The function CMS_encrypt_with_libctx() was added in OpenSSL 3.0.
+
 The B<CMS_STREAM> flag was first supported in OpenSSL 1.0.0.
 
 =head1 COPYRIGHT
 
-Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index d9a4796dacd57547e2bd8a3f0d6c9c7f7df91558..704d4bac01f9b4a701762c3397b76b2d0f5077d1 100644 (file)
@@ -2,16 +2,21 @@
 
 =head1 NAME
 
-CMS_ReceiptRequest_create0, CMS_add1_ReceiptRequest, CMS_get1_ReceiptRequest, CMS_ReceiptRequest_get0_values - CMS signed receipt request functions
+CMS_ReceiptRequest_create0_with_libctx, CMS_ReceiptRequest_create0,
+CMS_add1_ReceiptRequest, CMS_get1_ReceiptRequest, CMS_ReceiptRequest_get0_values
+- CMS signed receipt request functions
 
 =head1 SYNOPSIS
 
  #include <openssl/cms.h>
 
- 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 *CMS_ReceiptRequest_create0(
+     unsigned char *id, int idlen, int allorfirst,
+     STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo);
  int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
  int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
  void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, ASN1_STRING **pcid,
@@ -21,13 +26,18 @@ CMS_ReceiptRequest_create0, CMS_add1_ReceiptRequest, CMS_get1_ReceiptRequest, CM
 
 =head1 DESCRIPTION
 
-CMS_ReceiptRequest_create0() creates a signed receipt request structure. The
-B<signedContentIdentifier> field is set using B<id> and B<idlen>, or it is set
-to 32 bytes of pseudo random data if B<id> is NULL. If B<receiptList> is NULL
-the allOrFirstTier option in B<receiptsFrom> is used and set to the value of
-the B<allorfirst> parameter. If B<receiptList> is not NULL the B<receiptList>
-option in B<receiptsFrom> is used. The B<receiptsTo> parameter specifies the
-B<receiptsTo> field value.
+CMS_ReceiptRequest_create0_with_libctx() creates a signed receipt request
+structure. The B<signedContentIdentifier> field is set using I<id> and I<idlen>,
+or it is set to 32 bytes of pseudo random data if I<id> is NULL.
+If I<receiptList> is NULL the allOrFirstTier option in I<receiptsFrom> is used
+and set to the value of the I<allorfirst> parameter. If I<receiptList> is not
+NULL the I<receiptList> option in I<receiptsFrom> is used. The I<receiptsTo>
+parameter specifies the I<receiptsTo> field value. The library context I<libctx>
+and the property query I<propq> are used when retrieving algorithms from providers.
+
+CMS_ReceiptRequest_create0() is similar to
+CMS_ReceiptRequest_create0_with_libctx() but uses default values of NULL for the
+library context I<libctx> and the property query I<propq>.
 
 The CMS_add1_ReceiptRequest() function adds a signed receipt request B<rr>
 to SignerInfo structure B<si>.
@@ -51,8 +61,8 @@ CMS_verify().
 
 =head1 RETURN VALUES
 
-CMS_ReceiptRequest_create0() returns a signed receipt request structure or
-NULL if an error occurred.
+CMS_ReceiptRequest_create0_with_libctx() and CMS_ReceiptRequest_create0() return
+a signed receipt request structure or NULL if an error occurred.
 
 CMS_add1_ReceiptRequest() returns 1 for success or 0 if an error occurred.
 
@@ -66,9 +76,13 @@ L<ERR_get_error(3)>, L<CMS_sign(3)>,
 L<CMS_sign_receipt(3)>, L<CMS_verify(3)>
 L<CMS_verify_receipt(3)>
 
+=head1 HISTORY
+
+The function CMS_ReceiptRequest_create0_with_libctx() was added in OpenSSL 3.0.
+
 =head1 COPYRIGHT
 
-Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index cc20f8f00384213f59bde1acffa44c981d8989fa..cf92d35303b28ca77425c223dbe2f2f397f89590 100644 (file)
@@ -2,27 +2,36 @@
 
 =head1 NAME
 
-CMS_sign - create a CMS SignedData structure
+CMS_sign, CMS_sign_with_libctx - create a CMS SignedData structure
 
 =head1 SYNOPSIS
 
  #include <openssl/cms.h>
 
+ CMS_ContentInfo *CMS_sign_with_libctx(X509 *signcert, EVP_PKEY *pkey,
+                                       STACK_OF(X509) *certs, BIO *data,
+                                       unsigned int flags,
+                                       OPENSSL_CTX *ctx, const char *propq);
  CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
                            BIO *data, unsigned int flags);
 
 =head1 DESCRIPTION
 
-CMS_sign() creates and returns a CMS SignedData structure. B<signcert> is
-the certificate to sign with, B<pkey> is the corresponding private key.
-B<certs> is an optional additional set of certificates to include in the CMS
-structure (for example any intermediate CAs in the chain). Any or all of
-these parameters can be B<NULL>, see B<NOTES> below.
+CMS_sign_with_libctx() creates and returns a CMS SignedData structure.
+I<signcert> is the certificate to sign with, I<pkey> is the corresponding
+private key. I<certs> is an optional additional set of certificates to include
+in the CMS structure (for example any intermediate CAs in the chain). The
+library context I<libctx> and the property query I<propq> are used when
+retrieving algorithms from providers. Any or all of these parameters can be
+B<NULL>, see B<NOTES> below.
 
 The data to be signed is read from BIO B<data>.
 
 B<flags> is an optional set of flags.
 
+CMS_sign() is similar to CMS_sign_with_libctx() but uses default values of NULL
+for the library context I<libctx> and the property query I<propq>.
+
 =head1 NOTES
 
 Any of the following flags (ored together) can be passed in the B<flags>
@@ -57,7 +66,8 @@ omitted.
 If present the SMIMECapabilities attribute indicates support for the following
 algorithms in preference order: 256 bit AES, Gost R3411-94, Gost 28147-89, 192
 bit AES, 128 bit AES, triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2.
-If any of these algorithms is not available then it will not be included: for example the GOST algorithms will not be included if the GOST ENGINE is
+If any of these algorithms is not available then it will not be included:
+for example the GOST algorithms will not be included if the GOST ENGINE is
 not loaded.
 
 OpenSSL will by default identify signing certificates using issuer name
@@ -105,8 +115,9 @@ Some attributes such as counter signatures are not supported.
 
 =head1 RETURN VALUES
 
-CMS_sign() returns either a valid CMS_ContentInfo structure or NULL if an error
-occurred. The error can be obtained from ERR_get_error(3).
+CMS_sign_with_libctx() and CMS_sign() return either a valid CMS_ContentInfo
+structure or NULL if an error occurred. The error can be obtained from
+ERR_get_error(3).
 
 =head1 SEE ALSO
 
@@ -117,6 +128,8 @@ L<ERR_get_error(3)>, L<CMS_verify(3)>
 The B<CMS_STREAM> flag is only supported for detached data in OpenSSL 0.9.8,
 it is supported for embedded data in OpenSSL 1.0.0 and later.
 
+The CMS_sign_with_libctx() method was added in OpenSSL 3.0.
+
 =head1 COPYRIGHT
 
 Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
index 136bfd8f0a33979085882c355bc803c16015c5f2..c7ca845eee6675e521ed9d39a63c959c1d6c9603 100644 (file)
@@ -2,12 +2,14 @@
 
 =head1 NAME
 
-SMIME_read_CMS - parse S/MIME message
+SMIME_read_CMS_ex, SMIME_read_CMS - parse S/MIME message
 
 =head1 SYNOPSIS
 
  #include <openssl/cms.h>
 
+ CMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, BIO **bcont,
+                                    CMS_ContentInfo **cms);
  CMS_ContentInfo *SMIME_read_CMS(BIO *in, BIO **bcont);
 
 =head1 DESCRIPTION
@@ -22,6 +24,11 @@ written to B<*bcont>, otherwise B<*bcont> is set to NULL.
 The parsed CMS_ContentInfo structure is returned or NULL if an
 error occurred.
 
+SMIME_read_CMS_ex() is similar to SMIME_read_CMS() but can optionally supply a
+previously created I<cms> CMS_ContentInfo object. If I<cms> is NULL then it is
+identical to SMIME_read_CMS().
+To create a I<cms> object use L<CMS_ContentInfo_new_with_libctx(3)>.
+
 =head1 NOTES
 
 If B<*bcont> is not NULL then the message is clear text signed. B<*bcont> can
@@ -53,16 +60,22 @@ should be available.
 
 =head1 RETURN VALUES
 
-SMIME_read_CMS() returns a valid B<CMS_ContentInfo> structure or B<NULL>
-if an error occurred. The error can be obtained from ERR_get_error(3).
+SMIME_read_CMS_ex() and SMIME_read_CMS() return a valid B<CMS_ContentInfo>
+structure or B<NULL> if an error occurred. The error can be obtained from
+ERR_get_error(3).
 
 =head1 SEE ALSO
 
 L<ERR_get_error(3)>,
-L<SMIME_read_CMS(3)>, L<CMS_sign(3)>,
-L<CMS_verify(3)>, L<CMS_encrypt(3)>,
+L<CMS_sign(3)>,
+L<CMS_verify(3)>,
+L<CMS_encrypt(3)>,
 L<CMS_decrypt(3)>
 
+=head1 HISTORY
+
+The function SMIME_read_CMS_ex() was added in OpenSSL 3.0.
+
 =head1 COPYRIGHT
 
 Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
index a0f4b6a0ec3ddbbcdc3ae4e2dac71d328cb1c65b..7397008fcb9a35eb1bb5acb969daa4f8ff473917 100644 (file)
@@ -45,6 +45,9 @@ DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
 DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
 DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
 
+CMS_ContentInfo *CMS_ContentInfo_new_with_libctx(OPENSSL_CTX *libctx,
+                                                 const char *propq);
+
 # define CMS_SIGNERINFO_ISSUER_SERIAL    0
 # define CMS_SIGNERINFO_KEYIDENTIFIER    1
 
@@ -104,6 +107,7 @@ int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
 int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
                              int flags);
 CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
+CMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, BIO **bcont, CMS_ContentInfo **ci);
 int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
 
 int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont,
@@ -112,6 +116,10 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont,
 CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
                           STACK_OF(X509) *certs, BIO *data,
                           unsigned int flags);
+CMS_ContentInfo *CMS_sign_with_libctx(X509 *signcert, EVP_PKEY *pkey,
+                                      STACK_OF(X509) *certs, BIO *data,
+                                      unsigned int flags,
+                                      OPENSSL_CTX *ctx, const char *propq);
 
 CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
                                   X509 *signcert, EVP_PKEY *pkey,
@@ -119,11 +127,18 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
 
 int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
 CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
+CMS_ContentInfo *CMS_data_create_with_libctx(BIO *in, unsigned int flags,
+                                             OPENSSL_CTX *ctx,
+                                             const char *propq);
 
 int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
                       unsigned int flags);
 CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
                                    unsigned int flags);
+CMS_ContentInfo *CMS_digest_create_with_libctx(BIO *in, const EVP_MD *md,
+                                               unsigned int flags,
+                                               OPENSSL_CTX *ctx,
+                                               const char *propq);
 
 int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
                               const unsigned char *key, size_t keylen,
@@ -132,6 +147,13 @@ int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
 CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
                                            const unsigned char *key,
                                            size_t keylen, unsigned int flags);
+CMS_ContentInfo *CMS_EncryptedData_encrypt_with_libctx(BIO *in,
+                                                       const EVP_CIPHER *cipher,
+                                                       const unsigned char *key,
+                                                       size_t keylen,
+                                                       unsigned int flags,
+                                                       OPENSSL_CTX *ctx,
+                                                       const char *propq);
 
 int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
                                const unsigned char *key, size_t keylen);
@@ -147,12 +169,17 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
 
 CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
                              const EVP_CIPHER *cipher, unsigned int flags);
+CMS_ContentInfo *CMS_encrypt_with_libctx(STACK_OF(X509) *certs,
+                                         BIO *in, const EVP_CIPHER *cipher,
+                                         unsigned int flags,
+                                         OPENSSL_CTX *ctx, const char *propq);
 
 int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
                 BIO *dcont, BIO *out, unsigned int flags);
 
 int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
-int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, X509 *peer);
+int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk,
+                                   X509 *cert, X509 *peer);
 int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
                          unsigned char *key, size_t keylen,
                          const unsigned char *id, size_t idlen);
@@ -163,6 +190,10 @@ STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
 int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
 EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri);
 CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
+CMS_ContentInfo *CMS_EnvelopedData_create_with_libctx(const EVP_CIPHER *cipher,
+                                                      OPENSSL_CTX *ctx,
+                                                      const char *propq);
+
 CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
                                            X509 *recip, unsigned int flags);
 CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip,
@@ -297,11 +328,16 @@ void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
                                     int lastpos, int type);
 
 int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
-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(
+    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 *ctx, const char *propq);
+
 int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
 void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
                                     ASN1_STRING **pcid,