-Public PKCS7 methods that create a PKCS7 object now have variants that also add a libctx and propq.
This includes PKCS7_new_with_libctx(), PKCS7_sign_with_libctx() and PKCS7_encrypt_with_libctx()
-Added SMIME_read_PKCS7_ex() so that a created PKCS7 object can be passed to the read.
-d2i_PKCS7_bio() has been modified so that after it loads the PKCS7 object 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)
int pkcs7_main(int argc, char **argv)
{
ENGINE *e = NULL;
- PKCS7 *p7 = NULL;
+ PKCS7 *p7 = NULL, *p7i;
BIO *in = NULL, *out = NULL;
int informat = FORMAT_PEM, outformat = FORMAT_PEM;
char *infile = NULL, *outfile = NULL, *prog;
int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, ret = 1;
OPTION_CHOICE o;
+ OPENSSL_CTX *libctx = app_get0_libctx();
+ const char *propq = app_get0_propq();
prog = opt_init(argc, argv, pkcs7_options);
while ((o = opt_next()) != OPT_EOF) {
if (in == NULL)
goto end;
+ p7 = PKCS7_new_with_libctx(libctx, propq);
+ if (p7 == NULL) {
+ BIO_printf(bio_err, "unable to allocate PKCS7 object\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
if (informat == FORMAT_ASN1)
- p7 = d2i_PKCS7_bio(in, NULL);
+ p7i = d2i_PKCS7_bio(in, &p7);
else
- p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
- if (p7 == NULL) {
+ p7i = PEM_read_bio_PKCS7(in, &p7, NULL, NULL);
+ if (p7i == NULL) {
BIO_printf(bio_err, "unable to load PKCS7 object\n");
ERR_print_errors(bio_err);
goto end;
OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_MD,
OPT_CIPHER, OPT_INKEY, OPT_KEYFORM, OPT_CERTFILE, OPT_CAFILE,
OPT_CAPATH, OPT_CASTORE, OPT_NOCAFILE, OPT_NOCAPATH, OPT_NOCASTORE,
- OPT_R_ENUM, OPT_PROV_ENUM,
+ OPT_R_ENUM, OPT_PROV_ENUM, OPT_CONFIG,
OPT_V_ENUM,
OPT_IN, OPT_INFORM, OPT_OUT,
OPT_OUTFORM, OPT_CONTENT
{"stream", OPT_STREAM, '-', "Enable CMS streaming" },
{"indef", OPT_INDEF, '-', "Same as -stream" },
{"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"},
+ OPT_CONFIG_OPTION,
OPT_SECTION("Action"),
{"encrypt", OPT_ENCRYPT, '-', "Encrypt message"},
int smime_main(int argc, char **argv)
{
+ CONF *conf = NULL;
BIO *in = NULL, *out = NULL, *indata = NULL;
EVP_PKEY *key = NULL;
PKCS7 *p7 = NULL;
int vpmtouched = 0, rv = 0;
ENGINE *e = NULL;
const char *mime_eol = "\n";
+ OPENSSL_CTX *libctx = app_get0_libctx();
+ const char *propq = app_get0_propq();
if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
return 1;
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_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
goto end;
if (operation & SMIME_IP) {
+ PKCS7 *p7_in = NULL;
+
+ p7 = PKCS7_new_with_libctx(libctx, propq);
+ if (p7 == NULL) {
+ BIO_printf(bio_err, "Error allocating PKCS7 object\n");
+ goto end;
+ }
if (informat == FORMAT_SMIME) {
- p7 = SMIME_read_PKCS7(in, &indata);
+ p7_in = SMIME_read_PKCS7_ex(in, &indata, &p7);
} else if (informat == FORMAT_PEM) {
- p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
+ p7_in = PEM_read_bio_PKCS7(in, &p7, NULL, NULL);
} else if (informat == FORMAT_ASN1) {
- p7 = d2i_PKCS7_bio(in, NULL);
+ p7_in = d2i_PKCS7_bio(in, &p7);
} else {
BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
goto end;
}
- if (p7 == NULL) {
+ if (p7_in == NULL) {
BIO_printf(bio_err, "Error reading S/MIME message\n");
goto end;
}
if (operation == SMIME_ENCRYPT) {
if (indef)
flags |= PKCS7_STREAM;
- p7 = PKCS7_encrypt(encerts, in, cipher, flags);
+ p7 = PKCS7_encrypt_with_libctx(encerts, in, cipher, flags, libctx, propq);
} else if (operation & SMIME_SIGNERS) {
int i;
/*
flags |= PKCS7_STREAM;
}
flags |= PKCS7_PARTIAL;
- p7 = PKCS7_sign(NULL, NULL, other, in, flags);
+ p7 = PKCS7_sign_with_libctx(NULL, NULL, other, in, flags, libctx,
+ propq);
if (p7 == NULL)
goto end;
if (flags & PKCS7_NOCERTS) {
BIO_free(indata);
BIO_free_all(out);
OPENSSL_free(passin);
+ NCONF_free(conf);
return ret;
}
#include <openssl/asn1t.h>
#include <openssl/pkcs7.h>
#include <openssl/x509.h>
+#include "pk7_local.h"
/* PKCS#7 ASN1 module */
ASN1_ADB_OBJECT(PKCS7)
}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7)
-IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
+PKCS7 *d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len)
+{
+ PKCS7 *ret;
+
+ ret = (PKCS7 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, (PKCS7_it()));
+ if (ret != NULL && a != NULL)
+ pkcs7_resolve_libctx(ret);
+ return ret;
+}
+
+int i2d_PKCS7(const PKCS7 *a, unsigned char **out)
+{
+ return ASN1_item_i2d((const ASN1_VALUE *)a, out, (PKCS7_it()));\
+}
+
+PKCS7 *PKCS7_new(void)
+{
+ return (PKCS7 *)ASN1_item_new(ASN1_ITEM_rptr(PKCS7));
+}
+
+PKCS7 *PKCS7_new_with_libctx(OPENSSL_CTX *libctx, const char *propq)
+{
+ PKCS7 *pkcs7 = PKCS7_new();
+
+ if (pkcs7 != NULL) {
+ pkcs7->ctx.libctx = libctx;
+ pkcs7->ctx.propq = NULL;
+ if (propq != NULL) {
+ pkcs7->ctx.propq = OPENSSL_strdup(propq);
+ if (pkcs7->ctx.propq == NULL) {
+ PKCS7_free(pkcs7);
+ pkcs7 = NULL;
+ ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+ }
+ }
+ }
+ return pkcs7;
+}
+
+void PKCS7_free(PKCS7 *p7)
+{
+ if (p7 != NULL) {
+ OPENSSL_free(p7->ctx.propq);
+ ASN1_item_free((ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7));
+ }
+}
IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7)
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
+#include "pk7_local.h"
DEFINE_STACK_OF(X509_ALGOR)
DEFINE_STACK_OF(X509_ATTRIBUTE)
return NULL;
}
-static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
+static int pkcs7_bio_add_digest(BIO **pbio, X509_ALGOR *alg,
+ const PKCS7_CTX *ctx)
{
BIO *btmp;
- const EVP_MD *md;
+ const char *name;
+ EVP_MD *fetched = NULL;
+
if ((btmp = BIO_new(BIO_f_md())) == NULL) {
PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
goto err;
}
- md = EVP_get_digestbyobj(alg->algorithm);
- if (md == NULL) {
+ name = OBJ_nid2sn(OBJ_obj2nid(alg->algorithm));
+ fetched = EVP_MD_fetch(ctx->libctx, name, ctx->propq);
+ if (fetched == NULL) {
PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE);
goto err;
}
- BIO_set_md(btmp, md);
+ BIO_set_md(btmp, fetched);
+ EVP_MD_free(fetched);
if (*pbio == NULL)
*pbio = btmp;
else if (!BIO_push(*pbio, btmp)) {
err:
BIO_free(btmp);
return 0;
-
}
static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
unsigned char *ek = NULL;
int ret = 0;
size_t eklen;
+ const PKCS7_CTX *ctx = ri->ctx;
pkey = X509_get0_pubkey(ri->cert);
if (pkey == NULL)
return 0;
- pctx = EVP_PKEY_CTX_new(pkey, NULL);
+ pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, ctx->propq);
if (pctx == NULL)
return 0;
unsigned char *ek = NULL;
size_t eklen;
int ret = -1;
+ const PKCS7_CTX *ctx = ri->ctx;
- pctx = EVP_PKEY_CTX_new(pkey, NULL);
+ pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, ctx->propq);
if (pctx == NULL)
return -1;
int i;
BIO *out = NULL, *btmp = NULL;
X509_ALGOR *xa = NULL;
+ EVP_CIPHER *fetched_cipher = NULL;
const EVP_CIPHER *evp_cipher = NULL;
STACK_OF(X509_ALGOR) *md_sk = NULL;
STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
X509_ALGOR *xalg = NULL;
PKCS7_RECIP_INFO *ri = NULL;
ASN1_OCTET_STRING *os = NULL;
+ const PKCS7_CTX *p7_ctx;
if (p7 == NULL) {
PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
return NULL;
}
+ p7_ctx = pkcs7_get0_ctx(p7);
+
/*
* The content field in the PKCS7 ContentInfo is optional, but that really
* only applies to inner content (precisely, detached signatures).
}
for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
- if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
+ if (!pkcs7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i), p7_ctx))
goto err;
- if (xa && !PKCS7_bio_add_digest(&out, xa))
+ if (xa && !pkcs7_bio_add_digest(&out, xa, p7_ctx))
goto err;
if (evp_cipher != NULL) {
ivlen = EVP_CIPHER_iv_length(evp_cipher);
xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
if (ivlen > 0)
- if (RAND_bytes(iv, ivlen) <= 0)
+ if (RAND_bytes_ex(p7_ctx->libctx, iv, ivlen) <= 0)
goto err;
- if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0)
+
+ fetched_cipher = EVP_CIPHER_fetch(p7_ctx->libctx,
+ EVP_CIPHER_name(evp_cipher),
+ p7_ctx->propq);
+ if (fetched_cipher == NULL)
goto err;
+
+ if (EVP_CipherInit_ex(ctx, fetched_cipher, NULL, NULL, NULL, 1) <= 0)
+ goto err;
+
+ EVP_CIPHER_free(fetched_cipher);
+ fetched_cipher = NULL;
+
if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
goto err;
if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
return out;
err:
+ EVP_CIPHER_free(fetched_cipher);
BIO_free_all(out);
BIO_free_all(btmp);
return NULL;
/* int */
BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
{
- int i, j, len;
+ int i, len;
BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
X509_ALGOR *xa;
ASN1_OCTET_STRING *data_body = NULL;
- const EVP_MD *evp_md;
- const EVP_CIPHER *evp_cipher = NULL;
+ EVP_MD *evp_md = NULL;
+ EVP_CIPHER *evp_cipher = NULL;
EVP_CIPHER_CTX *evp_ctx = NULL;
X509_ALGOR *enc_alg = NULL;
STACK_OF(X509_ALGOR) *md_sk = NULL;
PKCS7_RECIP_INFO *ri = NULL;
unsigned char *ek = NULL, *tkey = NULL;
int eklen = 0, tkeylen = 0;
+ const char *name;
+ const PKCS7_CTX *p7_ctx;
if (p7 == NULL) {
PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER);
return NULL;
}
+ p7_ctx = pkcs7_get0_ctx(p7);
+
if (p7->d.ptr == NULL) {
PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
return NULL;
/* data_body is NULL if the optional EncryptedContent is missing. */
data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
- evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
+
+ name = OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm));
+ evp_cipher = EVP_CIPHER_fetch(p7_ctx->libctx, name, p7_ctx->propq);
if (evp_cipher == NULL) {
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
enc_alg = p7->d.enveloped->enc_data->algorithm;
/* data_body is NULL if the optional EncryptedContent is missing. */
data_body = p7->d.enveloped->enc_data->enc_data;
- evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
+ name = OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm));
+ evp_cipher = EVP_CIPHER_fetch(p7_ctx->libctx, name, p7_ctx->propq);
if (evp_cipher == NULL) {
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
goto err;
}
- j = OBJ_obj2nid(xa->algorithm);
- evp_md = EVP_get_digestbynid(j);
+ name = OBJ_nid2sn(OBJ_obj2nid(xa->algorithm));
+ evp_md = EVP_MD_fetch(p7_ctx->libctx, name, p7_ctx->propq);
if (evp_md == NULL) {
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_UNKNOWN_DIGEST_TYPE);
}
BIO_set_md(btmp, evp_md);
+ EVP_MD_free(evp_md);
if (out == NULL)
out = btmp;
else
*/
for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
-
+ ri->ctx = p7_ctx;
if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey,
EVP_CIPHER_key_length(evp_cipher)) < 0)
goto err;
ERR_clear_error();
}
} else {
+ ri->ctx = p7_ctx;
/* Only exit on fatal errors, not decrypt failure */
if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0)
goto err;
}
BIO_push(out, bio);
bio = NULL;
+ EVP_CIPHER_free(evp_cipher);
return out;
err:
+ EVP_CIPHER_free(evp_cipher);
OPENSSL_clear_free(ek, eklen);
OPENSSL_clear_free(tkey, tkeylen);
BIO_free_all(out);
STACK_OF(X509_ATTRIBUTE) *sk;
STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
ASN1_OCTET_STRING *os = NULL;
+ const PKCS7_CTX *p7_ctx;
if (p7 == NULL) {
PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
return 0;
}
+ p7_ctx = pkcs7_get0_ctx(p7);
+
if (p7->d.ptr == NULL) {
PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
return 0;
if (abuf == NULL)
goto err;
- if (!EVP_SignFinal(ctx_tmp, abuf, &abuflen, si->pkey)) {
+ if (!EVP_SignFinal_with_libctx(ctx_tmp, abuf, &abuflen, si->pkey,
+ p7_ctx->libctx, p7_ctx->propq)) {
OPENSSL_free(abuf);
PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
goto err;
int alen;
size_t siglen;
const EVP_MD *md = NULL;
+ const PKCS7_CTX *ctx = si->ctx;
md = EVP_get_digestbyobj(si->digest_alg->algorithm);
if (md == NULL)
mctx = EVP_MD_CTX_new();
if (mctx == NULL) {
- PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, ERR_R_MALLOC_FAILURE);
+ PKCS7err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
+ if (EVP_DigestSignInit_with_libctx(mctx, &pctx,
+ EVP_MD_name(md), ctx->libctx, ctx->propq,
+ si->pkey) <= 0)
goto err;
/*
#if 0
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) {
- PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
+ PKCS7err(0, PKCS7_R_CTRL_ERROR);
goto err;
}
#endif
#if 0
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) {
- PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
+ PKCS7err(0, PKCS7_R_CTRL_ERROR);
goto err;
}
#endif
OPENSSL_free(abuf);
EVP_MD_CTX_free(mctx);
return 0;
-
}
int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
{
ASN1_OCTET_STRING *os;
EVP_MD_CTX *mdc_tmp, *mdc;
+ EVP_MD *fetched_md = NULL;
int ret = 0, i;
int md_type;
STACK_OF(X509_ATTRIBUTE) *sk;
BIO *btmp;
EVP_PKEY *pkey;
+ const PKCS7_CTX *ctx = pkcs7_get0_ctx(p7);
mdc_tmp = EVP_MD_CTX_new();
if (mdc_tmp == NULL) {
goto err;
}
- if (!EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL))
+ fetched_md = EVP_MD_fetch(ctx->libctx, OBJ_nid2sn(md_type), ctx->propq);
+ if (fetched_md == NULL || !EVP_VerifyInit_ex(mdc_tmp, fetched_md, NULL))
goto err;
alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
goto err;
}
- i = EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey);
+ i = EVP_VerifyFinal_with_libctx(mdc_tmp, os->data, os->length, pkey,
+ ctx->libctx, ctx->propq);
if (i <= 0) {
PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE);
ret = -1;
ret = 1;
err:
EVP_MD_CTX_free(mdc_tmp);
+ EVP_MD_free(fetched_md);
return ret;
}
#include <openssl/x509.h>
#include "crypto/asn1.h"
#include "crypto/evp.h"
+#include "crypto/x509.h"
+#include "pk7_local.h"
DEFINE_STACK_OF(X509)
DEFINE_STACK_OF(X509_CRL)
}
}
+ psi->ctx = pkcs7_get0_ctx(p7);
if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
return 0;
return 1;
return NULL;
}
+static STACK_OF(X509) *pkcs7_get_signer_certs(const PKCS7 *p7)
+{
+ if (PKCS7_type_is_signed(p7))
+ return p7->d.sign->cert;
+ if (PKCS7_type_is_signedAndEnveloped(p7))
+ return p7->d.signed_and_enveloped->cert;
+ return NULL;
+}
+
+static STACK_OF(PKCS7_RECIP_INFO) *pkcs7_get_recipient_info(const PKCS7 *p7)
+{
+ if (PKCS7_type_is_signedAndEnveloped(p7))
+ return p7->d.signed_and_enveloped->recipientinfo;
+ if (PKCS7_type_is_enveloped(p7))
+ return p7->d.enveloped->recipientinfo;
+ return NULL;
+}
+
+/*
+ * Set up the library context into any loaded structure that needs it.
+ * i.e loaded X509 objects.
+ */
+void pkcs7_resolve_libctx(PKCS7 *p7)
+{
+ int i;
+ const PKCS7_CTX *ctx = pkcs7_get0_ctx(p7);
+ STACK_OF(PKCS7_RECIP_INFO) *rinfos = pkcs7_get_recipient_info(p7);
+ STACK_OF(PKCS7_SIGNER_INFO) *sinfos = PKCS7_get_signer_info(p7);
+ STACK_OF(X509) *certs = pkcs7_get_signer_certs(p7);
+
+ if (ctx == NULL)
+ return;
+
+ for (i = 0; i < sk_X509_num(certs); i++)
+ x509_set0_libctx(sk_X509_value(certs, i), ctx->libctx, ctx->propq);
+
+ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rinfos); i++) {
+ PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(rinfos, i);
+
+ x509_set0_libctx(ri->cert, ctx->libctx, ctx->propq);
+ }
+
+ for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
+ PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+
+ if (si != NULL)
+ si->ctx = ctx;
+ }
+}
+
+const PKCS7_CTX *pkcs7_get0_ctx(const PKCS7 *p7)
+{
+ return p7 != NULL ? &p7->ctx : NULL;
+}
+
+OPENSSL_CTX *pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx)
+{
+ return ctx != NULL ? ctx->libctx : NULL;
+}
+const char *pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx)
+{
+ return ctx != NULL ? ctx->propq : NULL;
+}
+
int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
{
if (PKCS7_type_is_digest(p7)) {
goto err;
if (!PKCS7_add_recipient_info(p7, ri))
goto err;
+ ri->ctx = pkcs7_get0_ctx(p7);
return ri;
err:
PKCS7_RECIP_INFO_free(ri);
}
ec->cipher = cipher;
+ ec->ctx = pkcs7_get0_ctx(p7);
return 1;
}
--- /dev/null
+/*
+ * Copyright 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "crypto/pkcs7.h"
+
+const PKCS7_CTX *pkcs7_get0_ctx(const PKCS7 *p7);
+OPENSSL_CTX *pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx);
+const char *pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx);
#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/asn1.h>
+#include "pk7_local.h"
/* PKCS#7 wrappers round generalised stream and MIME routines */
{
STACK_OF(X509_ALGOR) *mdalgs;
int ctype_nid = OBJ_obj2nid(p7->type);
+ const PKCS7_CTX *ctx = pkcs7_get0_ctx(p7);
+
if (ctype_nid == NID_pkcs7_signed)
mdalgs = p7->d.sign->md_algs;
else
flags ^= SMIME_OLDMIME;
- return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
- ctype_nid, NID_undef, mdalgs,
- ASN1_ITEM_rptr(PKCS7));
+ return SMIME_write_ASN1_with_libctx(bio, (ASN1_VALUE *)p7, data, flags,
+ ctype_nid, NID_undef, mdalgs,
+ ASN1_ITEM_rptr(PKCS7),
+ pkcs7_ctx_get0_libctx(ctx),
+ pkcs7_ctx_get0_propq(ctx));
+}
+
+PKCS7 *SMIME_read_PKCS7_ex(BIO *bio, BIO **bcont, PKCS7 **p7)
+{
+ PKCS7 *ret;
+
+ ret = (PKCS7 *)SMIME_read_ASN1_ex(bio, bcont, ASN1_ITEM_rptr(PKCS7),
+ (ASN1_VALUE **)p7);
+ if (ret != NULL && p7 != NULL)
+ pkcs7_resolve_libctx(ret);
+ return ret;
}
PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
{
- return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7));
+ return SMIME_read_PKCS7_ex(bio, bcont, NULL);
}
#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
+#include "pk7_local.h"
#define BUFFERSIZE 4096
static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
-PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
- BIO *data, int flags)
+PKCS7 *PKCS7_sign_with_libctx(X509 *signcert, EVP_PKEY *pkey,
+ STACK_OF(X509) *certs, BIO *data, int flags,
+ OPENSSL_CTX *libctx, const char *propq)
{
PKCS7 *p7;
int i;
- if ((p7 = PKCS7_new()) == NULL) {
- PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE);
+ if ((p7 = PKCS7_new_with_libctx(libctx, propq)) == NULL) {
+ PKCS7err(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
goto err;
if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) {
- PKCS7err(PKCS7_F_PKCS7_SIGN, PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
+ PKCS7err(0, PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
goto err;
}
return NULL;
}
+PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+ BIO *data, int flags)
+{
+ return PKCS7_sign_with_libctx(signcert, pkey, certs, data, flags, NULL, NULL);
+}
+
+
int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
{
BIO *p7bio;
PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN);
goto err;
}
-
ret = 1;
-
- err:
+err:
BIO_free_all(p7bio);
return ret;
{
PKCS7_SIGNER_INFO *si = NULL;
STACK_OF(X509_ALGOR) *smcap = NULL;
+
if (!X509_check_private_key(signcert, pkey)) {
PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
return NULL;
}
+ si->ctx = pkcs7_get0_ctx(p7);
if (!(flags & PKCS7_NOCERTS)) {
if (!PKCS7_add_certificate(p7, signcert))
goto err;
if (flags & PKCS7_REUSE_DIGEST) {
if (!pkcs7_copy_existing_digest(p7, si))
goto err;
- if (!(flags & PKCS7_PARTIAL) && !PKCS7_SIGNER_INFO_sign(si))
+ if (!(flags & PKCS7_PARTIAL)
+ && !PKCS7_SIGNER_INFO_sign(si))
goto err;
}
}
}
- if (osdig)
+ if (osdig != NULL)
return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
int i, j = 0, k, ret = 0;
BIO *p7bio = NULL;
BIO *tmpin = NULL, *tmpout = NULL;
+ const PKCS7_CTX *p7_ctx;
if (p7 == NULL) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER);
+ PKCS7err(0, PKCS7_R_INVALID_NULL_POINTER);
return 0;
}
if (!PKCS7_type_is_signed(p7)) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE);
+ PKCS7err(0, PKCS7_R_WRONG_CONTENT_TYPE);
return 0;
}
/* Check for no data and no content: no data to verify signature */
if (PKCS7_get_detached(p7) && !indata) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT);
+ PKCS7err(0, PKCS7_R_NO_CONTENT);
return 0;
}
* process is different, but the existing PKCs7 verification works.
*/
if (!PKCS7_get_detached(p7) && indata) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT);
+ PKCS7err(0, PKCS7_R_CONTENT_AND_DATA_PRESENT);
return 0;
}
}
sinfos = PKCS7_get_signer_info(p7);
if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA);
+ PKCS7err(0, PKCS7_R_NO_SIGNATURES_ON_DATA);
return 0;
}
signers = PKCS7_get0_signers(p7, certs, flags);
- if (!signers)
+ if (signers == NULL)
return 0;
/* Now verify the certificates */
-
- cert_ctx = X509_STORE_CTX_new();
+ p7_ctx = pkcs7_get0_ctx(p7);
+ cert_ctx = X509_STORE_CTX_new_with_libctx(p7_ctx->libctx, p7_ctx->propq);
if (cert_ctx == NULL)
goto err;
if (!(flags & PKCS7_NOVERIFY))
if (!(flags & PKCS7_NOCHAIN)) {
if (!X509_STORE_CTX_init(cert_ctx, store, signer,
p7->d.sign->cert)) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB);
+ PKCS7err(0, ERR_R_X509_LIB);
goto err;
}
X509_STORE_CTX_set_default(cert_ctx, "smime_sign");
} else if (!X509_STORE_CTX_init(cert_ctx, store, signer, NULL)) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB);
+ PKCS7err(0, ERR_R_X509_LIB);
goto err;
}
if (!(flags & PKCS7_NOCRL))
j = X509_STORE_CTX_get_error(cert_ctx);
X509_STORE_CTX_cleanup(cert_ctx);
if (i <= 0) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY,
- PKCS7_R_CERTIFICATE_VERIFY_ERROR);
+ PKCS7err(0, PKCS7_R_CERTIFICATE_VERIFY_ERROR);
ERR_add_error_data(2, "Verify error:",
X509_verify_cert_error_string(j));
goto err;
len = BIO_get_mem_data(indata, &ptr);
tmpin = BIO_new_mem_buf(ptr, len);
if (tmpin == NULL) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
+ PKCS7err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
} else
if (flags & PKCS7_TEXT) {
if ((tmpout = BIO_new(BIO_s_mem())) == NULL) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
+ PKCS7err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
BIO_set_mem_eof_return(tmpout, 0);
/* We now have to 'read' from p7bio to calculate digests etc. */
if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
+ PKCS7err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
for (;;) {
if (flags & PKCS7_TEXT) {
if (!SMIME_text(tmpout, out)) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SMIME_TEXT_ERROR);
+ PKCS7err(0, PKCS7_R_SMIME_TEXT_ERROR);
BIO_free(tmpout);
goto err;
}
signer = sk_X509_value(signers, i);
j = PKCS7_signatureVerify(p7bio, p7, si, signer);
if (j <= 0) {
- PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE);
+ PKCS7err(0, PKCS7_R_SIGNATURE_FAILURE);
goto err;
}
}
/* Build a complete PKCS#7 enveloped data */
-PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
- int flags)
+PKCS7 *PKCS7_encrypt_with_libctx(STACK_OF(X509) *certs, BIO *in,
+ const EVP_CIPHER *cipher, int flags,
+ OPENSSL_CTX *libctx, const char *propq)
{
PKCS7 *p7;
BIO *p7bio = NULL;
int i;
X509 *x509;
- if ((p7 = PKCS7_new()) == NULL) {
- PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE);
+
+ if ((p7 = PKCS7_new_with_libctx(libctx, propq)) == NULL) {
+ PKCS7err(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
goto err;
if (!PKCS7_set_cipher(p7, cipher)) {
- PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER);
+ PKCS7err(0, PKCS7_R_ERROR_SETTING_CIPHER);
goto err;
}
for (i = 0; i < sk_X509_num(certs); i++) {
x509 = sk_X509_value(certs, i);
if (!PKCS7_add_recipient(p7, x509)) {
- PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_ADDING_RECIPIENT);
+ PKCS7err(0, PKCS7_R_ERROR_ADDING_RECIPIENT);
goto err;
}
}
}
+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
+ int flags)
+{
+ return PKCS7_encrypt_with_libctx(certs, in, cipher, flags, NULL, NULL);
+}
+
+
int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
{
BIO *tmpmem;
#include <openssl/dsa.h>
#include <openssl/x509v3.h>
#include "crypto/asn1.h"
+#include "crypto/pkcs7.h"
#include "crypto/x509.h"
static void clean_id_ctx(EVP_MD_CTX *ctx)
#ifndef OPENSSL_NO_STDIO
PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7)
{
- return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
+ PKCS7 *ret;
+
+ ret = ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
+ if (ret != NULL && p7 != NULL)
+ pkcs7_resolve_libctx(ret);
+ return ret;
}
int i2d_PKCS7_fp(FILE *fp, const PKCS7 *p7)
PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7)
{
- return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
+ PKCS7 *ret;
+
+ ret = ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
+ if (ret != NULL && p7 != NULL)
+ pkcs7_resolve_libctx(ret);
+ return ret;
}
int i2d_PKCS7_bio(BIO *bp, const PKCS7 *p7)
{- $OpenSSL::safe::opt_r_synopsis -}
{- $OpenSSL::safe::opt_v_synopsis -}
{- $OpenSSL::safe::opt_provider_synopsis -}
+{- $OpenSSL::safe::opt_config_synopsis -}
I<recipcert> ...
=for openssl ifdef engine
{- $OpenSSL::safe::opt_provider_item -}
+{- $OpenSSL::safe::opt_config_item -}
+
=item I<recipcert> ...
One or more certificates of message recipients, used when encrypting
=head1 NAME
-PKCS7_encrypt - create a PKCS#7 envelopedData structure
+PKCS7_encrypt_with_libctx, PKCS7_encrypt
+- create a PKCS#7 envelopedData structure
=head1 SYNOPSIS
#include <openssl/pkcs7.h>
+ PKCS7 *PKCS7_encrypt_with_libctx(STACK_OF(X509) *certs, BIO *in,
+ const EVP_CIPHER *cipher, int flags,
+ OPENSSL_CTX *libctx, const char *propq);
PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
int flags);
=head1 DESCRIPTION
-PKCS7_encrypt() creates and returns a PKCS#7 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.
+PKCS7_encrypt_with_libctx() creates and returns a PKCS#7 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
+when retrieving algorithms from providers.
Only RSA keys are supported in PKCS#7 and envelopedData so the recipient
certificates supplied to this function must all contain RSA public keys, though
can be performed by obtaining the streaming ASN1 B<BIO> directly using
BIO_new_PKCS7().
+PKCS7_encrypt() is similar to PKCS7_encrypt_with_libctx() but uses default
+values of NULL for the library context I<libctx> and the property query I<propq>.
+
=head1 RETURN VALUES
-PKCS7_encrypt() returns either a PKCS7 structure or NULL if an error occurred.
-The error can be obtained from ERR_get_error(3).
+PKCS7_encrypt_with_libctx() and PKCS7_encrypt() return either a PKCS7 structure
+or NULL if an error occurred. The error can be obtained from ERR_get_error(3).
=head1 SEE ALSO
=head1 HISTORY
+The function PKCS7_encrypt_with_libctx() was added in OpenSSL 3.0.
+
The B<PKCS7_STREAM> flag was added in OpenSSL 1.0.0.
=head1 COPYRIGHT
-Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2002-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
=head1 NAME
-PKCS7_sign - create a PKCS#7 signedData structure
+PKCS7_sign_with_libctx, PKCS7_sign
+- create a PKCS#7 signedData structure
=head1 SYNOPSIS
#include <openssl/pkcs7.h>
+ PKCS7 *PKCS7_sign_with_libctx(X509 *signcert, EVP_PKEY *pkey,
+ STACK_OF(X509) *certs, BIO *data, int flags,
+ OPENSSL_CTX *libctx, const char *propq);
PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
BIO *data, int flags);
=head1 DESCRIPTION
-PKCS7_sign() creates and returns a PKCS#7 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 PKCS#7
-structure (for example any intermediate CAs in the chain).
+PKCS7_sign_with_libctx() creates and returns a PKCS#7 signedData structure.
+I<igncert> is the certificate to sign with, Ipkey> is the corresponding
+private key. I<certs> is an optional additional set of certificates to include
+in the PKCS#7 structure (for example any intermediate CAs in the chain). The
+library context I<libctx> and property query I<propq> are used when
+retrieving algorithms from providers.
The data to be signed is read from BIO B<data>.
In versions of OpenSSL before 1.0.0 the B<signcert> and B<pkey> parameters must
B<NOT> be NULL.
+PKCS7_sign() is similar to PKCS7_sign_with_libctx() but uses default values of
+NULL for the library context I<libctx> and the property query I<propq>.
+
=head1 BUGS
Some advanced attributes such as counter signatures are not supported.
=head1 RETURN VALUES
-PKCS7_sign() returns either a valid PKCS7 structure or NULL if an error
-occurred. The error can be obtained from ERR_get_error(3).
+PKCS7_sign_with_libctx() and PKCS7_sign() return either a valid PKCS7 structure
+or NULL if an error occurred. The error can be obtained from ERR_get_error(3).
=head1 SEE ALSO
=head1 HISTORY
+The function PKCS7_sign_with_libctx() was added in OpenSSL 3.0.
+
The B<PKCS7_PARTIAL> flag, and the ability for B<certs>, B<signcert>,
and B<pkey> parameters to be B<NULL> were added in OpenSSL 1.0.0.
=head1 NAME
-SMIME_read_PKCS7 - parse S/MIME message
+SMIME_read_PKCS7_ex, SMIME_read_PKCS7 - parse S/MIME message
=head1 SYNOPSIS
#include <openssl/pkcs7.h>
+ PKCS7 *SMIME_read_PKCS7_ex(BIO *bio, BIO **bcont, PKCS7 **p7);
PKCS7 *SMIME_read_PKCS7(BIO *in, BIO **bcont);
=head1 DESCRIPTION
The parsed PKCS#7 structure is returned or B<NULL> if an
error occurred.
+SMIME_read_PKCS7_ex() is similar to SMIME_read_PKCS7() but can optionally supply
+a previously created I<p7> PKCS#7 object. If I<p7> is NULL then it is identical
+to SMIME_read_PKCS7().
+To create a I<p7> object use L<PKCS7_new_with_libctx(3)>.
+
=head1 NOTES
If B<*bcont> is not B<NULL> then the message is clear text
=head1 RETURN VALUES
-SMIME_read_PKCS7() returns a valid B<PKCS7> structure or B<NULL>
-if an error occurred. The error can be obtained from ERR_get_error(3).
+SMIME_read_PKCS7_ex() and SMIME_read_PKCS7() return a valid B<PKCS7> structure
+or B<NULL> if an error occurred. The error can be obtained from ERR_get_error(3).
=head1 SEE ALSO
L<PKCS7_verify(3)>, L<PKCS7_encrypt(3)>
L<PKCS7_decrypt(3)>
+=head1 HISTORY
+
+The function SMIME_read_PKCS7_ex() was added in OpenSSL 3.0.
+
=head1 COPYRIGHT
-Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2002-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
CERTIFICATEPOLICIES_new,
CMS_ContentInfo_free,
CMS_ContentInfo_new,
+CMS_ContentInfo_new_with_libctx,
CMS_ContentInfo_print_ctx,
CMS_ReceiptRequest_free,
CMS_ReceiptRequest_new,
PKCS7_SIGN_ENVELOPE_new,
PKCS7_dup,
PKCS7_free,
+PKCS7_new_with_libctx,
PKCS7_new,
PKCS7_print_ctx,
PKCS8_PRIV_KEY_INFO_free,
B<I<TYPE>_new>() allocates an empty object of the indicated type.
The object returned must be released by calling B<I<TYPE>_free>().
+B<I<TYPE>_new_with_libctx>() is similiar to B<I<TYPE>_new>() but also passes the
+library context I<libctx> and the property query I<propq> to use when retrieving
+algorithms from providers.
+
B<I<TYPE>_dup>() copies an existing object, leaving it untouched.
B<I<TYPE>_free>() releases the object and all pointers and sub-objects
=head1 RETURN VALUES
-B<I<TYPE>_new>() and B<I<TYPE>_dup>() return a pointer to the object or NULL on
-failure.
+B<I<TYPE>_new>(), B<I<TYPE>_new_ex>() and B<I<TYPE>_dup>() return a pointer to
+the object or NULL on failure.
B<I<TYPE>_print_ctx>() returns 1 on success or zero on failure.
+=head1 HISTORY
+
+The functions PKCS7_new_with_libctx() and CMS_ContentInfo_new_with_libctx() were
+added in OpenSSL 3.0.
+
=head1 COPYRIGHT
Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
--- /dev/null
+/*
+ * Copyright 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+void pkcs7_resolve_libctx(PKCS7 *p7);
Key_Encryption_ID rsaEncryption
*/
+typedef struct PKCS7_CTX_st {
+ OPENSSL_CTX *libctx;
+ char *propq;
+} PKCS7_CTX;
+
typedef struct pkcs7_issuer_and_serial_st {
X509_NAME *issuer;
ASN1_INTEGER *serial;
STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */
/* The private key to sign with */
EVP_PKEY *pkey;
+ const PKCS7_CTX *ctx;
} PKCS7_SIGNER_INFO;
DEFINE_OR_DECLARE_STACK_OF(PKCS7_SIGNER_INFO)
X509_ALGOR *key_enc_algor;
ASN1_OCTET_STRING *enc_key;
X509 *cert; /* get the pub-key from this */
+ const PKCS7_CTX *ctx;
} PKCS7_RECIP_INFO;
DEFINE_OR_DECLARE_STACK_OF(PKCS7_RECIP_INFO)
X509_ALGOR *algorithm;
ASN1_OCTET_STRING *enc_data; /* [ 0 ] */
const EVP_CIPHER *cipher;
+ const PKCS7_CTX *ctx;
} PKCS7_ENC_CONTENT;
typedef struct pkcs7_enveloped_st {
/* Anything else */
ASN1_TYPE *other;
} d;
+ PKCS7_CTX ctx;
} PKCS7;
DEFINE_OR_DECLARE_STACK_OF(PKCS7)
DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST)
DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
DECLARE_ASN1_FUNCTIONS(PKCS7)
+PKCS7 *PKCS7_new_with_libctx(OPENSSL_CTX *libctx, const char *propq);
DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
BIO *data, int flags);
+PKCS7 *PKCS7_sign_with_libctx(X509 *signcert, EVP_PKEY *pkey,
+ STACK_OF(X509) *certs, BIO *data, int flags,
+ OPENSSL_CTX *libctx, const char *propq);
PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
X509 *signcert, EVP_PKEY *pkey,
int flags);
PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
int flags);
+PKCS7 *PKCS7_encrypt_with_libctx(STACK_OF(X509) *certs, BIO *in,
+ const EVP_CIPHER *cipher, int flags,
+ OPENSSL_CTX *libctx, const char *propq);
int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data,
int flags);
const unsigned char *md, int mdlen);
int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
+PKCS7 *SMIME_read_PKCS7_ex(BIO *bio, BIO **bcont, PKCS7 **p7);
PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);