Skip to content

Commit

Permalink
Add libctx support to PKCS7.
Browse files Browse the repository at this point in the history
-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 #11884)
  • Loading branch information
slontis committed Aug 9, 2020
1 parent 45b22d6 commit 90a1f2d
Show file tree
Hide file tree
Showing 16 changed files with 419 additions and 99 deletions.
17 changes: 13 additions & 4 deletions apps/pkcs7.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -119,11 +121,18 @@ int pkcs7_main(int argc, char **argv)
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;
Expand Down
32 changes: 25 additions & 7 deletions apps/smime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"},
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
/*
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
}

Expand Down
48 changes: 47 additions & 1 deletion crypto/pkcs7/pk7_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <openssl/asn1t.h>
#include <openssl/pkcs7.h>
#include <openssl/x509.h>
#include "pk7_local.h"

/* PKCS#7 ASN1 module */

Expand Down Expand Up @@ -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)

Expand Down

0 comments on commit 90a1f2d

Please sign in to comment.