summaryrefslogtreecommitdiffstats
path: root/apps/pkcs12.c
diff options
context:
space:
mode:
authorGraham Woodward <graham.woodward@ibm.com>2022-08-19 08:46:47 +0100
committerMatt Caswell <matt@openssl.org>2022-09-23 17:40:02 +0100
commite869c867c1c405de3b6538586f17b67937556a4b (patch)
tree21feab85e639e54c1e2a8a6d1a68a807f2e7dae4 /apps/pkcs12.c
parentecc920b3277311e859282b6d400ba8566d7ea8c1 (diff)
Allow PKCS12 export to set arbitrary bag attributes
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19025)
Diffstat (limited to 'apps/pkcs12.c')
-rw-r--r--apps/pkcs12.c74
1 files changed, 70 insertions, 4 deletions
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index 0338ff30d6..f4aef816dd 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -14,6 +14,8 @@
#include <string.h>
#include "apps.h"
#include "progs.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/pem.h>
@@ -54,6 +56,7 @@ void hex_prin(BIO *out, unsigned char *buf, int len);
static int alg_print(const X509_ALGOR *alg);
int cert_load(BIO *in, STACK_OF(X509) *sk);
static int set_pbe(int *ppbe, const char *str);
+static int jdk_trust(PKCS12_SAFEBAG *bag, void *cbarg);
typedef enum OPTION_choice {
OPT_COMMON,
@@ -525,6 +528,11 @@ int pkcs12_main(int argc, char **argv)
EVP_MD *macmd = NULL;
unsigned char *catmp = NULL;
int i;
+ CONF *conf = NULL;
+ ASN1_OBJECT *obj = NULL;
+ STACK_OF(CONF_VALUE) *cb_sk = NULL;
+ const char *cb_attr = NULL;
+ const CONF_VALUE *val = NULL;
if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
BIO_printf(bio_err, "Nothing to export due to -noout or -nocerts and -nokeys\n");
@@ -669,9 +677,30 @@ int pkcs12_main(int argc, char **argv)
if (!twopass)
OPENSSL_strlcpy(macpass, pass, sizeof(macpass));
- p12 = PKCS12_create_ex(cpass, name, key, ee_cert, certs,
- key_pbe, cert_pbe, iter, -1, keytype,
- app_get0_libctx(), app_get0_propq());
+ /* Load the config file */
+ if ((conf = app_load_config(default_config_file)) == NULL)
+ goto export_end;
+ if (!app_load_modules(conf))
+ goto export_end;
+ /* Find the cert bag section */
+ if ((cb_attr = NCONF_get_string(conf, "pkcs12", "certBagAttr")) != NULL) {
+ if ((cb_sk = NCONF_get_section(conf, cb_attr)) != NULL) {
+ for (i = 0; i < sk_CONF_VALUE_num(cb_sk); i++) {
+ val = sk_CONF_VALUE_value(cb_sk, i);
+ if (strcmp(val->name, "jdkTrustedKeyUsage") == 0)
+ obj = OBJ_txt2obj(val->value, 0);
+ }
+ } else {
+ ERR_clear_error();
+ }
+ } else {
+ ERR_clear_error();
+ }
+
+ p12 = PKCS12_create_ex2(cpass, name, key, ee_cert, certs,
+ key_pbe, cert_pbe, iter, -1, keytype,
+ app_get0_libctx(), app_get0_propq(),
+ jdk_trust, (void*)obj);
if (p12 == NULL) {
BIO_printf(bio_err, "Error creating PKCS12 structure for %s\n",
@@ -708,7 +737,8 @@ int pkcs12_main(int argc, char **argv)
OSSL_STACK_OF_X509_free(certs);
OSSL_STACK_OF_X509_free(untrusted_certs);
X509_free(ee_cert);
-
+ NCONF_free(conf);
+ ASN1_OBJECT_free(obj);
ERR_print_errors(bio_err);
goto end;
@@ -838,6 +868,31 @@ int pkcs12_main(int argc, char **argv)
return ret;
}
+static int jdk_trust(PKCS12_SAFEBAG *bag, void *cbarg)
+{
+ STACK_OF(X509_ATTRIBUTE) *attrs = NULL;
+ X509_ATTRIBUTE *attr = NULL;
+
+ /* Nothing to do */
+ if (cbarg == NULL)
+ return 1;
+
+ /* Get the current attrs */
+ attrs = (STACK_OF(X509_ATTRIBUTE)*)PKCS12_SAFEBAG_get0_attrs(bag);
+
+ /* Create a new attr for the JDK Trusted Usage and add it */
+ attr = X509_ATTRIBUTE_create(NID_oracle_jdk_trustedkeyusage, V_ASN1_OBJECT, (ASN1_OBJECT*)cbarg);
+
+ /* Add the new attr, if attrs is NULL, it'll be initialised */
+ X509at_add1_attr(&attrs, attr);
+
+ /* Set the bag attrs */
+ PKCS12_SAFEBAG_set0_attrs(bag, attrs);
+
+ X509_ATTRIBUTE_free(attr);
+ return 1;
+}
+
int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
int passlen, int options, char *pempass,
const EVP_CIPHER *enc)
@@ -1137,6 +1192,8 @@ int cert_load(BIO *in, STACK_OF(X509) *sk)
void print_attribute(BIO *out, const ASN1_TYPE *av)
{
char *value;
+ const char *ln;
+ char objbuf[80];
switch (av->type) {
case V_ASN1_BMPSTRING:
@@ -1163,6 +1220,15 @@ void print_attribute(BIO *out, const ASN1_TYPE *av)
BIO_printf(out, "\n");
break;
+ case V_ASN1_OBJECT:
+ ln = OBJ_nid2ln(OBJ_obj2nid(av->value.object));
+ if (!ln)
+ ln = "";
+ OBJ_obj2txt(objbuf, sizeof(objbuf), av->value.object, 1);
+ BIO_printf(out, "%s (%s)", ln, objbuf);
+ BIO_printf(out, "\n");
+ break;
+
default:
BIO_printf(out, "<Unsupported tag %d>\n", av->type);
break;