diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-07-25 11:11:03 +0200 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2020-08-09 09:34:52 +0200 |
commit | 90a1f2d76f53effefafbae31e2f425a3508bda45 (patch) | |
tree | 64efd480bd47dc88a3ec858c0e401d712ff39802 /crypto/pkcs7/pk7_smime.c | |
parent | Add libctx to SMIME ASN1 (diff) | |
download | openssl-90a1f2d76f53effefafbae31e2f425a3508bda45.tar.xz openssl-90a1f2d76f53effefafbae31e2f425a3508bda45.zip |
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)
Diffstat (limited to 'crypto/pkcs7/pk7_smime.c')
-rw-r--r-- | crypto/pkcs7/pk7_smime.c | 85 |
1 files changed, 52 insertions, 33 deletions
diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c index 385b4af42e..1dfdd69e51 100644 --- a/crypto/pkcs7/pk7_smime.c +++ b/crypto/pkcs7/pk7_smime.c @@ -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; |