From: Graham Woodward Date: Fri, 19 Aug 2022 07:46:47 +0000 (+0100) Subject: Allow PKCS12 export to set arbitrary bag attributes X-Git-Tag: openssl-3.2.0-alpha1~2012 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e869c86;p=thirdparty%2Fopenssl.git Allow PKCS12 export to set arbitrary bag attributes Reviewed-by: Dmitry Belyavskiy Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/19025) --- diff --git a/CHANGES.md b/CHANGES.md index 9bc1a91c94e..fb71df56a40 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -24,6 +24,14 @@ OpenSSL 3.1 ### Changes between 3.0 and 3.1 [xx XXX xxxx] + * Add the ability to add custom attributes to PKCS12 files. Add a new API + PKCS12_create_ex2, identical to the existing PKCS12_create_ex but allows + for a user specified callback and optional argument. + Added a new PKCS12_SAFEBAG_set0_attr, which allows for a new attr to be + added to the existing STACK_OF attrs. + + *Graham Woodward* + * Major refactor of the libssl record layer *Matt Caswell* diff --git a/apps/openssl-vms.cnf b/apps/openssl-vms.cnf index c141010e8ac..7eaab9457a4 100644 --- a/apps/openssl-vms.cnf +++ b/apps/openssl-vms.cnf @@ -388,3 +388,10 @@ oldcert = $insta::certout # insta.cert.pem # Certificate revocation cmd = rr oldcert = $insta::certout # insta.cert.pem + +[pkcs12] +certBagAttr = cb_attr + +# Uncomment this if you need Java compatible PKCS12 files +[cb_attr] +#jdkTrustedKeyUsage = anyExtendedKeyUsage diff --git a/apps/openssl.cnf b/apps/openssl.cnf index 1933f9ebe82..ff45f9a5aa4 100644 --- a/apps/openssl.cnf +++ b/apps/openssl.cnf @@ -388,3 +388,10 @@ oldcert = $insta::certout # insta.cert.pem # Certificate revocation cmd = rr oldcert = $insta::certout # insta.cert.pem + +[pkcs12] +certBagAttr = cb_attr + +# Uncomment this if you need Java compatible PKCS12 files +[cb_attr] +#jdkTrustedKeyUsage = anyExtendedKeyUsage diff --git a/apps/pkcs12.c b/apps/pkcs12.c index 0338ff30d6e..f4aef816dd4 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -14,6 +14,8 @@ #include #include "apps.h" #include "progs.h" +#include +#include #include #include #include @@ -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, "\n", av->type); break; diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index dbb2daa3502..96f49c8c7c7 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -905,6 +905,7 @@ PEM_R_UNSUPPORTED_CIPHER:113:unsupported cipher PEM_R_UNSUPPORTED_ENCRYPTION:114:unsupported encryption PEM_R_UNSUPPORTED_KEY_COMPONENTS:126:unsupported key components PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE:110:unsupported public key type +PKCS12_R_CALLBACK_FAILED:115:callback failed PKCS12_R_CANT_PACK_STRUCTURE:100:cant pack structure PKCS12_R_CONTENT_TYPE_NOT_DATA:121:content type not data PKCS12_R_DECODE_ERROR:101:decode error diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index eaecb61a51b..5d13a73ac4f 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -10,7 +10,7 @@ */ /* Serialized OID's */ -static const unsigned char so[8326] = { +static const unsigned char so[8345] = { 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ @@ -1149,9 +1149,11 @@ static const unsigned char so[8326] = { 0x04,0x00,0x81,0x95,0x32,0x01,0x06, /* [ 8297] OBJ_signedAssertion */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x30, /* [ 8304] OBJ_id_aa_ets_archiveTimestampV2 */ 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11,0x03,0x01, /* [ 8315] OBJ_hmacWithSM3 */ + 0x60,0x86,0x48,0x01,0x86,0xF9,0x66, /* [ 8325] OBJ_oracle */ + 0x60,0x86,0x48,0x01,0x86,0xF9,0x66,0xAD,0xCA,0x7B,0x01,0x01, /* [ 8332] OBJ_oracle_jdk_trustedkeyusage */ }; -#define NUM_NID 1282 +#define NUM_NID 1284 static const ASN1_OBJECT nid_objs[NUM_NID] = { {"UNDEF", "undefined", NID_undef}, {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, @@ -2435,9 +2437,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"signedAssertion", "signedAssertion", NID_signedAssertion, 7, &so[8297]}, {"id-aa-ets-archiveTimestampV2", "id-aa-ets-archiveTimestampV2", NID_id_aa_ets_archiveTimestampV2, 11, &so[8304]}, {"hmacWithSM3", "hmacWithSM3", NID_hmacWithSM3, 10, &so[8315]}, + {"oracle-organization", "Oracle organization", NID_oracle, 7, &so[8325]}, + {"oracle-jdk-trustedkeyusage", "Trusted key usage (Oracle)", NID_oracle_jdk_trustedkeyusage, 12, &so[8332]}, }; -#define NUM_SN 1273 +#define NUM_SN 1275 static const unsigned int sn_objs[NUM_SN] = { 364, /* "AD_DVCS" */ 419, /* "AES-128-CBC" */ @@ -3387,6 +3391,8 @@ static const unsigned int sn_objs[NUM_SN] = { 139, /* "nsSGC" */ 77, /* "nsSslServerName" */ 681, /* "onBasis" */ + 1283, /* "oracle-jdk-trustedkeyusage" */ + 1282, /* "oracle-organization" */ 1089, /* "organizationIdentifier" */ 491, /* "organizationalStatus" */ 1141, /* "oscca" */ @@ -3714,7 +3720,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1093, /* "x509ExtAdmission" */ }; -#define NUM_LN 1273 +#define NUM_LN 1275 static const unsigned int ln_objs[NUM_LN] = { 363, /* "AD Time Stamping" */ 405, /* "ANSI X9.62" */ @@ -3864,6 +3870,7 @@ static const unsigned int ln_objs[NUM_LN] = { 180, /* "OCSP Signing" */ 1005, /* "OGRN" */ 1226, /* "OGRNIP" */ + 1282, /* "Oracle organization" */ 161, /* "PBES2" */ 69, /* "PBKDF2" */ 162, /* "PBMAC1" */ @@ -3910,6 +3917,7 @@ static const unsigned int ln_objs[NUM_LN] = { 129, /* "TLS Web Server Authentication" */ 133, /* "Time Stamping" */ 375, /* "Trust Root" */ + 1283, /* "Trusted key usage (Oracle)" */ 1034, /* "X25519" */ 1035, /* "X448" */ 12, /* "X509" */ @@ -4991,7 +4999,7 @@ static const unsigned int ln_objs[NUM_LN] = { 125, /* "zlib compression" */ }; -#define NUM_OBJ 1144 +#define NUM_OBJ 1146 static const unsigned int obj_objs[NUM_OBJ] = { 0, /* OBJ_undef 0 */ 181, /* OBJ_iso 1 */ @@ -5455,6 +5463,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { 507, /* OBJ_id_hex_partial_message 1 3 6 1 7 1 1 1 */ 508, /* OBJ_id_hex_multipart_message 1 3 6 1 7 1 1 2 */ 57, /* OBJ_netscape 2 16 840 1 113730 */ + 1282, /* OBJ_oracle 2 16 840 1 113894 */ 754, /* OBJ_camellia_128_ecb 0 3 4401 5 3 1 9 1 */ 766, /* OBJ_camellia_128_ofb128 0 3 4401 5 3 1 9 3 */ 757, /* OBJ_camellia_128_cfb128 0 3 4401 5 3 1 9 4 */ @@ -6126,6 +6135,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { 957, /* OBJ_jurisdictionCountryName 1 3 6 1 4 1 311 60 2 1 3 */ 1056, /* OBJ_blake2b512 1 3 6 1 4 1 1722 12 2 1 16 */ 1057, /* OBJ_blake2s256 1 3 6 1 4 1 1722 12 2 2 8 */ + 1283, /* OBJ_oracle_jdk_trustedkeyusage 2 16 840 1 113894 746875 1 1 */ 1159, /* OBJ_dstu4145be 1 2 804 2 1 1 1 1 3 1 1 1 1 */ 1160, /* OBJ_uacurve0 1 2 804 2 1 1 1 1 3 1 1 2 0 */ 1161, /* OBJ_uacurve1 1 2 804 2 1 1 1 1 3 1 1 2 1 */ diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index 0a92288d1c8..e56d96336c6 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1279,3 +1279,5 @@ id_aa_ATSHashIndex_v3 1278 signedAssertion 1279 id_aa_ets_archiveTimestampV2 1280 hmacWithSM3 1281 +oracle 1282 +oracle_jdk_trustedkeyusage 1283 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index f413d274008..6c831141cda 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -1789,3 +1789,9 @@ dstu4145le 2 9 : uacurve9 : DSTU curve 9 : AES-128-SIV : aes-128-siv : AES-192-SIV : aes-192-siv : AES-256-SIV : aes-256-siv + + +!Cname oracle +joint-iso-itu-t 16 840 1 113894 : oracle-organization : Oracle organization +# Jdk trustedKeyUsage attribute +oracle 746875 1 1 : oracle-jdk-trustedkeyusage : Trusted key usage (Oracle) diff --git a/crypto/pkcs12/p12_attr.c b/crypto/pkcs12/p12_attr.c index 568a32a55ee..d9b2db9aaf8 100644 --- a/crypto/pkcs12/p12_attr.c +++ b/crypto/pkcs12/p12_attr.c @@ -119,3 +119,11 @@ PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag) { return bag->attrib; } + +void PKCS12_SAFEBAG_set0_attrs(PKCS12_SAFEBAG *bag, const STACK_OF(X509_ATTRIBUTE) *attrs) +{ + if (bag->attrib != attrs) + sk_X509_ATTRIBUTE_free(bag->attrib); + + bag->attrib = (STACK_OF(X509_ATTRIBUTE*))attrs; +} diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c index 7889842b6f8..3246fbb7e84 100644 --- a/crypto/pkcs12/p12_crt.c +++ b/crypto/pkcs12/p12_crt.c @@ -14,6 +14,8 @@ static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag); +static int pkcs12_remove_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, + PKCS12_SAFEBAG *bag); static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid) { @@ -24,16 +26,17 @@ static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid) return X509at_add1_attr(&bag->attrib, EVP_PKEY_get_attr(pkey, idx)) != NULL; } -PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, - X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, - int iter, int mac_iter, int keytype, - OSSL_LIB_CTX *ctx, const char *propq) +PKCS12 *PKCS12_create_ex2(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, + int iter, int mac_iter, int keytype, + OSSL_LIB_CTX *ctx, const char *propq, + PKCS12_create_cb *cb, void *cbarg) { PKCS12 *p12 = NULL; STACK_OF(PKCS7) *safes = NULL; STACK_OF(PKCS12_SAFEBAG) *bags = NULL; PKCS12_SAFEBAG *bag = NULL; - int i; + int i, cbret; unsigned char keyid[EVP_MAX_MD_SIZE]; unsigned int keyidlen = 0; @@ -65,12 +68,30 @@ PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, goto err; if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) goto err; + if (cb != NULL) { + cbret = cb(bag, cbarg); + if (cbret == -1) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CALLBACK_FAILED); + goto err; + } else if (cbret == 0) { + pkcs12_remove_bag(&bags, bag); + } + } } /* Add all other certificates */ for (i = 0; i < sk_X509_num(ca); i++) { - if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i))) + if ((bag = PKCS12_add_cert(&bags, sk_X509_value(ca, i))) == NULL) goto err; + if (cb != NULL) { + cbret = cb(bag, cbarg); + if (cbret == -1) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CALLBACK_FAILED); + goto err; + } else if (cbret == 0) { + pkcs12_remove_bag(&bags, bag); + } + } } if (bags && !PKCS12_add_safe_ex(&safes, bags, nid_cert, iter, pass, @@ -96,6 +117,15 @@ PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, goto err; if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) goto err; + if (cb != NULL) { + cbret = cb(bag, cbarg); + if (cbret == -1) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CALLBACK_FAILED); + goto err; + } else if (cbret == 0) { + pkcs12_remove_bag(&bags, bag); + } + } } if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL)) @@ -127,6 +157,16 @@ PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, } +PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, + STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, + int mac_iter, int keytype, + OSSL_LIB_CTX *ctx, const char *propq) +{ + return PKCS12_create_ex2(pass, name, pkey, cert, ca, nid_key, nid_cert, + iter, mac_iter, keytype, ctx, propq, + NULL, NULL); +} + PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype) @@ -281,6 +321,22 @@ int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, return PKCS12_add_safe_ex(psafes, bags, nid_safe, iter, pass, NULL, NULL); } + +static int pkcs12_remove_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, + PKCS12_SAFEBAG *bag) +{ + PKCS12_SAFEBAG *tmp; + + if (pbags == NULL || bag == NULL) + return 1; + + if ((tmp = sk_PKCS12_SAFEBAG_delete_ptr(*pbags, bag)) == NULL) + return 0; + + PKCS12_SAFEBAG_free(tmp); + return 1; +} + static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag) { diff --git a/crypto/pkcs12/pk12err.c b/crypto/pkcs12/pk12err.c index 6e3ec78cd6e..b53b0e0d092 100644 --- a/crypto/pkcs12/pk12err.c +++ b/crypto/pkcs12/pk12err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 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 @@ -15,6 +15,7 @@ #ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA PKCS12_str_reasons[] = { + {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_CALLBACK_FAILED), "callback failed"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_CANT_PACK_STRUCTURE), "cant pack structure"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_CONTENT_TYPE_NOT_DATA), diff --git a/doc/build.info b/doc/build.info index 8b55bcdbc7d..068082df325 100644 --- a/doc/build.info +++ b/doc/build.info @@ -1787,6 +1787,10 @@ DEPEND[html/man3/PKCS12_SAFEBAG_get1_cert.html]=man3/PKCS12_SAFEBAG_get1_cert.po GENERATE[html/man3/PKCS12_SAFEBAG_get1_cert.html]=man3/PKCS12_SAFEBAG_get1_cert.pod DEPEND[man/man3/PKCS12_SAFEBAG_get1_cert.3]=man3/PKCS12_SAFEBAG_get1_cert.pod GENERATE[man/man3/PKCS12_SAFEBAG_get1_cert.3]=man3/PKCS12_SAFEBAG_get1_cert.pod +DEPEND[html/man3/PKCS12_SAFEBAG_set0_attrs.html]=man3/PKCS12_SAFEBAG_set0_attrs.pod +GENERATE[html/man3/PKCS12_SAFEBAG_set0_attrs.html]=man3/PKCS12_SAFEBAG_set0_attrs.pod +DEPEND[man/man3/PKCS12_SAFEBAG_set0_attrs.3]=man3/PKCS12_SAFEBAG_set0_attrs.pod +GENERATE[man/man3/PKCS12_SAFEBAG_set0_attrs.3]=man3/PKCS12_SAFEBAG_set0_attrs.pod DEPEND[html/man3/PKCS12_add1_attr_by_NID.html]=man3/PKCS12_add1_attr_by_NID.pod GENERATE[html/man3/PKCS12_add1_attr_by_NID.html]=man3/PKCS12_add1_attr_by_NID.pod DEPEND[man/man3/PKCS12_add1_attr_by_NID.3]=man3/PKCS12_add1_attr_by_NID.pod @@ -3202,6 +3206,7 @@ html/man3/PKCS12_PBE_keyivgen.html \ html/man3/PKCS12_SAFEBAG_create_cert.html \ html/man3/PKCS12_SAFEBAG_get0_attrs.html \ html/man3/PKCS12_SAFEBAG_get1_cert.html \ +html/man3/PKCS12_SAFEBAG_set0_attrs.html \ html/man3/PKCS12_add1_attr_by_NID.html \ html/man3/PKCS12_add_CSPName_asc.html \ html/man3/PKCS12_add_cert.html \ @@ -3803,6 +3808,7 @@ man/man3/PKCS12_PBE_keyivgen.3 \ man/man3/PKCS12_SAFEBAG_create_cert.3 \ man/man3/PKCS12_SAFEBAG_get0_attrs.3 \ man/man3/PKCS12_SAFEBAG_get1_cert.3 \ +man/man3/PKCS12_SAFEBAG_set0_attrs.3 \ man/man3/PKCS12_add1_attr_by_NID.3 \ man/man3/PKCS12_add_CSPName_asc.3 \ man/man3/PKCS12_add_cert.3 \ diff --git a/doc/man3/PKCS12_SAFEBAG_set0_attrs.pod b/doc/man3/PKCS12_SAFEBAG_set0_attrs.pod new file mode 100644 index 00000000000..98e212a9b79 --- /dev/null +++ b/doc/man3/PKCS12_SAFEBAG_set0_attrs.pod @@ -0,0 +1,32 @@ +=pod + +=head1 NAME + +PKCS12_SAFEBAG_set0_attrs +- Set attributes for a PKCS#12 safeBag + +=head1 SYNOPSIS + + #include + + void PKCS12_SAFEBAG_set0_attrs(PKCS12_SAFEBAG *bag, const STACK_OF(X509_ATTRIBUTE) *attrs); + +=head1 DESCRIPTION + +PKCS12_SAFEBAG_set0_attrs() assigns the stack of Bs to a +PKCS#12 safeBag. I is the B to assign the attributes to. + +=head1 RETURN VALUES + +PKCS12_SAFEBAG_set0_attrs() does not return a value. + +=head1 COPYRIGHT + +Copyright 2019-2022 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 +L. + +=cut diff --git a/doc/man3/PKCS12_create.pod b/doc/man3/PKCS12_create.pod index dc0f06d9d32..8a61e2c76b9 100644 --- a/doc/man3/PKCS12_create.pod +++ b/doc/man3/PKCS12_create.pod @@ -2,7 +2,7 @@ =head1 NAME -PKCS12_create, PKCS12_create_ex - create a PKCS#12 structure +PKCS12_create, PKCS12_create_ex, PKCS12_create_cb, PKCS12_create_ex2 - create a PKCS#12 structure =head1 SYNOPSIS @@ -16,6 +16,13 @@ PKCS12_create, PKCS12_create_ex - create a PKCS#12 structure int iter, int mac_iter, int keytype, OSSL_LIB_CTX *ctx, const char *propq); + typedef int PKCS12_create_cb(PKCS12_SAFEBAG *bag, void *cbarg); + + PKCS12 *PKCS12_create_ex2(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, + int iter, int mac_iter, int keytype, + OSSL_LIB_CTX *ctx, const char *propq, + PKCS12_create_cb *cb, void *cbarg); =head1 DESCRIPTION PKCS12_create() creates a PKCS#12 structure. @@ -34,6 +41,14 @@ I is the type of key. PKCS12_create_ex() is identical to PKCS12_create() but allows for a library context I and property query I to be used to select algorithm implementations. +PKCS12_create_ex2() is identical to PKCS12_create_ex() but allows for a user defined +callback I of type B to be specified and also allows for an +optional argument I to be passed back to the callback. + +The I if specified will be called for every safebag added to the +PKCS12 structure and allows for optional application processing on the associated +safebag. For example one such use could be to add attributes to the safebag. + =head1 NOTES The parameters I, I, I, I and I @@ -73,6 +88,9 @@ PKCS12_create() makes assumptions regarding the encoding of the given pass phrase. See L for more information. +If I is specified, then it should return 1 for success and -1 for a fatal error. +A return of 0 is intended to mean to not add the bag after all. + =head1 RETURN VALUES PKCS12_create() returns a valid B structure or NULL if an error occurred. @@ -89,6 +107,7 @@ L =head1 HISTORY PKCS12_create_ex() was added in OpenSSL 3.0. +PKCS12_create_ex2() was added in OpenSSL 3.1. The defaults for encryption algorithms, MAC algorithm, and the MAC key derivation iteration count were changed in OpenSSL 3.0 to more modern diff --git a/fuzz/oids.txt b/fuzz/oids.txt index 05c40eb79a6..57be5f1674e 100644 --- a/fuzz/oids.txt +++ b/fuzz/oids.txt @@ -1145,3 +1145,5 @@ OBJ_id_aa_ATSHashIndex_v3="\x04\x00\x81\x95\x32\x01\x05" OBJ_signedAssertion="\x04\x00\x81\x95\x32\x01\x06" OBJ_id_aa_ets_archiveTimestampV2="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x02\x30" OBJ_hmacWithSM3="\x2A\x81\x1C\xCF\x55\x01\x83\x11\x03\x01" +OBJ_oracle="\x60\x86\x48\x01\x86\xF9\x66" +OBJ_oracle_jdk_trustedkeyusage="\x60\x86\x48\x01\x86\xF9\x66\xAD\xCA\x7B\x01\x01" diff --git a/include/crypto/pkcs12err.h b/include/crypto/pkcs12err.h index 662f412e97c..114971c607c 100644 --- a/include/crypto/pkcs12err.h +++ b/include/crypto/pkcs12err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2022 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 diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h index f329fdfbb14..e8c18b077fe 100644 --- a/include/openssl/obj_mac.h +++ b/include/openssl/obj_mac.h @@ -5570,6 +5570,16 @@ #define LN_aes_256_siv "aes-256-siv" #define NID_aes_256_siv 1200 +#define SN_oracle "oracle-organization" +#define LN_oracle "Oracle organization" +#define NID_oracle 1282 +#define OBJ_oracle OBJ_joint_iso_itu_t,16L,840L,1L,113894L + +#define SN_oracle_jdk_trustedkeyusage "oracle-jdk-trustedkeyusage" +#define LN_oracle_jdk_trustedkeyusage "Trusted key usage (Oracle)" +#define NID_oracle_jdk_trustedkeyusage 1283 +#define OBJ_oracle_jdk_trustedkeyusage OBJ_oracle,746875L,1L,1L + #endif /* OPENSSL_OBJ_MAC_H */ #ifndef OPENSSL_NO_DEPRECATED_3_0 diff --git a/include/openssl/pkcs12.h.in b/include/openssl/pkcs12.h.in index 7d8b751bbca..f3a72bb0efd 100644 --- a/include/openssl/pkcs12.h.in +++ b/include/openssl/pkcs12.h.in @@ -199,6 +199,7 @@ ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs, char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); const STACK_OF(X509_ATTRIBUTE) * PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag); +void PKCS12_SAFEBAG_set0_attrs(PKCS12_SAFEBAG *bag, const STACK_OF(X509_ATTRIBUTE) *attrs); unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, const char *pass, int passlen, const unsigned char *in, int inlen, @@ -286,6 +287,7 @@ DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) void PKCS12_PBE_add(void); int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); +typedef int PKCS12_create_cb(PKCS12_SAFEBAG *bag, void *cbarg); PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype); @@ -293,6 +295,11 @@ PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype, OSSL_LIB_CTX *ctx, const char *propq); +PKCS12 *PKCS12_create_ex2(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, + int iter, int mac_iter, int keytype, + OSSL_LIB_CTX *ctx, const char *propq, + PKCS12_create_cb *cb, void *cbarg); PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, diff --git a/include/openssl/pkcs12err.h b/include/openssl/pkcs12err.h index 933c83299ae..abce3736289 100644 --- a/include/openssl/pkcs12err.h +++ b/include/openssl/pkcs12err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 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 @@ -21,6 +21,7 @@ /* * PKCS12 reason codes. */ +# define PKCS12_R_CALLBACK_FAILED 115 # define PKCS12_R_CANT_PACK_STRUCTURE 100 # define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 # define PKCS12_R_DECODE_ERROR 101 diff --git a/test/helpers/pkcs12.c b/test/helpers/pkcs12.c index d5269e6d209..c2969c21d05 100644 --- a/test/helpers/pkcs12.c +++ b/test/helpers/pkcs12.c @@ -338,13 +338,15 @@ err: * PKCS12 safeBag/attribute builder */ -static int add_attributes(PKCS12_SAFEBAG *bag, const PKCS12_ATTR *attrs) +static int add_attributes(PKCS12_SAFEBAG *bag, const PKCS12_ATTR *attr) { int ret = 0; int attr_nid; - const PKCS12_ATTR *p_attr = attrs; + const PKCS12_ATTR *p_attr = attr; + STACK_OF(X509_ATTRIBUTE)* attrs = NULL; + X509_ATTRIBUTE *x509_attr = NULL; - if (attrs == NULL) + if (attr == NULL) return 1; while (p_attr->oid != NULL) { @@ -358,6 +360,12 @@ static int add_attributes(PKCS12_SAFEBAG *bag, const PKCS12_ATTR *attrs) if (!TEST_true(PKCS12_add_localkeyid(bag, (unsigned char *)p_attr->value, strlen(p_attr->value)))) goto err; + } else if (attr_nid == NID_oracle_jdk_trustedkeyusage) { + attrs = (STACK_OF(X509_ATTRIBUTE)*)PKCS12_SAFEBAG_get0_attrs(bag); + x509_attr = X509_ATTRIBUTE_create(attr_nid, V_ASN1_OBJECT, OBJ_txt2obj(p_attr->value, 0)); + X509at_add1_attr(&attrs, x509_attr); + PKCS12_SAFEBAG_set0_attrs(bag, attrs); + X509_ATTRIBUTE_free(x509_attr); } else { /* Custom attribute values limited to ASCII in these tests */ if (!TEST_true(PKCS12_add1_attr_by_txt(bag, p_attr->oid, MBSTRING_ASC, diff --git a/test/helpers/pkcs12.h b/test/helpers/pkcs12.h index d1a3b93d329..f09013222ee 100644 --- a/test/helpers/pkcs12.h +++ b/test/helpers/pkcs12.h @@ -82,6 +82,7 @@ void add_keybag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len, const PKCS12_ATTR *attrs, const PKCS12_ENC *enc); void add_secretbag(PKCS12_BUILDER *pb, int secret_nid, const char *secret, const PKCS12_ATTR *attrs); +void add_extra_attr(PKCS12_BUILDER *pb); /* Decode/check functions */ void start_check_pkcs12(PKCS12_BUILDER *pb); diff --git a/test/pkcs12_api_test.c b/test/pkcs12_api_test.c index 51976edea66..eebd78827f9 100644 --- a/test/pkcs12_api_test.c +++ b/test/pkcs12_api_test.c @@ -94,6 +94,98 @@ err: return TEST_true(ret); } +static int pkcs12_create_cb(PKCS12_SAFEBAG *bag, void *cbarg) +{ + int cb_ret = *((int*)cbarg); + return cb_ret; +} + +static PKCS12 *pkcs12_create_ex2_setup(EVP_PKEY **key, X509 **cert, STACK_OF(X509) **ca) +{ + PKCS12 *p12 = NULL; + p12 = PKCS12_load("out6.p12"); + if (!TEST_ptr(p12)) + goto err; + + if (!TEST_true(PKCS12_parse(p12, "", key, cert, ca))) + goto err; + + return p12; +err: + PKCS12_free(p12); + return NULL; +} + +static int pkcs12_create_ex2_test(int test) +{ + int ret = 0, cb_ret = 0; + PKCS12 *ptr = NULL, *p12 = NULL; + EVP_PKEY *key = NULL; + X509 *cert = NULL; + STACK_OF(X509) *ca = NULL; + + p12 = pkcs12_create_ex2_setup(&key, &cert, &ca); + if (!TEST_ptr(p12)) + goto err; + + if (test == 0) { + /* Confirm PKCS12_create_ex2 returns NULL */ + ptr = PKCS12_create_ex2(NULL, NULL, NULL, + NULL, NULL, NID_undef, NID_undef, + 0, 0, 0, + NULL, NULL, + NULL, NULL); + if (TEST_ptr(ptr)) + goto err; + + /* Can't proceed without a valid cert at least */ + if (!TEST_ptr(cert)) + goto err; + + /* Specified call back called - return success */ + cb_ret = 1; + ptr = PKCS12_create_ex2(NULL, NULL, NULL, + cert, NULL, NID_undef, NID_undef, + 0, 0, 0, + NULL, NULL, + pkcs12_create_cb, (void*)&cb_ret); + /* PKCS12 successfully created */ + if (!TEST_ptr(ptr)) + goto err; + } else if (test == 1) { + /* Specified call back called - return error*/ + cb_ret = -1; + ptr = PKCS12_create_ex2(NULL, NULL, NULL, + cert, NULL, NID_undef, NID_undef, + 0, 0, 0, + NULL, NULL, + pkcs12_create_cb, (void*)&cb_ret); + /* PKCS12 not created */ + if (TEST_ptr(ptr)) + goto err; + } else if (test == 2) { + /* Specified call back called - return failure */ + cb_ret = 0; + ptr = PKCS12_create_ex2(NULL, NULL, NULL, + cert, NULL, NID_undef, NID_undef, + 0, 0, 0, + NULL, NULL, + pkcs12_create_cb, (void*)&cb_ret); + /* PKCS12 successfully created */ + if (!TEST_ptr(ptr)) + goto err; + } + + ret = 1; +err: + PKCS12_free(p12); + PKCS12_free(ptr); + EVP_PKEY_free(key); + X509_free(cert); + OSSL_STACK_OF_X509_free(ca); + return TEST_true(ret); +} + typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, @@ -157,7 +249,7 @@ int setup_tests(void) ADD_TEST(test_null_args); ADD_TEST(pkcs12_parse_test); - + ADD_ALL_TESTS(pkcs12_create_ex2_test, 3); return 1; } diff --git a/test/pkcs12_format_test.c b/test/pkcs12_format_test.c index ff2c5c0ac30..bfb4ac058c5 100644 --- a/test/pkcs12_format_test.c +++ b/test/pkcs12_format_test.c @@ -205,6 +205,19 @@ static const PKCS12_ATTR ATTRS2[] = { { NULL, NULL } }; +static const PKCS12_ATTR ATTRS3[] = { + { "friendlyName", "wildduk" }, + { "localKeyID", "1122334455" }, + { "oracle-jdk-trustedkeyusage", "anyExtendedKeyUsage" }, + { NULL, NULL } +}; + +static const PKCS12_ATTR ATTRS4[] = { + { "friendlyName", "wildduk" }, + { "localKeyID", "1122334455" }, + { NULL, NULL } +}; + static const PKCS12_ENC enc_default = { #ifndef OPENSSL_NO_DES NID_pbe_WithSHA1And3_Key_TripleDES_CBC, @@ -708,6 +721,84 @@ static int test_multiple_contents(void) return end_pkcs12_builder(pb); } +static int test_jdk_trusted_attr(void) +{ + PKCS12_BUILDER *pb = new_pkcs12_builder("jdk_trusted.p12"); + + /* Generate/encode */ + start_pkcs12(pb); + + start_contentinfo(pb); + + add_certbag(pb, CERT1, sizeof(CERT1), ATTRS3); + + end_contentinfo(pb); + + end_pkcs12_with_mac(pb, &mac_default); + + /* Read/decode */ + start_check_pkcs12_with_mac(pb, &mac_default); + + start_check_contentinfo(pb); + + check_certbag(pb, CERT1, sizeof(CERT1), ATTRS3); + + end_check_contentinfo(pb); + + end_check_pkcs12(pb); + + return end_pkcs12_builder(pb); +} + +static int test_set0_attrs(void) +{ + PKCS12_BUILDER *pb = new_pkcs12_builder("attrs.p12"); + PKCS12_SAFEBAG *bag = NULL; + STACK_OF(X509_ATTRIBUTE) *attrs = NULL; + X509_ATTRIBUTE *attr = NULL; + + start_pkcs12(pb); + + start_contentinfo(pb); + + /* Add cert and attrs (name/locakkey only) */ + add_certbag(pb, CERT1, sizeof(CERT1), ATTRS4); + + bag = sk_PKCS12_SAFEBAG_value(pb->bags, 0); + attrs = (STACK_OF(X509_ATTRIBUTE)*)PKCS12_SAFEBAG_get0_attrs(bag); + + /* Create new attr, add to list and confirm return attrs is not NULL */ + attr = X509_ATTRIBUTE_create(NID_oracle_jdk_trustedkeyusage, V_ASN1_OBJECT, OBJ_txt2obj("anyExtendedKeyUsage", 0)); + X509at_add1_attr(&attrs, attr); + PKCS12_SAFEBAG_set0_attrs(bag, attrs); + attrs = (STACK_OF(X509_ATTRIBUTE)*)PKCS12_SAFEBAG_get0_attrs(bag); + X509_ATTRIBUTE_free(attr); + if(!TEST_ptr(attrs)) { + goto err; + } + + end_contentinfo(pb); + + end_pkcs12(pb); + + /* Read/decode */ + start_check_pkcs12(pb); + + start_check_contentinfo(pb); + + /* Use existing check functionality to confirm cert bag attrs identical to ATTRS3 */ + check_certbag(pb, CERT1, sizeof(CERT1), ATTRS3); + + end_check_contentinfo(pb); + + end_check_pkcs12(pb); + + return end_pkcs12_builder(pb); + +err: + return 0; +} + #ifndef OPENSSL_NO_DES static int pkcs12_create_test(void) { @@ -883,6 +974,8 @@ int setup_tests(void) ADD_TEST(test_cert_key_encrypted_content); ADD_TEST(test_single_secret_encrypted_content); ADD_TEST(test_multiple_contents); + ADD_TEST(test_jdk_trusted_attr); + ADD_TEST(test_set0_attrs); return 1; } diff --git a/test/recipes/80-test_pkcs12.t b/test/recipes/80-test_pkcs12.t index cb855e2bf00..06a90ec24b3 100644 --- a/test/recipes/80-test_pkcs12.t +++ b/test/recipes/80-test_pkcs12.t @@ -54,7 +54,7 @@ if (eval { require Win32::API; 1; }) { } $ENV{OPENSSL_WIN32_UTF8}=1; -plan tests => 21; +plan tests => 24; # Test different PKCS#12 formats ok(run(test(["pkcs12_format_test"])), "test pkcs12 formats"); @@ -81,6 +81,7 @@ my $outfile3 = "out3.p12"; my $outfile4 = "out4.p12"; my $outfile5 = "out5.p12"; my $outfile6 = "out6.p12"; +my $outfile7 = "out7.p12"; # Test the -chain option with -untrusted ok(run(app(["openssl", "pkcs12", "-export", "-chain", @@ -146,9 +147,14 @@ my @pkcs12info = run(app(["openssl", "pkcs12", "-info", "-in", $outfile5, # Test that with one input certificate, we get one output certificate ok(grep(/subject=CN\s*=\s*server.example/, @pkcs12info) == 1, "test one cert in output"); + # Test that the expected friendly name is present in the output ok(grep(/testname/, @pkcs12info) == 1, "test friendly name in output"); +# Test there's no Oracle Trusted Key Usage bag attribute +ok(grep(/Trusted key usage (Oracle)/, @pkcs12info) == 0, + "test no oracle trusted key usage"); + # Test export of PEM file with both cert and key, without password. # -nomac necessary to avoid legacy provider requirement { @@ -164,6 +170,22 @@ ok(grep(/testname/, @pkcs12info) == 1, "test friendly name in output"); ok(scalar @match > 0 ? 0 : 1, "test_export_pkcs12_outerr6_empty"); } +# Test with Oracle Trusted Key Usage specified in openssl.cnf +{ + $ENV{OPENSSL_CONF} = srctop_file("test", "recipes", "80-test_pkcs12_data", "jdk_trusted.cnf"); + ok(run(app(["openssl", "pkcs12", "-export", "-out", $outfile7, + "-in", srctop_file(@path, "ee-cert.pem"), + "-nokeys", "-passout", "pass:", "-certpbe", "NONE"])), + "test nokeys single cert"); + + my @pkcs12info = run(app(["openssl", "pkcs12", "-info", "-in", $outfile7, + "-passin", "pass:"]), capture => 1); + ok(grep(/Trusted key usage \(Oracle\): Any Extended Key Usage \(2.5.29.37.0\)/, @pkcs12info) == 1, + "test oracle trusted key usage is set"); + + delete $ENV{OPENSSL_CONF} +} + # Tests for pkcs12_parse ok(run(test(["pkcs12_api_test", "-in", $outfile1, diff --git a/test/recipes/80-test_pkcs12_data/jdk_trusted.cnf b/test/recipes/80-test_pkcs12_data/jdk_trusted.cnf new file mode 100644 index 00000000000..57d11fccf2a --- /dev/null +++ b/test/recipes/80-test_pkcs12_data/jdk_trusted.cnf @@ -0,0 +1,8 @@ +# +[pkcs12] +certBagAttr = cb_attr + +# Uncomment this if you need Java compatible PKCS12 files +[cb_attr] +jdkTrustedKeyUsage = anyExtendedKeyUsage + diff --git a/util/libcrypto.num b/util/libcrypto.num index 5e6c85b6385..4c5cd7907d3 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5463,3 +5463,5 @@ BIO_s_dgram_pair ? 3_1_0 EXIST::FUNCTION:DGRAM BIO_new_bio_dgram_pair ? 3_1_0 EXIST::FUNCTION:DGRAM EVP_PKEY_auth_encapsulate_init ? 3_1_0 EXIST::FUNCTION: EVP_PKEY_auth_decapsulate_init ? 3_1_0 EXIST::FUNCTION: +PKCS12_SAFEBAG_set0_attrs ? 3_1_0 EXIST::FUNCTION: +PKCS12_create_ex2 ? 3_1_0 EXIST::FUNCTION: diff --git a/util/other.syms b/util/other.syms index 36ce26ee361..a35f6fd54a3 100644 --- a/util/other.syms +++ b/util/other.syms @@ -139,6 +139,7 @@ pem_password_cb datatype ssl_ct_validation_cb datatype ASYNC_stack_alloc_fn datatype ASYNC_stack_free_fn datatype +PKCS12_create_cb datatype # ASN1_BIT_STRING_digest define BIO_IS_ERRNO define