summaryrefslogtreecommitdiffstats
path: root/crypto/pkcs12
diff options
context:
space:
mode:
authorslontis <shane.lontis@oracle.com>2022-12-21 14:39:07 +1000
committerTomas Mraz <tomas@openssl.org>2023-01-16 17:17:31 +0100
commitfe2a7341b50450dc6acd6f8a17d4420511a5aefe (patch)
treeb7ebedf8881759406bff879c5826cb182eccc5e7 /crypto/pkcs12
parent76aa4f3ac0d76e58f2111cbf87ae7f25c8766190 (diff)
PKCS12 - Add additional libctx and propq support.
Fixes #19718 Fixes #19716 Added PKCS12_SAFEBAG_get1_cert_ex(), PKCS12_SAFEBAG_get1_crl_ex() and ASN1_item_unpack_ex(). parse_bag and parse_bags now use the libctx/propq stored in the P7_CTX. PKCS12_free() needed to be manually constructed in order to free the propq. pkcs12_api_test.c changed so that it actually tests the libctx, propq. Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19942)
Diffstat (limited to 'crypto/pkcs12')
-rw-r--r--crypto/pkcs12/p12_add.c12
-rw-r--r--crypto/pkcs12/p12_asn.c17
-rw-r--r--crypto/pkcs12/p12_init.c6
-rw-r--r--crypto/pkcs12/p12_kiss.c30
-rw-r--r--crypto/pkcs12/p12_local.h2
-rw-r--r--crypto/pkcs12/p12_sbag.c37
-rw-r--r--crypto/pkcs12/p12_utl.c28
7 files changed, 115 insertions, 17 deletions
diff --git a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c
index 8a56644368..aaef5874f1 100644
--- a/crypto/pkcs12/p12_add.c
+++ b/crypto/pkcs12/p12_add.c
@@ -78,7 +78,9 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA);
return NULL;
}
- return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
+ return ASN1_item_unpack_ex(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
+ ossl_pkcs7_ctx_get0_libctx(&p7->ctx),
+ ossl_pkcs7_ctx_get0_propq(&p7->ctx));
}
/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
@@ -181,6 +183,7 @@ int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes)
STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12)
{
STACK_OF(PKCS7) *p7s;
+ PKCS7_CTX *p7ctx;
PKCS7 *p7;
int i;
@@ -188,8 +191,11 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12)
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA);
return NULL;
}
- p7s = ASN1_item_unpack(p12->authsafes->d.data,
- ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
+ p7ctx = &p12->authsafes->ctx;
+ p7s = ASN1_item_unpack_ex(p12->authsafes->d.data,
+ ASN1_ITEM_rptr(PKCS12_AUTHSAFES),
+ ossl_pkcs7_ctx_get0_libctx(p7ctx),
+ ossl_pkcs7_ctx_get0_propq(p7ctx));
if (p7s != NULL) {
for (i = 0; i < sk_PKCS7_num(p7s); i++) {
p7 = sk_PKCS7_value(p7s, i);
diff --git a/crypto/pkcs12/p12_asn.c b/crypto/pkcs12/p12_asn.c
index aabbd38eef..caae639f88 100644
--- a/crypto/pkcs12/p12_asn.c
+++ b/crypto/pkcs12/p12_asn.c
@@ -12,6 +12,7 @@
#include <openssl/asn1t.h>
#include <openssl/pkcs12.h>
#include "p12_local.h"
+#include "crypto/pkcs7.h"
/* PKCS#12 ASN1 module */
@@ -21,7 +22,21 @@ ASN1_SEQUENCE(PKCS12) = {
ASN1_OPT(PKCS12, mac, PKCS12_MAC_DATA)
} ASN1_SEQUENCE_END(PKCS12)
-IMPLEMENT_ASN1_FUNCTIONS(PKCS12)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(PKCS12, PKCS12, PKCS12)
+
+PKCS12 *PKCS12_new(void)
+{
+ return (PKCS12 *)ASN1_item_new(ASN1_ITEM_rptr(PKCS12));
+}
+
+void PKCS12_free(PKCS12 *p12)
+{
+ if (p12 != NULL && p12->authsafes != NULL) {
+ OPENSSL_free(p12->authsafes->ctx.propq);
+ p12->authsafes->ctx.propq = NULL;
+ }
+ ASN1_item_free((ASN1_VALUE *)p12, ASN1_ITEM_rptr(PKCS12));
+}
ASN1_SEQUENCE(PKCS12_MAC_DATA) = {
ASN1_SIMPLE(PKCS12_MAC_DATA, dinfo, X509_SIG),
diff --git a/crypto/pkcs12/p12_init.c b/crypto/pkcs12/p12_init.c
index dd469b5c5c..1d6c74b8c4 100644
--- a/crypto/pkcs12/p12_init.c
+++ b/crypto/pkcs12/p12_init.c
@@ -56,3 +56,9 @@ PKCS12 *PKCS12_init(int mode)
return PKCS12_init_ex(mode, NULL, NULL);
}
+const PKCS7_CTX *ossl_pkcs12_get0_pkcs7ctx(const PKCS12 *p12)
+{
+ if (p12 == NULL || p12->authsafes == NULL)
+ return NULL;
+ return &p12->authsafes->ctx;
+}
diff --git a/crypto/pkcs12/p12_kiss.c b/crypto/pkcs12/p12_kiss.c
index 0f7a437a28..f172e8b96d 100644
--- a/crypto/pkcs12/p12_kiss.c
+++ b/crypto/pkcs12/p12_kiss.c
@@ -18,10 +18,12 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
- int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+ int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts,
+ OSSL_LIB_CTX *libctx, const char *propq);
static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
- EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+ EVP_PKEY **pkey, STACK_OF(X509) *ocerts,
+ OSSL_LIB_CTX *libctx, const char *propq);
/*
* Parse and decrypt a PKCS#12 structure returning user key, user cert and
@@ -157,7 +159,8 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
sk_PKCS7_pop_free(asafes, PKCS7_free);
return 0;
}
- if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
+ if (!parse_bags(bags, pass, passlen, pkey, ocerts,
+ p7->ctx.libctx, p7->ctx.propq)) {
sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
sk_PKCS7_pop_free(asafes, PKCS7_free);
return 0;
@@ -170,12 +173,14 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
/* pkey and/or ocerts may be NULL */
static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
- int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
+ int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts,
+ OSSL_LIB_CTX *libctx, const char *propq)
{
int i;
for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i),
- pass, passlen, pkey, ocerts))
+ pass, passlen, pkey, ocerts,
+ libctx, propq))
return 0;
}
return 1;
@@ -183,7 +188,8 @@ static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
/* pkey and/or ocerts may be NULL */
static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
- EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
+ EVP_PKEY **pkey, STACK_OF(X509) *ocerts,
+ OSSL_LIB_CTX *libctx, const char *propq)
{
PKCS8_PRIV_KEY_INFO *p8;
X509 *x509;
@@ -201,7 +207,8 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
case NID_keyBag:
if (pkey == NULL || *pkey != NULL)
return 1;
- *pkey = EVP_PKCS82PKEY(PKCS12_SAFEBAG_get0_p8inf(bag));
+ *pkey = EVP_PKCS82PKEY_ex(PKCS12_SAFEBAG_get0_p8inf(bag),
+ libctx, propq);
if (*pkey == NULL)
return 0;
break;
@@ -209,9 +216,10 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
case NID_pkcs8ShroudedKeyBag:
if (pkey == NULL || *pkey != NULL)
return 1;
- if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL)
+ if ((p8 = PKCS12_decrypt_skey_ex(bag, pass, passlen,
+ libctx, propq)) == NULL)
return 0;
- *pkey = EVP_PKCS82PKEY(p8);
+ *pkey = EVP_PKCS82PKEY_ex(p8, libctx, propq);
PKCS8_PRIV_KEY_INFO_free(p8);
if (!(*pkey))
return 0;
@@ -221,7 +229,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
if (ocerts == NULL
|| PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate)
return 1;
- if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL)
+ if ((x509 = PKCS12_SAFEBAG_get1_cert_ex(bag, libctx, propq)) == NULL)
return 0;
if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
X509_free(x509);
@@ -251,7 +259,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
case NID_safeContentsBag:
return parse_bags(PKCS12_SAFEBAG_get0_safes(bag), pass, passlen, pkey,
- ocerts);
+ ocerts, libctx, propq);
default:
return 1;
diff --git a/crypto/pkcs12/p12_local.h b/crypto/pkcs12/p12_local.h
index acaa27b193..97697922bd 100644
--- a/crypto/pkcs12/p12_local.h
+++ b/crypto/pkcs12/p12_local.h
@@ -41,3 +41,5 @@ struct pkcs12_bag_st {
ASN1_TYPE *other; /* Secret or other bag */
} value;
};
+
+const PKCS7_CTX *ossl_pkcs12_get0_pkcs7ctx(const PKCS12 *p12);
diff --git a/crypto/pkcs12/p12_sbag.c b/crypto/pkcs12/p12_sbag.c
index 7106936c62..73e55461eb 100644
--- a/crypto/pkcs12/p12_sbag.c
+++ b/crypto/pkcs12/p12_sbag.c
@@ -11,6 +11,7 @@
#include "internal/cryptlib.h"
#include <openssl/pkcs12.h>
#include "p12_local.h"
+#include "crypto/x509.h"
#ifndef OPENSSL_NO_DEPRECATED_1_1_0
ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid)
@@ -101,6 +102,42 @@ X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag)
ASN1_ITEM_rptr(X509_CRL));
}
+X509 *PKCS12_SAFEBAG_get1_cert_ex(const PKCS12_SAFEBAG *bag,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ X509 *ret = NULL;
+
+ if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag)
+ return NULL;
+ if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate)
+ return NULL;
+ ret = ASN1_item_unpack_ex(bag->value.bag->value.octet,
+ ASN1_ITEM_rptr(X509), libctx, propq);
+ if (!ossl_x509_set0_libctx(ret, libctx, propq)) {
+ X509_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+X509_CRL *PKCS12_SAFEBAG_get1_crl_ex(const PKCS12_SAFEBAG *bag,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ X509_CRL *ret = NULL;
+
+ if (PKCS12_SAFEBAG_get_nid(bag) != NID_crlBag)
+ return NULL;
+ if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl)
+ return NULL;
+ ret = ASN1_item_unpack_ex(bag->value.bag->value.octet,
+ ASN1_ITEM_rptr(X509_CRL), libctx, propq);
+ if (!ossl_x509_crl_set0_libctx(ret, libctx, propq)) {
+ X509_CRL_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509)
{
return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
diff --git a/crypto/pkcs12/p12_utl.c b/crypto/pkcs12/p12_utl.c
index 6046b70886..59e0cda814 100644
--- a/crypto/pkcs12/p12_utl.c
+++ b/crypto/pkcs12/p12_utl.c
@@ -10,6 +10,8 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/pkcs12.h>
+#include "p12_local.h"
+#include "crypto/pkcs7/pk7_local.h"
/* Cheap and nasty Unicode stuff */
@@ -230,12 +232,34 @@ int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12)
PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12)
{
- return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
+ OSSL_LIB_CTX *libctx = NULL;
+ const char *propq = NULL;
+ const PKCS7_CTX *p7ctx = NULL;
+
+ if (p12 != NULL) {
+ p7ctx = ossl_pkcs12_get0_pkcs7ctx(*p12);
+ if (p7ctx != NULL) {
+ libctx = ossl_pkcs7_ctx_get0_libctx(p7ctx);
+ propq = ossl_pkcs7_ctx_get0_propq(p7ctx);
+ }
+ }
+ return ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(PKCS12), bp, p12, libctx, propq);
}
#ifndef OPENSSL_NO_STDIO
PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12)
{
- return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
+ OSSL_LIB_CTX *libctx = NULL;
+ const char *propq = NULL;
+ const PKCS7_CTX *p7ctx = NULL;
+
+ if (p12 != NULL) {
+ p7ctx = ossl_pkcs12_get0_pkcs7ctx(*p12);
+ if (p7ctx != NULL) {
+ libctx = ossl_pkcs7_ctx_get0_libctx(p7ctx);
+ propq = ossl_pkcs7_ctx_get0_propq(p7ctx);
+ }
+ }
+ return ASN1_item_d2i_fp_ex(ASN1_ITEM_rptr(PKCS12), fp, p12, libctx, propq);
}
#endif