mirror of
https://github.com/openssl/openssl.git
synced 2025-03-25 20:00:44 +08:00
Add libctx support to PKCS7.
-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)
This commit is contained in:
parent
45b22d6a35
commit
90a1f2d76f
19
apps/pkcs7.c
19
apps/pkcs7.c
@ -57,12 +57,14 @@ const OPTIONS pkcs7_options[] = {
|
||||
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) {
|
||||
@ -119,11 +121,18 @@ int pkcs7_main(int argc, char **argv)
|
||||
if (in == NULL)
|
||||
goto end;
|
||||
|
||||
if (informat == FORMAT_ASN1)
|
||||
p7 = d2i_PKCS7_bio(in, NULL);
|
||||
else
|
||||
p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
|
||||
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)
|
||||
p7i = d2i_PKCS7_bio(in, &p7);
|
||||
else
|
||||
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;
|
||||
|
32
apps/smime.c
32
apps/smime.c
@ -45,7 +45,7 @@ typedef enum OPTION_choice {
|
||||
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
|
||||
@ -70,6 +70,7 @@ const OPTIONS smime_options[] = {
|
||||
{"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"},
|
||||
@ -133,6 +134,7 @@ const OPTIONS smime_options[] = {
|
||||
|
||||
int smime_main(int argc, char **argv)
|
||||
{
|
||||
CONF *conf = NULL;
|
||||
BIO *in = NULL, *out = NULL, *indata = NULL;
|
||||
EVP_PKEY *key = NULL;
|
||||
PKCS7 *p7 = NULL;
|
||||
@ -155,6 +157,8 @@ int smime_main(int argc, char **argv)
|
||||
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;
|
||||
@ -252,6 +256,11 @@ int smime_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_ENGINE:
|
||||
e = setup_engine(opt_arg(), 0);
|
||||
break;
|
||||
@ -476,18 +485,25 @@ int smime_main(int argc, char **argv)
|
||||
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;
|
||||
}
|
||||
@ -518,7 +534,7 @@ int smime_main(int argc, char **argv)
|
||||
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;
|
||||
/*
|
||||
@ -533,7 +549,8 @@ int smime_main(int argc, char **argv)
|
||||
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) {
|
||||
@ -643,6 +660,7 @@ int smime_main(int argc, char **argv)
|
||||
BIO_free(indata);
|
||||
BIO_free_all(out);
|
||||
OPENSSL_free(passin);
|
||||
NCONF_free(conf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
#include <openssl/x509.h>
|
||||
#include "pk7_local.h"
|
||||
|
||||
/* PKCS#7 ASN1 module */
|
||||
|
||||
@ -62,7 +63,52 @@ ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = {
|
||||
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)
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#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)
|
||||
@ -57,22 +58,27 @@ static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
|
||||
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)) {
|
||||
@ -86,7 +92,6 @@ static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
|
||||
err:
|
||||
BIO_free(btmp);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
|
||||
@ -97,12 +102,13 @@ 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;
|
||||
|
||||
@ -148,8 +154,9 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
|
||||
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;
|
||||
|
||||
@ -201,17 +208,21 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
|
||||
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).
|
||||
@ -266,10 +277,10 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -287,10 +298,21 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
|
||||
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)
|
||||
@ -342,6 +364,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
|
||||
return out;
|
||||
|
||||
err:
|
||||
EVP_CIPHER_free(fetched_cipher);
|
||||
BIO_free_all(out);
|
||||
BIO_free_all(btmp);
|
||||
return NULL;
|
||||
@ -361,12 +384,12 @@ static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
|
||||
/* 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;
|
||||
@ -374,12 +397,16 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
|
||||
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;
|
||||
@ -410,7 +437,9 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
|
||||
/* 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);
|
||||
@ -422,7 +451,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
|
||||
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);
|
||||
@ -449,8 +479,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
|
||||
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);
|
||||
@ -458,6 +488,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
|
||||
}
|
||||
|
||||
BIO_set_md(btmp, evp_md);
|
||||
EVP_MD_free(evp_md);
|
||||
if (out == NULL)
|
||||
out = btmp;
|
||||
else
|
||||
@ -504,13 +535,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
|
||||
*/
|
||||
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;
|
||||
@ -585,9 +617,11 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
|
||||
}
|
||||
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);
|
||||
@ -658,12 +692,15 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
|
||||
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;
|
||||
@ -771,7 +808,8 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
|
||||
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;
|
||||
@ -830,6 +868,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
|
||||
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)
|
||||
@ -837,11 +876,13 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -863,7 +904,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
|
||||
#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
|
||||
@ -903,7 +944,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
|
||||
#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
|
||||
@ -918,7 +959,6 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
|
||||
OPENSSL_free(abuf);
|
||||
EVP_MD_CTX_free(mctx);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
|
||||
@ -983,11 +1023,13 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
|
||||
{
|
||||
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) {
|
||||
@ -1055,7 +1097,8 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
|
||||
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,
|
||||
@ -1078,7 +1121,8 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
|
||||
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;
|
||||
@ -1087,6 +1131,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_MD_CTX_free(mdc_tmp);
|
||||
EVP_MD_free(fetched_md);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
#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)
|
||||
@ -236,6 +238,7 @@ int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
|
||||
}
|
||||
}
|
||||
|
||||
psi->ctx = pkcs7_get0_ctx(p7);
|
||||
if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
|
||||
return 0;
|
||||
return 1;
|
||||
@ -380,6 +383,70 @@ PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
|
||||
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)) {
|
||||
@ -435,6 +502,7 @@ PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
|
||||
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);
|
||||
@ -547,6 +615,7 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
|
||||
}
|
||||
|
||||
ec->cipher = cipher;
|
||||
ec->ctx = pkcs7_get0_ctx(p7);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
14
crypto/pkcs7/pk7_local.h
Normal file
14
crypto/pkcs7/pk7_local.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* 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);
|
@ -11,6 +11,7 @@
|
||||
#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 */
|
||||
|
||||
@ -30,6 +31,8 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
|
||||
{
|
||||
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
|
||||
@ -37,12 +40,25 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include "pk7_local.h"
|
||||
|
||||
#define BUFFERSIZE 4096
|
||||
|
||||
@ -23,14 +24,15 @@ DEFINE_STACK_OF(PKCS7_SIGNER_INFO)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -41,7 +43,7 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -66,6 +68,13 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
|
||||
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;
|
||||
@ -84,10 +93,8 @@ int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
|
||||
PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
err:
|
||||
BIO_free_all(p7bio);
|
||||
|
||||
return ret;
|
||||
@ -116,6 +123,7 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
|
||||
{
|
||||
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);
|
||||
@ -128,6 +136,7 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
si->ctx = pkcs7_get0_ctx(p7);
|
||||
if (!(flags & PKCS7_NOCERTS)) {
|
||||
if (!PKCS7_add_certificate(p7, signcert))
|
||||
goto err;
|
||||
@ -162,7 +171,8 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -197,7 +207,7 @@ static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
|
||||
|
||||
}
|
||||
|
||||
if (osdig)
|
||||
if (osdig != NULL)
|
||||
return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
|
||||
|
||||
PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
|
||||
@ -217,20 +227,21 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -243,7 +254,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@ -251,17 +262,17 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
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))
|
||||
@ -270,12 +281,12 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
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))
|
||||
@ -285,8 +296,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
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;
|
||||
@ -307,7 +317,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
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
|
||||
@ -318,7 +328,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
|
||||
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);
|
||||
@ -327,7 +337,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
|
||||
/* 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 (;;) {
|
||||
@ -340,7 +350,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
|
||||
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;
|
||||
}
|
||||
@ -354,7 +364,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -437,29 +447,31 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs,
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
@ -478,6 +490,13 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#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)
|
||||
@ -232,7 +233,12 @@ int i2d_X509_CRL_bio(BIO *bp, const X509_CRL *crl)
|
||||
#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)
|
||||
@ -243,7 +249,12 @@ 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)
|
||||
|
@ -50,6 +50,7 @@ B<openssl> B<smime>
|
||||
{- $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
|
||||
@ -292,6 +293,8 @@ Any verification errors cause the command to exit.
|
||||
|
||||
{- $OpenSSL::safe::opt_provider_item -}
|
||||
|
||||
{- $OpenSSL::safe::opt_config_item -}
|
||||
|
||||
=item I<recipcert> ...
|
||||
|
||||
One or more certificates of message recipients, used when encrypting
|
||||
|
@ -2,20 +2,26 @@
|
||||
|
||||
=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
|
||||
@ -60,10 +66,13 @@ PEM_write_bio_PKCS7_stream() finalize the structure. Alternatively finalization
|
||||
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
|
||||
|
||||
@ -71,11 +80,13 @@ L<ERR_get_error(3)>, L<PKCS7_decrypt(3)>
|
||||
|
||||
=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
|
||||
|
@ -2,21 +2,27 @@
|
||||
|
||||
=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>.
|
||||
|
||||
@ -88,14 +94,17 @@ PKCS#7 structure is output.
|
||||
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
|
||||
|
||||
@ -103,6 +112,8 @@ L<ERR_get_error(3)>, L<PKCS7_verify(3)>
|
||||
|
||||
=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.
|
||||
|
||||
|
@ -2,12 +2,13 @@
|
||||
|
||||
=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
|
||||
@ -23,6 +24,11 @@ B<*bcont> is set to B<NULL>.
|
||||
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
|
||||
@ -56,8 +62,8 @@ streaming single pass option should be available.
|
||||
|
||||
=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
|
||||
|
||||
@ -66,9 +72,13 @@ L<SMIME_read_PKCS7(3)>, L<PKCS7_sign(3)>,
|
||||
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
|
||||
|
@ -29,6 +29,7 @@ CERTIFICATEPOLICIES_free,
|
||||
CERTIFICATEPOLICIES_new,
|
||||
CMS_ContentInfo_free,
|
||||
CMS_ContentInfo_new,
|
||||
CMS_ContentInfo_new_with_libctx,
|
||||
CMS_ContentInfo_print_ctx,
|
||||
CMS_ReceiptRequest_free,
|
||||
CMS_ReceiptRequest_new,
|
||||
@ -201,6 +202,7 @@ PKCS7_SIGN_ENVELOPE_free,
|
||||
PKCS7_SIGN_ENVELOPE_new,
|
||||
PKCS7_dup,
|
||||
PKCS7_free,
|
||||
PKCS7_new_with_libctx,
|
||||
PKCS7_new,
|
||||
PKCS7_print_ctx,
|
||||
PKCS8_PRIV_KEY_INFO_free,
|
||||
@ -335,6 +337,10 @@ to generate the function bodies.
|
||||
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
|
||||
@ -348,11 +354,16 @@ user-defined, then pass in any I<pctx> down to any nested calls.
|
||||
|
||||
=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.
|
||||
|
10
include/crypto/pkcs7.h
Normal file
10
include/crypto/pkcs7.h
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* 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);
|
@ -36,6 +36,11 @@ Digest_Encryption_ID rsaEncryption
|
||||
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;
|
||||
@ -51,6 +56,7 @@ typedef struct pkcs7_signer_info_st {
|
||||
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)
|
||||
|
||||
@ -60,6 +66,7 @@ typedef struct pkcs7_recip_info_st {
|
||||
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)
|
||||
|
||||
@ -82,6 +89,7 @@ typedef struct pkcs7_enc_content_st {
|
||||
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 {
|
||||
@ -147,6 +155,7 @@ typedef struct pkcs7_st {
|
||||
/* Anything else */
|
||||
ASN1_TYPE *other;
|
||||
} d;
|
||||
PKCS7_CTX ctx;
|
||||
} PKCS7;
|
||||
DEFINE_OR_DECLARE_STACK_OF(PKCS7)
|
||||
|
||||
@ -231,6 +240,7 @@ DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
|
||||
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)
|
||||
@ -289,6 +299,9 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
|
||||
|
||||
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,
|
||||
@ -301,6 +314,9 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs,
|
||||
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);
|
||||
|
||||
@ -315,6 +331,7 @@ int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user