From ce2e7dc60e1f3dac02c5b652e14599cf86223498 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Wed, 7 Aug 2024 10:57:04 +0200 Subject: [PATCH] An interface to create PKCS #12 files in FIPS compliant way Resolves: RHEL-36659 --- 0124-PBMAC1-PKCS12-FIPS-support.patch | 1463 +++++++++++++++++++++++++ openssl.spec | 8 +- 2 files changed, 1470 insertions(+), 1 deletion(-) create mode 100644 0124-PBMAC1-PKCS12-FIPS-support.patch diff --git a/0124-PBMAC1-PKCS12-FIPS-support.patch b/0124-PBMAC1-PKCS12-FIPS-support.patch new file mode 100644 index 0000000..b8d4403 --- /dev/null +++ b/0124-PBMAC1-PKCS12-FIPS-support.patch @@ -0,0 +1,1463 @@ +From d959252c47af0eb0dd55bc032606901fedaf029b Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Fri, 7 Jun 2024 14:37:57 +0200 +Subject: [PATCH 1/4] Implementation of the RFC 9579, PBMAC1 in PKCS#12 + +--- + apps/pkcs12.c | 63 ++++++-- + crypto/asn1/p5_pbev2.c | 7 + + crypto/evp/digest.c | 54 +++++++ + crypto/pkcs12/p12_mutl.c | 296 ++++++++++++++++++++++++++++++++---- + include/crypto/evp.h | 3 + + include/openssl/pkcs12.h.in | 3 + + include/openssl/x509.h.in | 15 +- + 7 files changed, 394 insertions(+), 47 deletions(-) + +diff --git a/apps/pkcs12.c b/apps/pkcs12.c +index 54323a9713393..cbe133742a8be 100644 +--- a/apps/pkcs12.c ++++ b/apps/pkcs12.c +@@ -70,7 +70,7 @@ typedef enum OPTION_choice { + OPT_NAME, OPT_CSP, OPT_CANAME, + OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH, + OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE, +- OPT_R_ENUM, OPT_PROV_ENUM, OPT_JDKTRUST, ++ OPT_R_ENUM, OPT_PROV_ENUM, OPT_JDKTRUST, OPT_PBMAC1_PBKDF2, OPT_PBMAC1_PBKDF2_MD, + #ifndef OPENSSL_NO_DES + OPT_LEGACY_ALG + #endif +@@ -147,6 +147,8 @@ const OPTIONS pkcs12_options[] = { + #endif + {"macalg", OPT_MACALG, 's', + "Digest algorithm to use in MAC (default SHA256)"}, ++ {"pbmac1_pbkdf2", OPT_PBMAC1_PBKDF2, '-', "Use PBMAC1 with PBKDF2 instead of MAC"}, ++ {"pbmac1_pbkdf2_md", OPT_PBMAC1_PBKDF2_MD, 's', "Digest to use for PBMAC1 KDF (default SHA256)"}, + {"iter", OPT_ITER, 'p', "Specify the iteration count for encryption and MAC"}, + {"noiter", OPT_NOITER, '-', "Don't use encryption iteration"}, + {"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration)"}, +@@ -170,14 +172,14 @@ int pkcs12_main(int argc, char **argv) + int use_legacy = 0; + #endif + /* use library defaults for the iter, maciter, cert, and key PBE */ +- int iter = 0, maciter = 0; ++ int iter = 0, maciter = 0, pbmac1_pbkdf2 = 0; + int macsaltlen = PKCS12_SALT_LEN; + int cert_pbe = NID_undef; + int key_pbe = NID_undef; + int ret = 1, macver = 1, add_lmk = 0, private = 0; + int noprompt = 0; + char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL; +- char *passin = NULL, *passout = NULL, *macalg = NULL; ++ char *passin = NULL, *passout = NULL, *macalg = NULL, *pbmac1_pbkdf2_md = NULL; + char *cpass = NULL, *mpass = NULL, *badpass = NULL; + const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL, *prog; + int noCApath = 0, noCAfile = 0, noCAstore = 0; +@@ -283,6 +285,12 @@ int pkcs12_main(int argc, char **argv) + case OPT_MACALG: + macalg = opt_arg(); + break; ++ case OPT_PBMAC1_PBKDF2: ++ pbmac1_pbkdf2 = 1; ++ break; ++ case OPT_PBMAC1_PBKDF2_MD: ++ pbmac1_pbkdf2_md = opt_arg(); ++ break; + case OPT_CERTPBE: + if (!set_pbe(&cert_pbe, opt_arg())) + goto opthelp; +@@ -700,10 +708,20 @@ int pkcs12_main(int argc, char **argv) + } + + if (maciter != -1) { +- if (!PKCS12_set_mac(p12, mpass, -1, NULL, macsaltlen, maciter, macmd)) { +- BIO_printf(bio_err, "Error creating PKCS12 MAC; no PKCS12KDF support?\n"); +- BIO_printf(bio_err, "Use -nomac if MAC not required and PKCS12KDF support not available.\n"); +- goto export_end; ++ if (pbmac1_pbkdf2 == 1) { ++ if (!PKCS12_set_pbmac1_pbkdf2(p12, mpass, -1, NULL, ++ macsaltlen, maciter, ++ macmd, pbmac1_pbkdf2_md)) { ++ BIO_printf(bio_err, "Error creating PBMAC1\n"); ++ goto export_end; ++ } ++ } else { ++ if (!PKCS12_set_mac(p12, mpass, -1, NULL, macsaltlen, maciter, macmd)) { ++ BIO_printf(bio_err, "Error creating PKCS12 MAC; no PKCS12KDF support?\n"); ++ BIO_printf(bio_err, ++ "Use -nomac or -pbmac1_pbkdf2 if PKCS12KDF support not available\n"); ++ goto export_end; ++ } + } + } + assert(private); +@@ -774,11 +792,32 @@ int pkcs12_main(int argc, char **argv) + X509_ALGOR_get0(&macobj, NULL, NULL, macalgid); + BIO_puts(bio_err, "MAC: "); + i2a_ASN1_OBJECT(bio_err, macobj); +- BIO_printf(bio_err, ", Iteration %ld\n", +- tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L); +- BIO_printf(bio_err, "MAC length: %ld, salt length: %ld\n", +- tmac != NULL ? ASN1_STRING_length(tmac) : 0L, +- tsalt != NULL ? ASN1_STRING_length(tsalt) : 0L); ++ if (OBJ_obj2nid(macobj) == NID_pbmac1) { ++ PBKDF2PARAM *pbkdf2_param = PBMAC1_get1_pbkdf2_param(macalgid); ++ ++ if (pbkdf2_param == NULL) { ++ BIO_printf(bio_err, ", Unsupported KDF or params for PBMAC1\n"); ++ } else { ++ const ASN1_OBJECT *prfobj; ++ ++ BIO_printf(bio_err, " using PBKDF2, Iteration %ld\n", ++ ASN1_INTEGER_get(pbkdf2_param->iter)); ++ BIO_printf(bio_err, "Key length: %ld, Salt length: %d\n", ++ ASN1_INTEGER_get(pbkdf2_param->keylength), ++ ASN1_STRING_length(pbkdf2_param->salt->value.octet_string)); ++ X509_ALGOR_get0(&prfobj, NULL, NULL, pbkdf2_param->prf); ++ BIO_printf(bio_err, "PBKDF2 PRF: "); ++ i2a_ASN1_OBJECT(bio_err, prfobj); ++ BIO_printf(bio_err, "\n"); ++ } ++ PBKDF2PARAM_free(pbkdf2_param); ++ } else { ++ BIO_printf(bio_err, ", Iteration %ld\n", ++ tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L); ++ BIO_printf(bio_err, "MAC length: %ld, salt length: %ld\n", ++ tmac != NULL ? ASN1_STRING_length(tmac) : 0L, ++ tsalt != NULL ? ASN1_STRING_length(tsalt) : 0L); ++ } + } + if (macver) { + EVP_KDF *pkcs12kdf; +diff --git a/crypto/asn1/p5_pbev2.c b/crypto/asn1/p5_pbev2.c +index 8575d05bf6d5a..c22cc6b77075d 100644 +--- a/crypto/asn1/p5_pbev2.c ++++ b/crypto/asn1/p5_pbev2.c +@@ -35,6 +35,13 @@ ASN1_SEQUENCE(PBKDF2PARAM) = { + + IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM) + ++ASN1_SEQUENCE(PBMAC1PARAM) = { ++ ASN1_SIMPLE(PBMAC1PARAM, keyDerivationFunc, X509_ALGOR), ++ ASN1_SIMPLE(PBMAC1PARAM, messageAuthScheme, X509_ALGOR) ++} ASN1_SEQUENCE_END(PBMAC1PARAM) ++ ++IMPLEMENT_ASN1_FUNCTIONS(PBMAC1PARAM) ++ + /* + * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know + * this is horrible! Extended version to allow application supplied PRF NID +diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c +index 18a64329b7a35..a74e2fa42c5bb 100644 +--- a/crypto/evp/digest.c ++++ b/crypto/evp/digest.c +@@ -20,6 +20,7 @@ + #include + #include + #include "internal/cryptlib.h" ++#include "internal/nelem.h" + #include "internal/provider.h" + #include "internal/core.h" + #include "crypto/evp.h" +@@ -1185,3 +1186,56 @@ void EVP_MD_do_all_provided(OSSL_LIB_CTX *libctx, + (void (*)(void *, void *))fn, arg, + evp_md_from_algorithm, evp_md_up_ref, evp_md_free); + } ++ ++typedef struct { ++ int md_nid; ++ int hmac_nid; ++} ossl_hmacmd_pair; ++ ++static const ossl_hmacmd_pair ossl_hmacmd_pairs[] = { ++ {NID_sha1, NID_hmacWithSHA1}, ++ {NID_md5, NID_hmacWithMD5}, ++ {NID_sha224, NID_hmacWithSHA224}, ++ {NID_sha256, NID_hmacWithSHA256}, ++ {NID_sha384, NID_hmacWithSHA384}, ++ {NID_sha512, NID_hmacWithSHA512}, ++ {NID_id_GostR3411_94, NID_id_HMACGostR3411_94}, ++ {NID_id_GostR3411_2012_256, NID_id_tc26_hmac_gost_3411_2012_256}, ++ {NID_id_GostR3411_2012_512, NID_id_tc26_hmac_gost_3411_2012_512}, ++ {NID_sha3_224, NID_hmac_sha3_224}, ++ {NID_sha3_256, NID_hmac_sha3_256}, ++ {NID_sha3_384, NID_hmac_sha3_384}, ++ {NID_sha3_512, NID_hmac_sha3_512}, ++ {NID_sha512_224, NID_hmacWithSHA512_224}, ++ {NID_sha512_256, NID_hmacWithSHA512_256} ++}; ++ ++int ossl_hmac2mdnid(int hmac_nid) ++{ ++ int md_nid = NID_undef; ++ size_t i; ++ ++ for (i = 0; i < OSSL_NELEM(ossl_hmacmd_pairs); i++) { ++ if (ossl_hmacmd_pairs[i].hmac_nid == hmac_nid) { ++ md_nid = ossl_hmacmd_pairs[i].md_nid; ++ break; ++ } ++ } ++ ++ return md_nid; ++} ++ ++int ossl_md2hmacnid(int md_nid) ++{ ++ int hmac_nid = NID_undef; ++ size_t i; ++ ++ for (i = 0; i < OSSL_NELEM(ossl_hmacmd_pairs); i++) { ++ if (ossl_hmacmd_pairs[i].md_nid == md_nid) { ++ hmac_nid = ossl_hmacmd_pairs[i].hmac_nid; ++ break; ++ } ++ } ++ ++ return hmac_nid; ++} +diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c +index 4091e61d9dd06..d410978a49e1e 100644 +--- a/crypto/pkcs12/p12_mutl.c ++++ b/crypto/pkcs12/p12_mutl.c +@@ -15,12 +15,19 @@ + + #include + #include "internal/cryptlib.h" ++#include "crypto/evp.h" + #include + #include + #include + #include + #include "p12_local.h" + ++static int pkcs12_pbmac1_pbkdf2_key_gen(const char *pass, int passlen, ++ unsigned char *salt, int saltlen, ++ int id, int iter, int keylen, ++ unsigned char *out, ++ const EVP_MD *md_type); ++ + int PKCS12_mac_present(const PKCS12 *p12) + { + return p12->mac ? 1 : 0; +@@ -72,9 +79,76 @@ static int pkcs12_gen_gost_mac_key(const char *pass, int passlen, + return 1; + } + +-/* Generate a MAC */ ++PBKDF2PARAM *PBMAC1_get1_pbkdf2_param(const X509_ALGOR *macalg) ++{ ++ PBMAC1PARAM *param = NULL; ++ PBKDF2PARAM *pbkdf2_param = NULL; ++ const ASN1_OBJECT *kdf_oid; ++ ++ param = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBMAC1PARAM), macalg->parameter); ++ if (param == NULL) { ++ ERR_raise(ERR_LIB_PKCS12, ERR_R_PASSED_INVALID_ARGUMENT); ++ return NULL; ++ } ++ ++ X509_ALGOR_get0(&kdf_oid, NULL, NULL, param->keyDerivationFunc); ++ if (OBJ_obj2nid(kdf_oid) != NID_id_pbkdf2) { ++ ERR_raise(ERR_LIB_PKCS12, ERR_R_PASSED_INVALID_ARGUMENT); ++ PBMAC1PARAM_free(param); ++ return NULL; ++ } ++ ++ pbkdf2_param = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), ++ param->keyDerivationFunc->parameter); ++ PBMAC1PARAM_free(param); ++ ++ return pbkdf2_param; ++} ++ ++static int PBMAC1_PBKDF2_HMAC(OSSL_LIB_CTX *ctx, const char *propq, ++ const char *pass, int passlen, ++ const X509_ALGOR *macalg, unsigned char *key) ++{ ++ PBKDF2PARAM *pbkdf2_param = NULL; ++ const ASN1_OBJECT *kdf_hmac_oid; ++ int ret = -1; ++ int keylen = 0; ++ EVP_MD *kdf_md = NULL; ++ const ASN1_OCTET_STRING *pbkdf2_salt = NULL; ++ ++ pbkdf2_param = PBMAC1_get1_pbkdf2_param(macalg); ++ if (pbkdf2_param == NULL) { ++ ERR_raise(ERR_LIB_PKCS12, ERR_R_UNSUPPORTED); ++ goto err; ++ } ++ keylen = ASN1_INTEGER_get(pbkdf2_param->keylength); ++ pbkdf2_salt = pbkdf2_param->salt->value.octet_string; ++ X509_ALGOR_get0(&kdf_hmac_oid, NULL, NULL, pbkdf2_param->prf); ++ ++ kdf_md = EVP_MD_fetch(ctx, OBJ_nid2sn(ossl_hmac2mdnid(OBJ_obj2nid(kdf_hmac_oid))), propq); ++ if (kdf_md == NULL) { ++ ERR_raise(ERR_LIB_PKCS12, ERR_R_FETCH_FAILED); ++ goto err; ++ } ++ ++ if (PKCS5_PBKDF2_HMAC(pass, passlen, pbkdf2_salt->data, pbkdf2_salt->length, ++ ASN1_INTEGER_get(pbkdf2_param->iter), kdf_md, keylen, key) <= 0) { ++ ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ret = keylen; ++ ++ err: ++ EVP_MD_free(kdf_md); ++ PBKDF2PARAM_free(pbkdf2_param); ++ ++ return ret; ++} ++ ++/* Generate a MAC, also used for verification */ + static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen, ++ int pbmac1_md_nid, int pbmac1_kdf_nid, + int (*pkcs12_key_gen)(const char *pass, int passlen, + unsigned char *salt, int slen, + int id, int iter, int n, +@@ -88,8 +162,8 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char key[EVP_MAX_MD_SIZE], *salt; + int saltlen, iter; + char md_name[80]; +- int md_size = 0; +- int md_nid; ++ int keylen = 0; ++ int md_nid = NID_undef; + const X509_ALGOR *macalg; + const ASN1_OBJECT *macoid; + +@@ -111,9 +185,13 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + iter = ASN1_INTEGER_get(p12->mac->iter); + X509_SIG_get0(p12->mac->dinfo, &macalg, NULL); + X509_ALGOR_get0(&macoid, NULL, NULL, macalg); +- if (OBJ_obj2txt(md_name, sizeof(md_name), macoid, 0) < 0) +- return 0; +- ++ if (OBJ_obj2nid(macoid) == NID_pbmac1) { ++ if (OBJ_obj2txt(md_name, sizeof(md_name), OBJ_nid2obj(pbmac1_md_nid), 0) < 0) ++ return 0; ++ } else { ++ if (OBJ_obj2txt(md_name, sizeof(md_name), macoid, 0) < 0) ++ return 0; ++ } + (void)ERR_set_mark(); + md = md_fetch = EVP_MD_fetch(p12->authsafes->ctx.libctx, md_name, + p12->authsafes->ctx.propq); +@@ -127,40 +205,61 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + } + (void)ERR_pop_to_mark(); + +- md_size = EVP_MD_get_size(md); ++ keylen = EVP_MD_get_size(md); + md_nid = EVP_MD_get_type(md); +- if (md_size < 0) ++ if (keylen < 0) + goto err; +- if ((md_nid == NID_id_GostR3411_94 +- || md_nid == NID_id_GostR3411_2012_256 +- || md_nid == NID_id_GostR3411_2012_512) +- && ossl_safe_getenv("LEGACY_GOST_PKCS12") == NULL) { +- md_size = TK26_MAC_KEY_LEN; ++ ++ /* For PBMAC1 we use a special keygen callback if not provided (e.g. on verification) */ ++ if (pbmac1_md_nid != NID_undef && pkcs12_key_gen == NULL) { ++ keylen = PBMAC1_PBKDF2_HMAC(p12->authsafes->ctx.libctx, p12->authsafes->ctx.propq, ++ pass, passlen, macalg, key); ++ if (keylen < 0) ++ goto err; ++ } else if ((md_nid == NID_id_GostR3411_94 ++ || md_nid == NID_id_GostR3411_2012_256 ++ || md_nid == NID_id_GostR3411_2012_512) ++ && ossl_safe_getenv("LEGACY_GOST_PKCS12") == NULL) { ++ keylen = TK26_MAC_KEY_LEN; + if (!pkcs12_gen_gost_mac_key(pass, passlen, salt, saltlen, iter, +- md_size, key, md)) { ++ keylen, key, md)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); + goto err; + } + } else { ++ EVP_MD *hmac_md = (EVP_MD *)md; ++ int fetched = 0; ++ ++ if (pbmac1_kdf_nid != NID_undef) { ++ char hmac_md_name[128]; ++ ++ if (OBJ_obj2txt(hmac_md_name, sizeof(hmac_md_name), OBJ_nid2obj(pbmac1_kdf_nid), 0) < 0) ++ goto err; ++ hmac_md = EVP_MD_fetch(NULL, hmac_md_name, NULL); ++ fetched = 1; ++ } + if (pkcs12_key_gen != NULL) { +- if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID, +- iter, md_size, key, md)) { ++ int res = (*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID, ++ iter, keylen, key, hmac_md); ++ ++ if (fetched) ++ EVP_MD_free(hmac_md); ++ if (res != 1) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); + goto err; + } + } else { + /* Default to UTF-8 password */ + if (!PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, PKCS12_MAC_ID, +- iter, md_size, key, md, +- p12->authsafes->ctx.libctx, +- p12->authsafes->ctx.propq)) { ++ iter, keylen, key, md, ++ p12->authsafes->ctx.libctx, p12->authsafes->ctx.propq)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); + goto err; + } + } + } + if ((hmac = HMAC_CTX_new()) == NULL +- || !HMAC_Init_ex(hmac, key, md_size, md, NULL) ++ || !HMAC_Init_ex(hmac, key, keylen, md, NULL) + || !HMAC_Update(hmac, p12->authsafes->d.data->data, + p12->authsafes->d.data->length) + || !HMAC_Final(hmac, mac, maclen)) { +@@ -178,7 +277,7 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen) + { +- return pkcs12_gen_mac(p12, pass, passlen, mac, maclen, NULL); ++ return pkcs12_gen_mac(p12, pass, passlen, mac, maclen, NID_undef, NID_undef, NULL); + } + + /* Verify the mac */ +@@ -187,14 +286,40 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + const ASN1_OCTET_STRING *macoct; ++ const X509_ALGOR *macalg; ++ const ASN1_OBJECT *macoid; + + if (p12->mac == NULL) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_ABSENT); + return 0; + } +- if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NULL)) { +- ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); +- return 0; ++ ++ X509_SIG_get0(p12->mac->dinfo, &macalg, NULL); ++ X509_ALGOR_get0(&macoid, NULL, NULL, macalg); ++ if (OBJ_obj2nid(macoid) == NID_pbmac1) { ++ PBMAC1PARAM *param = NULL; ++ const ASN1_OBJECT *hmac_oid; ++ int md_nid = NID_undef; ++ ++ param = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBMAC1PARAM), macalg->parameter); ++ if (param == NULL) { ++ ERR_raise(ERR_LIB_PKCS12, ERR_R_UNSUPPORTED); ++ return 0; ++ } ++ X509_ALGOR_get0(&hmac_oid, NULL, NULL, param->messageAuthScheme); ++ md_nid = ossl_hmac2mdnid(OBJ_obj2nid(hmac_oid)); ++ ++ if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, md_nid, NID_undef, NULL)) { ++ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); ++ PBMAC1PARAM_free(param); ++ return 0; ++ } ++ PBMAC1PARAM_free(param); ++ } else { ++ if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NID_undef, NID_undef, NULL)) { ++ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); ++ return 0; ++ } + } + X509_SIG_get0(p12->mac->dinfo, NULL, &macoct); + if ((maclen != (unsigned int)ASN1_STRING_length(macoct)) +@@ -205,7 +330,6 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) + } + + /* Set a mac */ +- + int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type) +@@ -226,7 +350,7 @@ int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + /* + * Note that output mac is forced to UTF-8... + */ +- if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NULL)) { ++ if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NID_undef, NID_undef, NULL)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); + return 0; + } +@@ -238,9 +362,18 @@ int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + return 1; + } + +-/* Set up a mac structure */ +-int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, +- const EVP_MD *md_type) ++static int pkcs12_pbmac1_pbkdf2_key_gen(const char *pass, int passlen, ++ unsigned char *salt, int saltlen, ++ int id, int iter, int keylen, ++ unsigned char *out, ++ const EVP_MD *md_type) ++{ ++ return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, ++ md_type, keylen, out); ++} ++ ++static int pkcs12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, ++ int nid) + { + X509_ALGOR *macalg; + +@@ -274,11 +407,112 @@ int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, + memcpy(p12->mac->salt->data, salt, saltlen); + } + X509_SIG_getm(p12->mac->dinfo, &macalg, NULL); +- if (!X509_ALGOR_set0(macalg, OBJ_nid2obj(EVP_MD_get_type(md_type)), +- V_ASN1_NULL, NULL)) { ++ if (!X509_ALGOR_set0(macalg, OBJ_nid2obj(nid), V_ASN1_NULL, NULL)) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); + return 0; + } + + return 1; + } ++ ++/* Set up a mac structure */ ++int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, ++ const EVP_MD *md_type) ++{ ++ return pkcs12_setup_mac(p12, iter, salt, saltlen, EVP_MD_get_type(md_type)); ++} ++ ++int PKCS12_set_pbmac1_pbkdf2(PKCS12 *p12, const char *pass, int passlen, ++ unsigned char *salt, int saltlen, int iter, ++ const EVP_MD *md_type, const char *prf_md_name) ++{ ++ unsigned char mac[EVP_MAX_MD_SIZE]; ++ unsigned int maclen; ++ ASN1_OCTET_STRING *macoct; ++ X509_ALGOR *alg = NULL; ++ int ret = 0; ++ int prf_md_nid = NID_undef, prf_nid = NID_undef, hmac_nid; ++ unsigned char *known_salt = NULL; ++ int keylen = 0; ++ PBMAC1PARAM *param = NULL; ++ X509_ALGOR *hmac_alg = NULL, *macalg = NULL; ++ ++ if (md_type == NULL) ++ /* No need to do a fetch as the md_type is used only to get a NID */ ++ md_type = EVP_sha256(); ++ ++ if (prf_md_name == NULL) ++ prf_md_nid = EVP_MD_get_type(md_type); ++ else ++ prf_md_nid = OBJ_txt2nid(prf_md_name); ++ ++ if (iter == 0) ++ iter = PKCS12_DEFAULT_ITER; ++ ++ keylen = EVP_MD_get_size(md_type); ++ ++ prf_nid = ossl_md2hmacnid(prf_md_nid); ++ hmac_nid = ossl_md2hmacnid(EVP_MD_get_type(md_type)); ++ ++ if (prf_nid == NID_undef || hmac_nid == NID_undef) { ++ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); ++ goto err; ++ } ++ ++ if (salt == NULL) { ++ known_salt = OPENSSL_malloc(saltlen); ++ if (known_salt == NULL) ++ goto err; ++ ++ if (RAND_bytes_ex(NULL, known_salt, saltlen, 0) <= 0) { ++ ERR_raise(ERR_LIB_PKCS12, ERR_R_RAND_LIB); ++ goto err; ++ } ++ } ++ ++ param = PBMAC1PARAM_new(); ++ hmac_alg = X509_ALGOR_new(); ++ alg = PKCS5_pbkdf2_set(iter, salt ? salt : known_salt, saltlen, prf_nid, keylen); ++ if (param == NULL || hmac_alg == NULL || alg == NULL) ++ goto err; ++ ++ if (pkcs12_setup_mac(p12, iter, salt ? salt : known_salt, saltlen, ++ NID_pbmac1) == PKCS12_ERROR) { ++ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_SETUP_ERROR); ++ goto err; ++ } ++ ++ if (!X509_ALGOR_set0(hmac_alg, OBJ_nid2obj(hmac_nid), V_ASN1_NULL, NULL)) { ++ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_SETUP_ERROR); ++ goto err; ++ } ++ ++ X509_ALGOR_free(param->keyDerivationFunc); ++ X509_ALGOR_free(param->messageAuthScheme); ++ param->keyDerivationFunc = alg; ++ param->messageAuthScheme = hmac_alg; ++ ++ X509_SIG_getm(p12->mac->dinfo, &macalg, &macoct); ++ if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBMAC1PARAM), param, &macalg->parameter)) ++ goto err; ++ ++ /* ++ * Note that output mac is forced to UTF-8... ++ */ ++ if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, ++ EVP_MD_get_type(md_type), prf_md_nid, ++ pkcs12_pbmac1_pbkdf2_key_gen)) { ++ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); ++ goto err; ++ } ++ if (!ASN1_OCTET_STRING_set(macoct, mac, maclen)) { ++ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_STRING_SET_ERROR); ++ goto err; ++ } ++ ret = 1; ++ ++ err: ++ PBMAC1PARAM_free(param); ++ OPENSSL_free(known_salt); ++ return ret; ++} +diff --git a/include/crypto/evp.h b/include/crypto/evp.h +index 32c60f223c78c..72d9995e8f0f4 100644 +--- a/include/crypto/evp.h ++++ b/include/crypto/evp.h +@@ -964,4 +964,7 @@ int evp_pkey_decrypt_alloc(EVP_PKEY_CTX *ctx, unsigned char **outp, + size_t *outlenp, size_t expected_outlen, + const unsigned char *in, size_t inlen); + ++int ossl_md2hmacnid(int mdnid); ++int ossl_hmac2mdnid(int hmac_nid); ++ + #endif /* OSSL_CRYPTO_EVP_H */ +diff --git a/include/openssl/pkcs12.h.in b/include/openssl/pkcs12.h.in +index 35759d4deadc3..ab62207e49b55 100644 +--- a/include/openssl/pkcs12.h.in ++++ b/include/openssl/pkcs12.h.in +@@ -269,6 +269,9 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); + int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type); ++int PKCS12_set_pbmac1_pbkdf2(PKCS12 *p12, const char *pass, int passlen, ++ unsigned char *salt, int saltlen, int iter, ++ const EVP_MD *md_type, const char *prf_md_name); + int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, + int saltlen, const EVP_MD *md_type); + unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, +diff --git a/include/openssl/x509.h.in b/include/openssl/x509.h.in +index 99bc4aab29133..b7f080a5360db 100644 +--- a/include/openssl/x509.h.in ++++ b/include/openssl/x509.h.in +@@ -279,7 +279,12 @@ typedef struct PBKDF2PARAM_st { + X509_ALGOR *prf; + } PBKDF2PARAM; + +-#ifndef OPENSSL_NO_SCRYPT ++typedef struct { ++ X509_ALGOR *keyDerivationFunc; ++ X509_ALGOR *messageAuthScheme; ++} PBMAC1PARAM; ++ ++# ifndef OPENSSL_NO_SCRYPT + typedef struct SCRYPT_PARAMS_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *costParameter; +@@ -287,7 +292,7 @@ typedef struct SCRYPT_PARAMS_st { + ASN1_INTEGER *parallelizationParameter; + ASN1_INTEGER *keyLength; + } SCRYPT_PARAMS; +-#endif ++# endif + + #ifdef __cplusplus + } +@@ -1023,9 +1028,10 @@ X509 *X509_find_by_subject(STACK_OF(X509) *sk, const X509_NAME *name); + DECLARE_ASN1_FUNCTIONS(PBEPARAM) + DECLARE_ASN1_FUNCTIONS(PBE2PARAM) + DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) +-#ifndef OPENSSL_NO_SCRYPT ++DECLARE_ASN1_FUNCTIONS(PBMAC1PARAM) ++# ifndef OPENSSL_NO_SCRYPT + DECLARE_ASN1_FUNCTIONS(SCRYPT_PARAMS) +-#endif ++# endif + + int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); +@@ -1062,6 +1068,7 @@ X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen, + OSSL_LIB_CTX *libctx); + ++PBKDF2PARAM *PBMAC1_get1_pbkdf2_param(const X509_ALGOR *macalg); + /* PKCS#8 utilities */ + + DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +From 29d98a8287d217b2232344056934d3cd2c6f44a3 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Fri, 7 Jun 2024 14:38:40 +0200 +Subject: [PATCH 2/4] Implementation of the RFC 9579, PBMAC1 in PKCS#12 - + documentation + +--- + doc/man1/openssl-pkcs12.pod.in | 11 +++++++ + doc/man3/PBMAC1_get1_pbkdf2_param.pod | 46 +++++++++++++++++++++++++++ + doc/man3/PKCS12_gen_mac.pod | 37 ++++++++++++++++----- + doc/man3/X509_dup.pod | 3 ++ + doc/man3/d2i_X509.pod | 2 ++ + util/missingcrypto.txt | 1 - + util/missingcrypto111.txt | 1 - + 7 files changed, 91 insertions(+), 10 deletions(-) + create mode 100644 doc/man3/PBMAC1_get1_pbkdf2_param.pod + +diff --git a/doc/man1/openssl-pkcs12.pod.in b/doc/man1/openssl-pkcs12.pod.in +index 665b22bb644ac..020543cd5c895 100644 +--- a/doc/man1/openssl-pkcs12.pod.in ++++ b/doc/man1/openssl-pkcs12.pod.in +@@ -62,6 +62,8 @@ PKCS#12 output (export) options: + [B<-certpbe> I] + [B<-descert>] + [B<-macalg> I] ++[B<-pbmac1_pbkdf2>] ++[B<-pbmac1_pbkdf2_md> I] + [B<-iter> I] + [B<-noiter>] + [B<-nomaciter>] +@@ -345,6 +347,15 @@ then both, the private key and the certificates are encrypted using triple DES. + + Specify the MAC digest algorithm. If not included SHA256 will be used. + ++=item B<-pbmac1_pbkdf2> ++ ++Use PBMAC1 with PBKDF2 for MAC protection of the PKCS#12 file. ++ ++=item B<-pbmac1_pbkdf2_md> I ++ ++Specify the PBKDF2 KDF digest algorithm. If not specified, SHA256 will be used. ++Unless C<-pbmac1_pbkdf2> is specified, this parameter is ignored. ++ + =item B<-iter> I + + This option specifies the iteration count for the encryption key and MAC. The +diff --git a/doc/man3/PBMAC1_get1_pbkdf2_param.pod b/doc/man3/PBMAC1_get1_pbkdf2_param.pod +new file mode 100644 +index 0000000000000..415c3cd214a2e +--- /dev/null ++++ b/doc/man3/PBMAC1_get1_pbkdf2_param.pod +@@ -0,0 +1,46 @@ ++=pod ++ ++=head1 NAME ++ ++PBMAC1_get1_pbkdf2_param - Function to manipulate a PBMAC1 ++MAC structure ++ ++=head1 SYNOPSIS ++ ++ #include ++ ++ PBKDF2PARAM *PBMAC1_get1_pbkdf2_param(const X509_ALGOR *macalg); ++ ++=head1 DESCRIPTION ++ ++PBMAC1_get1_pbkdf2_param() retrieves a B structure from an ++I structure. ++ ++=head1 RETURN VALUES ++ ++PBMAC1_get1_pbkdf2_param() returns NULL in case when PBMAC1 uses an algorithm ++apart from B or when passed incorrect parameters and a pointer to ++B structure otherwise. ++ ++=head1 CONFORMING TO ++ ++IETF RFC 9579 (L) ++ ++=head1 SEE ALSO ++ ++L ++ ++=head1 HISTORY ++ ++The I function was added in OpenSSL 3.4. ++ ++=head1 COPYRIGHT ++ ++Copyright 2021-2024 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_gen_mac.pod b/doc/man3/PKCS12_gen_mac.pod +index a72df145fedd7..ebeee98f04e68 100644 +--- a/doc/man3/PKCS12_gen_mac.pod ++++ b/doc/man3/PKCS12_gen_mac.pod +@@ -3,7 +3,8 @@ + =head1 NAME + + PKCS12_gen_mac, PKCS12_setup_mac, PKCS12_set_mac, +-PKCS12_verify_mac - Functions to create and manipulate a PKCS#12 structure ++PKCS12_set_pbmac1_pbkdf2, PKCS12_verify_mac, PKCS12_get0_mac - ++Functions to create and manipulate a PKCS#12 MAC structure + + =head1 SYNOPSIS + +@@ -15,9 +16,19 @@ PKCS12_verify_mac - Functions to create and manipulate a PKCS#12 structure + int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type); ++ int PKCS12_set_pbmac1_pbkdf2(PKCS12 *p12, const char *pass, int passlen, ++ unsigned char *salt, int saltlen, int iter, ++ const EVP_MD *md_type, ++ const char *prf_md_name); + int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, + int saltlen, const EVP_MD *md_type); + ++ void PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac, ++ const X509_ALGOR **pmacalg, ++ const ASN1_OCTET_STRING **psalt, ++ const ASN1_INTEGER **piter, ++ const PKCS12 *p12); ++ + =head1 DESCRIPTION + + PKCS12_gen_mac() generates an HMAC over the entire PKCS#12 object using the +@@ -31,10 +42,15 @@ PKCS12_setup_mac() sets the MAC part of the PKCS#12 structure with the supplied + parameters. + + PKCS12_set_mac() sets the MAC and MAC parameters into the PKCS#12 object. ++PKCS12_set_pbmac1_pbkdf2() sets the MAC and MAC parameters into the PKCS#12 ++object when B with PBKDF2 is used for protection of the PKCS#12 object. + + I is the passphrase to use in the HMAC. I is the salt value to use, +-I is the iteration count and I is the message digest +-function to use. ++I is the iteration count and I is the message digest function to ++use. I specifies the digest used for the PBKDF2 in PBMAC1 KDF. ++ ++PKCS12_get0_mac() retrieves any included MAC value, B object, ++I, and I count from the PKCS12 object. + + =head1 NOTES + +@@ -43,17 +59,18 @@ If I is NULL then a suitable salt will be generated and used. + If I is 1 then an iteration count will be omitted from the PKCS#12 + structure. + +-PKCS12_gen_mac(), PKCS12_verify_mac() and PKCS12_set_mac() make assumptions +-regarding the encoding of the given passphrase. See L +-for more information. ++PKCS12_gen_mac(), PKCS12_verify_mac(), PKCS12_set_mac() and ++PKCS12_set_pbmac1_pbkdf2() make assumptions regarding the encoding of the ++given passphrase. See L for more information. + + =head1 RETURN VALUES + +-All functions return 1 on success and 0 if an error occurred. ++All functions returning an integer return 1 on success and 0 if an error occurred. + + =head1 CONFORMING TO + + IETF RFC 7292 (L) ++IETF RFC 9579 (L) + + =head1 SEE ALSO + +@@ -62,9 +79,13 @@ L, + L, + L + ++=head1 HISTORY ++ ++The I function was added in OpenSSL 3.4. ++ + =head1 COPYRIGHT + +-Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. ++Copyright 2021-2024 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/doc/man3/X509_dup.pod b/doc/man3/X509_dup.pod +index fc93494a76617..81ea2275d7414 100644 +--- a/doc/man3/X509_dup.pod ++++ b/doc/man3/X509_dup.pod +@@ -218,6 +218,9 @@ PBEPARAM_free, + PBEPARAM_new, + PBKDF2PARAM_free, + PBKDF2PARAM_new, ++PBMAC1PARAM_free, ++PBMAC1PARAM_it, ++PBMAC1PARAM_new, + PKCS12_BAGS_free, + PKCS12_BAGS_new, + PKCS12_MAC_DATA_free, +diff --git a/doc/man3/d2i_X509.pod b/doc/man3/d2i_X509.pod +index 75b37e5544396..3615bcaafe7c0 100644 +--- a/doc/man3/d2i_X509.pod ++++ b/doc/man3/d2i_X509.pod +@@ -115,6 +115,7 @@ d2i_OTHERNAME, + d2i_PBE2PARAM, + d2i_PBEPARAM, + d2i_PBKDF2PARAM, ++d2i_PBMAC1PARAM, + d2i_PKCS12, + d2i_PKCS12_BAGS, + d2i_PKCS12_MAC_DATA, +@@ -300,6 +301,7 @@ i2d_OTHERNAME, + i2d_PBE2PARAM, + i2d_PBEPARAM, + i2d_PBKDF2PARAM, ++i2d_PBMAC1PARAM, + i2d_PKCS12, + i2d_PKCS12_BAGS, + i2d_PKCS12_MAC_DATA, +diff --git a/util/missingcrypto.txt b/util/missingcrypto.txt +index b7d5091b31912..a56491d0f8b94 100644 +--- a/util/missingcrypto.txt ++++ b/util/missingcrypto.txt +@@ -749,7 +749,6 @@ PKCS12_MAC_DATA_it(3) + PKCS12_PBE_add(3) + PKCS12_SAFEBAGS_it(3) + PKCS12_SAFEBAG_it(3) +-PKCS12_get0_mac(3) + PKCS12_get_attr(3) + PKCS12_it(3) + PKCS12_item_pack_safebag(3) +diff --git a/util/missingcrypto111.txt b/util/missingcrypto111.txt +index 0386701ad1e32..f3402ada7e60f 100644 +--- a/util/missingcrypto111.txt ++++ b/util/missingcrypto111.txt +@@ -1027,7 +1027,6 @@ PKCS12_add_safe(3) + PKCS12_add_safes(3) + PKCS12_decrypt_skey(3) + PKCS12_gen_mac(3) +-PKCS12_get0_mac(3) + PKCS12_get_attr(3) + PKCS12_get_attr_gen(3) + PKCS12_get_friendlyname(3) + +From 7257898633703d5841aefa7fb4f9d192430fdad8 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Thu, 6 Jun 2024 13:07:48 +0200 +Subject: [PATCH 3/4] Make update + +--- + doc/build.info | 6 ++++++ + util/libcrypto.num | 7 +++++++ + 2 files changed, 13 insertions(+) + +diff --git a/doc/build.info b/doc/build.info +index d47371e88aa9f..60a5d9b86bd5c 100644 +--- a/doc/build.info ++++ b/doc/build.info +@@ -1847,6 +1847,10 @@ DEPEND[html/man3/OpenSSL_version.html]=man3/OpenSSL_version.pod + GENERATE[html/man3/OpenSSL_version.html]=man3/OpenSSL_version.pod + DEPEND[man/man3/OpenSSL_version.3]=man3/OpenSSL_version.pod + GENERATE[man/man3/OpenSSL_version.3]=man3/OpenSSL_version.pod ++DEPEND[html/man3/PBMAC1_get1_pbkdf2_param.html]=man3/PBMAC1_get1_pbkdf2_param.pod ++GENERATE[html/man3/PBMAC1_get1_pbkdf2_param.html]=man3/PBMAC1_get1_pbkdf2_param.pod ++DEPEND[man/man3/PBMAC1_get1_pbkdf2_param.3]=man3/PBMAC1_get1_pbkdf2_param.pod ++GENERATE[man/man3/PBMAC1_get1_pbkdf2_param.3]=man3/PBMAC1_get1_pbkdf2_param.pod + DEPEND[html/man3/PEM_X509_INFO_read_bio_ex.html]=man3/PEM_X509_INFO_read_bio_ex.pod + GENERATE[html/man3/PEM_X509_INFO_read_bio_ex.html]=man3/PEM_X509_INFO_read_bio_ex.pod + DEPEND[man/man3/PEM_X509_INFO_read_bio_ex.3]=man3/PEM_X509_INFO_read_bio_ex.pod +@@ -3453,6 +3457,7 @@ html/man3/OSSL_trace_get_category_num.html \ + html/man3/OSSL_trace_set_channel.html \ + html/man3/OpenSSL_add_all_algorithms.html \ + html/man3/OpenSSL_version.html \ ++html/man3/PBMAC1_get1_pbkdf2_param.html \ + html/man3/PEM_X509_INFO_read_bio_ex.html \ + html/man3/PEM_bytes_read_bio.html \ + html/man3/PEM_read.html \ +@@ -4113,6 +4118,7 @@ man/man3/OSSL_trace_get_category_num.3 \ + man/man3/OSSL_trace_set_channel.3 \ + man/man3/OpenSSL_add_all_algorithms.3 \ + man/man3/OpenSSL_version.3 \ ++man/man3/PBMAC1_get1_pbkdf2_param.3 \ + man/man3/PEM_X509_INFO_read_bio_ex.3 \ + man/man3/PEM_bytes_read_bio.3 \ + man/man3/PEM_read.3 \ +diff --git a/util/libcrypto.num b/util/libcrypto.num +index 7f958a4fa31db..ef11c0302e396 100644 +--- a/util/libcrypto.num ++++ b/util/libcrypto.num +@@ -5664,3 +5664,10 @@ OSSL_IETF_ATTR_SYNTAX_get_value_num ? 3_4_0 EXIST::FUNCTION: + OPENSSL_strncasecmp ? 3_0_1 EXIST::FUNCTION: + ossl_ctx_legacy_digest_signatures_allowed ? 3_0_1 EXIST::FUNCTION: + ossl_ctx_legacy_digest_signatures_allowed_set ? 3_0_1 EXIST::FUNCTION: ++PKCS12_set_pbmac1_pbkdf2 ? 3_4_0 EXIST::FUNCTION: ++PBMAC1_get1_pbkdf2_param ? 3_4_0 EXIST::FUNCTION: ++d2i_PBMAC1PARAM ? 3_4_0 EXIST::FUNCTION: ++i2d_PBMAC1PARAM ? 3_4_0 EXIST::FUNCTION: ++PBMAC1PARAM_free ? 3_4_0 EXIST::FUNCTION: ++PBMAC1PARAM_new ? 3_4_0 EXIST::FUNCTION: ++PBMAC1PARAM_it ? 3_4_0 EXIST::FUNCTION: + +From 97fbb9437163fb5114da40250b7ace83748a2e81 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Thu, 6 Jun 2024 17:01:45 +0200 +Subject: [PATCH 4/4] Test vectors from rfc9579 and creation tests + +--- + test/recipes/80-test_pkcs12.t | 55 +++++++++++++++++- + .../pbmac1_256_256.bad-iter.p12 | Bin 0 -> 2703 bytes + .../pbmac1_256_256.bad-salt.p12 | Bin 0 -> 2702 bytes + .../pbmac1_256_256.good.p12 | Bin 0 -> 2702 bytes + .../pbmac1_256_256.no-len.p12 | Bin 0 -> 2700 bytes + .../pbmac1_512_256.good.p12 | Bin 0 -> 2702 bytes + .../pbmac1_512_512.good.p12 | Bin 0 -> 2736 bytes + 7 files changed, 54 insertions(+), 1 deletion(-) + create mode 100644 test/recipes/80-test_pkcs12_data/pbmac1_256_256.bad-iter.p12 + create mode 100644 test/recipes/80-test_pkcs12_data/pbmac1_256_256.bad-salt.p12 + create mode 100644 test/recipes/80-test_pkcs12_data/pbmac1_256_256.good.p12 + create mode 100644 test/recipes/80-test_pkcs12_data/pbmac1_256_256.no-len.p12 + create mode 100644 test/recipes/80-test_pkcs12_data/pbmac1_512_256.good.p12 + create mode 100644 test/recipes/80-test_pkcs12_data/pbmac1_512_512.good.p12 + +diff --git a/test/recipes/80-test_pkcs12.t b/test/recipes/80-test_pkcs12.t +index 999129a03074d..c14ef94998cde 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 => 31; ++plan tests => 45; + + # Test different PKCS#12 formats + ok(run(test(["pkcs12_format_test"])), "test pkcs12 formats"); +@@ -170,6 +170,59 @@ ok(grep(/Trusted key usage (Oracle)/, @pkcs12info) == 0, + ok(scalar @match > 0 ? 0 : 1, "test_export_pkcs12_outerr6_empty"); + } + ++my %pbmac1_tests = ( ++ pbmac1_defaults => {args => [], lookup => "hmacWithSHA256"}, ++ pbmac1_nondefaults => {args => ["-pbmac1_pbkdf2_md", "sha512", "-macalg", "sha384"], lookup => "hmacWithSHA512"}, ++); ++ ++for my $instance (sort keys %pbmac1_tests) { ++ my $extra_args = $pbmac1_tests{$instance}{args}; ++ my $lookup = $pbmac1_tests{$instance}{lookup}; ++ # Test export of PEM file with both cert and key, with password. ++ { ++ my $pbmac1_id = $instance; ++ ok(run(app(["openssl", "pkcs12", "-export", "-pbmac1_pbkdf2", ++ "-inkey", srctop_file(@path, "cert-key-cert.pem"), ++ "-in", srctop_file(@path, "cert-key-cert.pem"), ++ "-passout", "pass:1234", ++ @$extra_args, ++ "-out", "$pbmac1_id.p12"], stderr => "${pbmac1_id}_err.txt")), ++ "test_export_pkcs12_${pbmac1_id}"); ++ open DATA, "${pbmac1_id}_err.txt"; ++ my @match = grep /:error:/, ; ++ close DATA; ++ ok(scalar @match > 0 ? 0 : 1, "test_export_pkcs12_${pbmac1_id}_err.empty"); ++ ++ ok(run(app(["openssl", "pkcs12", "-in", "$pbmac1_id.p12", "-info", "-noout", ++ "-passin", "pass:1234"], stderr => "${pbmac1_id}_info.txt")), ++ "test_export_pkcs12_${pbmac1_id}_info"); ++ open DATA, "${pbmac1_id}_info.txt"; ++ my @match = grep /$lookup/, ; ++ close DATA; ++ ok(scalar @match > 0 ? 1 : 0, "test_export_pkcs12_${pbmac1_id}_info"); ++ } ++} ++ ++# Test pbmac1 pkcs12 good files, RFC 9579 ++for my $file ("pbmac1_256_256.good.p12", "pbmac1_512_256.good.p12", "pbmac1_512_512.good.p12") ++{ ++ my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); ++ ok(run(app(["openssl", "pkcs12", "-in", $path, "-password", "pass:1234", "-noenc"])), ++ "test pbmac1 pkcs12 file $file"); ++} ++ ++# Test pbmac1 pkcs12 bad files, RFC 9579 ++for my $file ("pbmac1_256_256.bad-iter.p12", "pbmac1_256_256.bad-salt.p12", "pbmac1_256_256.no-len.p12") ++{ ++ my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); ++ with({ exit_checker => sub { return shift == 1; } }, ++ sub { ++ ok(run(app(["openssl", "pkcs12", "-in", $path, "-password", "pass:1234", "-noenc"])), ++ "test pbmac1 pkcs12 bad file $file"); ++ } ++ ); ++} ++ + # Test some bad pkcs12 files + my $bad1 = srctop_file("test", "recipes", "80-test_pkcs12_data", "bad1.p12"); + my $bad2 = srctop_file("test", "recipes", "80-test_pkcs12_data", "bad2.p12"); +diff --git a/test/recipes/80-test_pkcs12_data/pbmac1_256_256.bad-iter.p12 b/test/recipes/80-test_pkcs12_data/pbmac1_256_256.bad-iter.p12 +new file mode 100644 +index 0000000000000000000000000000000000000000..9957d473c433bc9fb9572ecf51332a7f325fe36f +GIT binary patch +literal 2703 +zcmai$c{J1u8^_I<8ABNB4Pk6UgnstR*kkNVmbleK_MOQV5{B$bZuZ@TE(Q%DI~6Sy +za_>;K?Awg&gK)d&eNUbD{pbGioacPM-{+j?zt8ysc%~FEh#tT*L1Bzi@rLpHEFcC@ +z37&Bef@j+hBY7)1Ad8U9Q_fZY!PWdV!<$)A!L;D^99D!DhE +zeQE;1U^pGX41@pY8<-JF2ME9z9peo_uJjO)6ojpI>t?AXtBj{Jv>|^u>h6bVJpBw; +z+#a^-mWMrkMYg}Jfxic~-vQC^Kt6wiU3a5|Vneevb2UJ$z)2qnB(3bX+ki6$-vZY@ +z_jNXQZTo6cC8;EgG@yE-_xV79ZGQJ%I{69AF&s=P;{7m`BV^eD>hi8QDGbWW=k(N~ +z?rwAx=6c3#F>pv2L4VOaP$r$r8H)wPkN!jmp#f9wlbG_*(`oK#@rheWABcv-oOfog +zZYz%aTa??GYAh^>vo?%Ytn1k}?VQgy3?$BA43ITPmqN=#z7%|ZuMyYTsb!MrPNefm +zZqFRZBncUQLYTJFRO5#Vm}Abxr(6e>cmXMQ`{e6;(W1HbvJy+6ch6Ew4a%-^T)$S! +zZ-KnuFs_#(<>qmAQHUMRgA=lor{8J5+lgi3=XMhrn{rQ)Q8o{i>As;dbVXX%-pF_* +zZzgS@b5K1fKeg-SDJdp=IfDL64sDgQcs97g>-}r5xM&}z?CAJ5DfWlrG{Vclzf>dn +zo{V*Ewz$6%Lf?^0e0Q>3DIInhuW#>Yl@qx8n7!wUPXuV11Kb@ccR{%DDS;0qHY>mu +zu-vr2t#J+HN=T``{Vnn9R#VlV+Ii{wMEM1hhXQ^ve5Zr$o3Kq}n^%2LkRM1kp&yyN +zAIuV?4KWFhmGbLG$uK=egKjkyGTp!b68!4=amq-$qDri1b;qV9YFJH~WOizc9I_%J +z44_J>+hGh!f}QMW!}Tr^@1zS%n5t6Ov;=QmkAqZ|PFXjGT~H>*Zg3m@=;#5|xjVXa +z=7!*1ZMuW{7jRvPZEBWku= +z>pX3o*5O*R8WWG=%h|0czJp%Kpab&Azs(Zn5^hkb3c)52sAW^j`(JBf2EO(u;};5! +zJ78c=pipR;Q`}}oNj`E?>xmo1c;h+*jm-F +zvGHxT@3QKop@A(X%GI?VH>66GGkfm!BX8F_RG=h|*OTP)9Z`1b7<0OAi@nQHs^*85 +zy*k?D(T_YY`YGM_^c@Sl@gz6Yg;Gw|Vky;(_%~Rln$h^CvdyVE;n0ScW(%D_2ZaT( +z<3JvG*k_Ou-4q$NEa0%}?T(4#q1{(hydmIOYF_cub5Cw@>J!^KG*=9kyF|@s=|27Q +zk5EesrnuH`ef-b#>n}vJP!(M)-5U9(H%wuaT-Hq#?`FZSaO8=JSxam?LFa7UX-&BK +zIDm)7{outv0D=ZX@KD@$+xPo;!p{7cP0UOn@b^&eyD9T;z_IRE*SwPN?f9?2sdG23 +zR1)>R-S`UQdvhgZ6oQ8g4M@YO8nkG!jk}taE%TK@@R2z0qnt?s#hH5~A7!4`E7*MW!m9T778sjy_p@|)v(>Z)=gcJcZLp?ECAhRQ*>te0UgO>T +z2!WGkqg5>=c`{xYLI9e=7GvIPcLnpC&fKx}N>j5dT@r0A!A+m^|pCwV%3}UgTlK*(`F{ +zPE_J;HRlt|ru*VW!Bh<_#<*>;Jv5N5(AdP?(m~9_6tWxOYfDd`22P^04U&R2Zr$>- +z+S}&in23Z+TUPeaSFchSdhOE0HWRA57_5a4k<9K1n4QJ6@Ttyv(<|-^FIfAs){oKH +zqoB1uud(vU?4o(Mh)@Yne2`GvO5mxWbYq0!lNT2Fo9>2DjQiZ4nM|rNda1}rV7|GK^jbT#JYRA%BE6nLJBS9BEd(yLu>AqCaWH~S=o;Yl +zic31awmQ +z51!~>BfRljLJY^Qp!I#PjtaOIPDWYp+$&mbuVGcU)QqmMx@9N@lGwtF9@~Xn-;x*U +zRR}CmP}b3UWSLQx=yn#R!-^im4P0K}(>&NwVZrb@W~U1o6fNJ0i`^IUgM;lg5T9HE +zUp?nq!(DFHFFOZ^v`yg@3Tp0oG-OAq7r%L2@%9|U=R!)c$gbRS?~&Uuhq2aMJ4bF) +zf9njx1D3ZECBTEZrI0V={tmq_rW~!5r`TA@z92xfYOR#%H)xcyAYVzqvpW-~s7ggZ +zV|Wf(Fi+sk3X;)Gv!LJ@2C>OTp;CMfZI^QGP_q1}y?ib7d!@%IEYg|Tz27j)$Y$y3 +z`4@4b-II|shmwgiM~Bgiiypp>)Nf4n-UjRgh-0>@+qtPVBd)8s%)CyCu8_8O6#0mT +zf%CXFZHEb(A-2~HXCGkoY3Frim&%;~856h40r_N$o~%%u3OU(#^nHpCJf&869MoR0 +zqP7On(hy;EhPkfH46;KSkjHL35~I4ooaATVlj8K4mFeX(d6hS_vW^&Q1gR$l#1FOJ +zP3WkyRW%X8xE`;1+p8FC`VJL(1*uzfeD%;{Gp$p1BKOFmMcJo#Y&Mx?ruFQNH{1^7 +zOHZfkTqNCL8+mP1emzme1_TNP`D>}n-%12coa(BwP0IT9FXEZ1t{DyZoYPX;)PLp^dR +zK=cP-8M) +zf3265`=`i(z#yUj>vI3o>>xtn<-Ye+$zWwI^q_2ul78QG*>lf;C9Y5z5p$iWB-kVb +QZf;>CWNWRj_YbE31}omyrT_o{ + +literal 0 +HcmV?d00001 + +diff --git a/test/recipes/80-test_pkcs12_data/pbmac1_256_256.bad-salt.p12 b/test/recipes/80-test_pkcs12_data/pbmac1_256_256.bad-salt.p12 +new file mode 100644 +index 0000000000000000000000000000000000000000..fef1e51f71c94240b8d5e375b3e5273a7cb54be5 +GIT binary patch +literal 2702 +zcmai$cQo4z8^xrY#+` +zsC%QWRa;5aj(vO2`=0i^??3mC=RD{8{XXYB|9#FEz%!(PL9_s#0Scp+OfXE?X9CfI +zO7Zl25Ip@BfTyPbc!Q@&82E%CpMi~4*-@x=x8h{^0@0?%=a;JrWBq6NzTQ|xqnPt3Pp-qLOF?ZhM@U*k% +z8S;f2Y&sjIWE-ljnY#hYDxCPff~cAMW*cxt}-Y;CpLL2`8~mKlp|`+ +zVO#NIfJLR9srurg7<1Ej)w-T-%g)6@!yv*e+5k~^q#IT){H5sgJN5YPZcURUPXdi! +zN@w;^Hc`;<6N_m(RV87hh%xp;Lh5x;sSl8PXF$HOA0?7+FDt$bdiyl3%%I$X{ra_f +zJ`2RXrjL55k{(`MOM+~0Zmgi4Jnc^Foo);RAE$@##I$FsjIw!{Ot0hRk*m@=_D065 +z1+(e<9K&kCg=sx6&WN!QE0MHc@~B@qO6EeUeBQnCiO2c5Fw!CwRHFuyuQ7&RbJ5UBeuS)evzOVc5rXBoRm=UlL}s>=o~+5 +z;7ZH>w)!=YdqryP?c=0xTP-zzY87Pe6XX|(UJCf7h@CFhVn7Q`eZPV#0iQikCX3UsTbnBm^N7vPuIPg2J^6)(qm*LH1MB1ct~iDqZEh!HCS +zivd(AZ9AM!NuZkzWw_oW?3*mbfUYTXPfzsK@j6Jm+%4-tw+qTf+YN7{9vo#rU3+n5 +zvyK9Hv}g`0NA_53jmR_9k;_gERIxH8D-D?j$#GKkq575igo26mtuVg~ +zGDsY2l^9*E^X2>0K>0{pzxF_tt9z$axmMf^J6RHZ(xN+Bw%mTH@ym<=bJ%nxmQOGw +z{(z1#kxZs$Pji|XCHu)qt|x7j;Efv~^oce)=aynrS{KfxKLOty_<)g}W>R~>&)Tkv +ziA(6PeVfxD4Gn5DQLe4`a+EAp&hEQAh`3$vRD~2jSx=TPbVk~#q0MP}E%vU&sF)vG +z_G@dA#y@aBA0+qQ)psuP#S=Y{Qe_;>C6X#x39m5>b>j&w<(t#cf0>fi)_eBn +zA7Pdj4Ds#91AI^Q8>Mhe6h${nk7nMP4O197pLr9>vstt&6n$!9))v=Uq0QBBRu^IZ +z5x_&^fAHcT06{|_cqsO}?f-qeVdwtKCPoGj_L8EU{nVCi;PV<2bp?&S?k(E@@7*8Hki{T6W!VwY`WM~uJLSs +zfWV1!I28*C?yOf&q;ef)*q>6*lozg4rs>VMY-wLJ>nPM6xF}#_)8C&%VxR4zHplY7 +z&g4k?J9OzW$4XKG6wbv6o}**G7S@V&J$r}HfH})RM4pJKJm`bM)Nz}^}vK#1cOG}#$PNuO9mV`BL-SV;8 +z+va7TjD|~FR`=1?ekIfO+og+cCf4@QSqmK^7(ElwJ4@*i)7_1xS3MV>GY{mfpP(>D +z!D|CP6O~iB4;MTl!^FMu!GayDL1zNe&5?$WpIhK>cpApg?{j{1Z%B9`i$^O~`h2A7 +zFc!~-gk(m4b+Ns~QBKNW4!}#U6&Nne}zu +zVCmmIHHD4zx=e0W6gNCRT}`>)yw~CT=@+pIzGn)jH|qxU^6pFqE}rL8c2$i|t`3;} +zBX(lwi}BcaxlEcdYWblN|3Ygq@s(CsWue4oWM(6sRxlMTTMX#7vHk(EaWaBU>KNel +zN=m!FwL4RvX%O~MxS$fx3(h=xfw95%Q|04?@q@*z(%-RiHWk~c_k}_;c{_;43BNbK +zs!;%!ypwQcYS1Vv>u8aCwo5lhvu5n)jNN<_=-haJgX|{epA>}Ly4r>qeI-%l9zuo<(Q$-*MMz^<%G57c79sjnEO|3c0spzPiV(mvV3II +z&_!&AmeVBF5YumlwGXuVwDYRE=kk2OITMfSA^8-GzML@ZWm1a&_`6g;cxt`SM^IynL8BdRfNvN6Nf{u&Gc@a$^0XWHf6t(iMbS}*>*0+*PKoy +z-6t~*ZW5lbje-sepPq_JHyvuU>)D(vp +zmZFk4%`!FtN#jzg-76#o5in2U9)&z)xzS*!j>cZUTI%tJeG=nm-4jj4+gh9GjP%JN +z0g)eorRS9U1#-U6^%--@hOGy5lJh|xqas0@H(eZv0{j7^ABRw8Kn;-oDH#C-1a59& +zBWP=_ulEmE!63o^>vI3o>>z>>mHu~CNML16)Ua%ulK#L<`7`gp9+tpJq5r+oPI{IQar@!yJZdr(R^P9KNApO`$IsP03$%+r(^{9AaFGT*QT>i +zZ2%YyrvVsY@c(=R(?e+hei*%DyaC9S76L*+SnIZKmRT@MdpbiK3r3>uzK_P!&Tz)< +zVXJR@*wI$y_{r$|d0+<|SQ^vi3O3lZH%iy7sWzsr`YbDO()$XMM$VgUz!`&Yg==2; +zHXFOTZJ$ISm4=cAl}~j)AIP)L@4n3-KZZGmfl0+Y?}u{*EjmHn-c_eXf!PHdo*I!4CEAmwhqTtgpPB+pJpd@SOz{WH{tOq_Y`R*vk>W?8<&T#N@?2}8m;8d +zr0sJIsRkCLcE30y#e^+~(|*aNe&r~c4XW~b_sT0S+Q%s;I=&sn_CSnU@nYyNFn +z5V)&Jb5J?F$6{l+K206I>`+e?D^s*om##;RkqL)tSLWjL$J4e>vjkfdM|$ds>K#^E +zPnxE+IF~HP#iDp~cdJSw&m(cJp(*V>rDZ@td1qXDM@ +z(rAms$V#m@-=})YN7}m8hbrg0c3PBb#7%J%C4nc+IwNIEZI>FpObalFOjY9e1cTxZ +z=ok~$*Qr@kT&9LeKC-B_#ElZXQ9Xn{!CL#=Vw7^r{JFFz;9LD4urgCjsxSCi+f=Zz +z@$EKmv+Jdx0jpl1M91FeiBsZjF83%I-N;xzBHI|`vEWWvXb81c~r16F6LKo1v&cw3g +zKpuS1ub&d#92vUI@9@>z9TUe*y|18fgWt2vtm=j5p6ue(C)PD+o+vDDiIUmcbN1&S +zAr|Hgac#%_d{6ZnB%_%q3N99IO}x_^Cb0E9=1nBeX5p?-KzE1OGjXTEwOnR7#${VDZKY5q!Os_tC#mew`X_5z*$ivrfxeSO(v_L)vQWe#WJPbddO%C0O +zO1z`ue2Uq0U%Vucs)ofFwGVZK1h5tv8M|9Jh_?NVt>*p_jJi>pESZZJOw2LQOZFmCzxA(LDjPvzQh()zx5f)qUYPbAR^Q2^xD8 +zxZ3YEUOAalJnt4BBJPO~6l`A!I1`X+3O9KC+#G+?-5`p7pX;M*ef&ciJVv3?>mya0 +zv1leJC?oQ#lg%ZLa&kIz=tbe-BUzW{PL4zSL=}H6^{bCpA+J<9wezMHx*0O3*Vc3b +zrG9tU5H{59G`?L?RR8#NCHXjIqk&E{kP4P50(4qg|A1IK7{VsB_3^qT +zrJdi}9I4OLiF@eifD-o$jy$^lF@biI +zvEH?c*SD5fMq*dcdcO8!{H{flQC2(miobT$GOJpsM^{}~5$u(1;Tfq+Q$Y8k_C&?qGV-ctXk5ff)ff&!p6 +zGKVOfui(iJlvYnOU&ql6VUrC*P`nQ9I(fE889wA*fd=}W;-eHMsjQs7W6Uz5MQVEf +zd7MbkWaP}DMB>cRVf5mnhi?<*n4!U2pKXxkgthukUTW>A>sMS>ewTQ6aQoYJx$wrp +zi@0`8hY6|yw$Bu2=WqFG=M|y*@|@o}V>iN}T(Ws@b_nh=IoWsYU5XDprB3K0sH1R2 +zWfh{KCQR=Pb6uGkVuLgyPTaV~$Fzeu$WOtiB^fa*)63`b2{*H|kLYU!D5r(Q_jTUQ +z=&16qD#8MBycVynG#2dDFkA(R2=q5e$<~_y + +literal 0 +HcmV?d00001 + +diff --git a/test/recipes/80-test_pkcs12_data/pbmac1_256_256.no-len.p12 b/test/recipes/80-test_pkcs12_data/pbmac1_256_256.no-len.p12 +new file mode 100644 +index 0000000000000000000000000000000000000000..35ebe05d177f7d745251e2fce3ebb4f23e0ebd09 +GIT binary patch +literal 2700 +zcmai$cQ71^7RK$`T}$+Gm0-0cYF59jURE#BuVfLuv(bVGmgqv<=$){+SY-*KlY|r! +z#Jx+RMXxLRB6xZ8-X!nMdo%ZsGiT2CojK>f-+TxxO%f15iNMl;A=F|C`U%H$04hKk +zmih>UrQSnesYwVd$oZ!QDZ_#+ze{F70LAyF|I+~=Y<~=3I)ouY^yf&6;08feacsLT +zzI8!BAd~_@3xWRY8;}}If#88qJ0<7?+$cc+F%V<@-tBU8dPy%AaC6~U^!*PpSju_U +z_#<@99Zx&T>f8V+y#P=2kRwBLhD_lOlh#hzwiVgh#7&Q39ZL96Nl?#yyN_@|VcVe^ +zSHCXAZSLDA;|OKpgkhx%ozEw-j7x{_GKo(iP7y#t3Fn8=JU;VoK(9~rMR9OWA&Zwf +z>2RmJINvLFkBV8u0Q`&Ei2~tj-eep?`0P&xJ|x1J?IN}+>~fARMtJ&8@&~;B7|Xo{ +z`+d2o0JADvW7XwlVfyBY>Mb4X)`M$>`a$@4lpd_^OgpSX;7ifx_p0$dJ?chD9(W4h +zl&y;$ytw7Nd?m|$vy|gQ5y*@I|IY@ +zg8B4gmJyZU!nEF(mxS1ewMfb@dE^b2(uI&}@At30<70fCb7K-Z#h4xmlPh12{G}Ad +z^>ng#x836vAM&1P(z}Z_oJ9BytgfAtMPAV16Q+I}-$=k5Gq5j8TAaVQsgesWw7|m{ +zxYl~SuX+>UR+(CR_gm7}z1EsPH3~A1@iNN4`pCo+oLFJyPyehk$I9?Z`gz@mU7gr7xy@ +z-hubN2E|F$=n;dp!S)<^RMD}4EL<*cp(fcNHbKOls@_;kD40y&yU6BilOOAAz^ipx +zYBsgZX|k?bObSPHHyO?E8D=X1TZA(|un}Ggz(MUs3bpl~4q{~r+5HcOV0Y^stKlN&TgftoPH?g)8aJ~>Ef0dNg-go)u +zA7SQZH1QqZ2DzWp&>-CMZkc8nq0`SiPR&fTIz{-_HhllHi-N=^2L%en~D +zDFhZA|AQC*1Q0j`gau>1%YNU>3v%V(Y@($B0Kc2k-$lv41CHg8ikeNKkJH}*r@_Mz +zCokx8x8)Ve@Ai7=1PBWn9hQKSRLL86c}HDJ_Z +z_Tkz%l(qWkjaC{OC^9r=8=~v=VXW&2$(v6Z+@VhwOLXm^vFc`0y2-iw +z5d{ +z(LNXRbQDy=9M?}-yRl6*V4E(qn^@aRWyyaEqxDEc9jv5B%=R=I+juO$pdZZHI!B_< +zf;R`fC#z<1OP1Ut!$iEW!F-+TL6^J|Es^?9UzlNUd+0|~AG1xlH6%Qi!lLA=yr;-o +zw8irwA(>Gd&eqpiDu@~M;nxI4&!k;nI6I9T +zOZ@JkE?}V3ZFHxyxZ&x=ddj1gqfVbszX(@yKbO7muN&0KyFVSc%*w6cq8ycs3z+{S +zc5?WO;rK*_WSSvzwZwpDsjZmsS|hBgP;@skvyn<8m<*IEMrgM){sFRbG=NNN>0xzB +z%eudIIFX;L;g66pL8Ts7oj7#@V}tExDkks~C(Bu7zhk7WD)&<#@rPz|brK8{es6qT +zBMU5jFX}?qpjKYq*(&|~kZOTq)6mxmv->vCsqxXywyUsT(mfb|DK9v{lR?x~SZs)6 +zT}mz)4+B7U^o}`M5(!m_9OB`j*NLBFZa?EW&gZU#Igj8XtWMT?02Tp@)nQT@LKGPp +zPjzorzVTmW7>ip+>iXGF@VFJvL|Yy_DB0+$qgOFki>bD_qb~*!*~1E++lJoSlMxt@ +z4JwmW&{ThHo>h_L&JNe4M^0jfZ!B}Eog66Ap}3rKGx_vN*6zi}9rO7^fp)44pIn1p +zJ!jp-+-TFSxC#Yz&SGSX>K=GD=SHiPzIjsp_A1rq;_Xs_L+Q1FGxsrOL-n_|PHe^j +zmRb5IbZc&2pOGz|ji4TxEgJ?oD69adHUN +zu|-(XQYB|ju%ueL**1o11f60KCdTF1shw{Nm*R#W6{;iO%Rfn_lgQ2;_=Z}8wMon^ +zy@(g=n~9n~6-}ByJB?Xc@$_pUeWPjg(PJ8BIA^T6o1a!U?zVx+F6a^I4efllEfd*1 +zd=1m7;W$m!M-P}_>;f%59lXZ%DlP_GF>=QZ%cPj~=Y(Mti79>)?^AuDsrCF*fUcr- +z`@I{j?NR8=0}|KH*m)=p=FL2+B1xz~P|3Rx1K51d#aI-Wu!VoL~RKU#aPxSA{M*ucpt;un1#F +zN{O=! +wg4}<_IuKt(mEQv;B2YmcIU?0AuRAzb@!TtLl{HLKz*I9j88QQc{^zZK0K6{N*8l(j + +literal 0 +HcmV?d00001 + +diff --git a/test/recipes/80-test_pkcs12_data/pbmac1_512_256.good.p12 b/test/recipes/80-test_pkcs12_data/pbmac1_512_256.good.p12 +new file mode 100644 +index 0000000000000000000000000000000000000000..e8d4899691bfec94614bf1614c0e9d45b902cf24 +GIT binary patch +literal 2702 +zcmai$XHXM}7KKSjLJPg9krp5dtO*HCK!hMlfKXgfI#LZaQi2reL5lP$MT%7EC6I^; +zC`DLA7DP4z(iA~@4~T#+JMWFY_iKOLxpU6BGxy&&2Tf*=0|J=QWOguwO*UFLdXE#p +z0(eAb+Xa!?w$Nm@H8dII@GF8mB7;nhEn^^n>3He>N&slHp90K@)wmrh*}zO_5eS=Iv@YNlGYB9H;<3c(p-6ScN9EXskqoP5qi{0w +z47G^^7Gd+bc<}~Fgv7UOY||$9Vx7GWFqBwZz(2@Li=v*KZ6RzFhbL%5y>@HX*g|fK +zCFqY*(F=sh(a;N)GHI#~25yMcT_{*a)IDT;VNko2^?scCxtKjyLprQ(YXAh}L#%n( +zTQrhNI76$_g!lGcpUJy)#$0n;G6ZQ#gO>#8w>!LU{(S-z=WV6_Pg +zU*q$mxw1C5Ex$SI=B3N?jdOchd{4fgVv=pT4ZoVk9Z8}FNHUvYc4BhvoTUsI8L^sL +zopiZ;y2XdHfUO!V-Ar5BROQO(-K1jGZ7ZwQ!@L!*8;l#mKUQ?Yzp@bGbDg|ELDX}Q&X!Y4%3b*7*VHf%9yZv!SWi>t>qm6DRrsYEr;&BPo!3}4V@ +zk?AMeU*?oAW{xGA$SE*L7`tfRwiT#@v9gqOtDkqwN;#{ly0J}Nt?hZV1xAlN*4&`O +zo9da~^}MoxyT7Vk-92 +z`Y3n;E-oE~9xR#>@)u0sn#CVfstkUtzoh@2+a05kV*_uuuYEzSeI1hbS)7*QO!P~C +zUpz75Z=$s3)O#=QnbMzDER&L`hq$60tR+pC63&E_?TS#3G2b&kyp{F7S&&35;>&M5 +zoi(MtRe^Tbu7XhXI68w9sOH1As}p-duSoG*Qkw>vkUeG2mDftlHA~m$ge}onp(n8m +zjgL*GaTIZ6RA)2QALINZPma#jy)Ibw&1Y%$yleTJY&G+3C7q8dc)f9RLJ&!BHfys` +zaK2_A6@J2!er@{0=ws8BH6wK-N)Zh+u50iiFvMOD3ykZI*xk+il9(tg0csxxoP57w +znjV%tW3PLyr +zEqvBZD*alJHx#UUSUudi^LW71U$8h1Dw(>yN;V%GV;T|#h&eWq{{|fGcn3K57F4v8+{vgq3Oh~ZrmcEST-O8z4%K1s}M;tPIc +zvuMYpV5W+0Rp}Q}bxD!pJEs=sD=OV!n^Ee3qTtk`$Aw(zo%z>QnV?T|U!r)o;7w81 +zU8CuN( +zJMm~CzxWw161M$eue=Jp=M_L1i0#Y2MGA8K()rh?vW>%30k;T}1? +z73pvY=|4vmbzqOSv-E$-F!*{oNrwn~$f41DUk0TThvqA(==BjI2KmgHnSx1=#&OijuHpX8vmIu1PgNf;+T-W%LX3WP +z&{M@dfCZ%)WLtc}A*y(c^jYJ2tcE(uY+ewf71epylo^X+N#8rQb|Ue`>HI&+qd)mi +zId1=z#p>EI>l<)+iMA|za=3;zliQfPg_;_ezGxi5rM!wx@zl36fR6R;pK9|{zggX* +zI6Wwgv1upQj4OReh2&+=-Pn==w3ffs-CqWjKex5G188Rqb`XY6^RUk$`=4$`8sPh}=d +zv}X!M)}HY<>H3J5M?xOCT|9W&eD}BTmWQhLCqxa48DSh-kzZRxQ+j6ECqPlX{Qmc^GC9chTwY@c+_gztryy>w&dM=$U8i>Kpbf+D} +z?Vt}#Da&gwKZZJZ)>~u*r}KQ-=}o7F^3P&hdJSmW%72t?l7+Ayu%T4Lc{nj}7&S;y +zz22p-cu4Wo2I^8oDFG?Hj(rdN$71iy?jf1LKBnw%CeB1cCTX{@H=Qu31p;5@G-X&J +z1vYRNT{O^EkvCH4zO*k_)-C*YZk?&YXgTvRv&{EHw)K<0LYMb)dxsMdr7y};se-ZX +zj`eRLC6ZHm$aFaJ&TF0w;}^q&d-N7Xu0&R=9n)a$X>W)J+jk6IL8~=YwI;Vo$o%nPP#DS +zOsjaY(w>~gaR7Bor+MVily= +VW!Nl&SdEOYi{CK0av2B!{0(@<()a)X + +literal 0 +HcmV?d00001 + +diff --git a/test/recipes/80-test_pkcs12_data/pbmac1_512_512.good.p12 b/test/recipes/80-test_pkcs12_data/pbmac1_512_512.good.p12 +new file mode 100644 +index 0000000000000000000000000000000000000000..64e14341a10d04e7e98cf83dbb2b6409ae1fd72f +GIT binary patch +literal 2736 +zcmai$c{J3I8pdbF48|5&vqjlrhOaf*e~6LnON7GM*TRf3A}0Gbexk{eEm_A}b`r8> +zuMmwr#kJMgD&qQ`dr#f}?jP@Y&+|O*Iq!d;^8f?}G6YNm5Ex*zaLE`{%mFi)4xCSb +z??VZ2DnNj50R*V?pNKY}0JS)^Odw#;=|cTUz`%{)0>%tn11|lMOaMQWo?KOURPZ9w +z69S?|M>=i!$5!lE!;5%1$L!@f+eA>5>rmGyl-<5gfLWQhjpo01c7G3*uvx%W?sgue{9RT|s4#R>C6J%Edk<=-uq-d@r!ROUg)X-ILGkK7})ZpGl# +z6-*+R=UWkb{1Uk*#E0!_e;YnW&+pQ^eq4sI$Ww|Hv(}0#a +zKlQ^+B%Z=t5EUDbniPw$^O<*tICAC6KObyy_!1pUMJP=_w3MQ_L}_KLa~I$j`nTT} +zHKwJ_EiYl2+#BDc^{A=46L)q=)y5g6&!p^&Vq?l?HW_g0&*yWG8)~BcGLmG2_zkpD +zuJoXL67oBKU=FvPnif~prLZ59aGj)q&F+Tb8c-j#f&RP0OKAu!zYnC!R&k()qJN1D +zH)n{YHF**!la_j>+`ZaK*3+)|hY9ao;2E{SU;60toCXNT@qDh`ml?gc_3=eV{?51F +z=U0+nWJ9&68P5wsaB~Oh{Ml7-lZyT?nz7-@3_Pa$cFyfOH{VqUHj`A%$91}J$gqD1T>EH^|xG)1&ISL#*ZFlj`&Q|`X@`eO}%)v57KM?!MyKQ +zXc{9i<$mE}VxakYPTQpB%tY3V*Dl{DW5lfc_V}%EtVn1p7nY~{N*8NuoyQ_$)ws86do%hBVb(F1bVEvsA9>F&O +zRQs=KLrclFky%8f;cM0HkAnqrG!8bmFh0|w6SSh^JAOInR!2Krmr4GHh^F&q&BF29 +z*|eckw27|l!`5RThgUd3i2XeIHB||T+HmQF1 +zPDP#z=8kjer&j+4rM{T~`6CS-p+%{%^hoip*Obdm#BNa17XnqR4f#}AZEEru&#GzO +zS(|OatP(Y7WaOUxEG~h6fN5pGvEXc-|1Te>L%`F|$k|~yrON}$Q~GV(GItZZR5rtq +zx@@Va4Xu+B1WTkJN6(5zi^HOIP318BM~CGBgDH4 +zLaK$Ks@QD9D>chzYe`t>NjjE`cuObjo}66SL50g8p9$Sm^^tns +z;0_RAQNMZd4}f48C;@i&)b>3cPg=(RvWbZS3^@&DPfg_i15SP5i)Nv}TDSi%aONt8 +z`B0c7FBPnYhe9LB8cKkUDN;BJQl}W&QaCv2Pc-)0f6CFEbAOdK&Ob3`Zm!y`U3A_z +zODU+hSBxYWL41$n&+28lD!q0TwRAFBNsli%CnzuIPE_J$DjM&>bE7k^auH?~miFK) +zIqaBwg7QmEwp)ZSN6kj5jefLN-FgZBcH76~>AGKHJauJBXEOUCn_uh{(n3he>JRLQ +zR|B-g%xs4l(>}LpgECD!Tqrr!Vx|{2qiD6Sg)V5%4}U+mVekZjH08N`i}}Fy*3^0# +zKz&<(b0knfLr)75aA8X|3pbq_oeCq8e7yiN*S+Qd)>ig&jMwh9R+b7e+Im__SSes+ +zMDA};&vN=jlrY*Ehga$F@lBOSQ_Yyhk>Pz>=S5R8vmJc)scR +z=#Y@?kRW+Jndd2|TkldK}))zdux@RmaSl_TDG0?o5 +zMMh%2IT4G9~=#_+fE&WM@d6`gnk`K +z4ZAPu-T)R`7#!}|D~Z^i8YP*nzuQ&$t^)ex^SI)5bkOl@$Ch5et(hmU_H$6{=rd(= +zH*9Taf@8>5lz@Cc`s0rbN|)&x9;{@sX6g>J>@7D0-tggLsaChE +zzWcuCVOajxbVG+ly{x;j!jR)mBkL?no4>)=YitX8aX)SOTr(yPVoxrI*RR#up7#Q5 +z!0saXlgee#J^Ms>kaU^#^Pe+9Tw>CWyg)zG{L3(N9jlQ$s~q?b%j!`e#kFy^z8iAp +zQ|IfPf8O6EM%?ua$)DxW{I#W1QaAd&_M^8%JCiVwCzS=o!;k(}DaOl#W09 +zSk4>aZ7zFHy<|Igb>#!~?A4PQWj>6QxLJ@Kj1CZPTN_dw)mu~-BUvZrsoc9C#w#ld +zT>K4KIHxQZl%o^f%#yHeHs^H6%z +z8T%F9D?MlaAu9x|^*?Qn@wCnT>2{|Isuci|f7PzcNM|bXivb;s8AAv{)-jC$Rb~R?lGFsEHIm`3Psh-q4iM{;+CGg!1m8_f06hv5BRSmBm$E2pIft +D?Q7k< + +literal 0 +HcmV?d00001 + diff --git a/openssl.spec b/openssl.spec index 333a425..f58bd8c 100644 --- a/openssl.spec +++ b/openssl.spec @@ -29,7 +29,7 @@ print(string.sub(hash, 0, 16)) Summary: Utilities from the general purpose cryptography library with TLS implementation Name: openssl Version: 3.2.2 -Release: 7%{?dist} +Release: 8%{?dist} Epoch: 1 Source: openssl-%{version}.tar.gz Source2: Makefile.certificate @@ -158,6 +158,8 @@ Patch117: 0117-ignore-unknown-sigalgorithms-groups.patch Patch121: 0121-FIPS-cms-defaults.patch # HKDF regression with older provider implementations Patch122: 0123-kdf-Preserve-backward-compatibility-with-older-provi.patch +# https://github.com/openssl/openssl/issues/24577 +Patch124: 0124-PBMAC1-PKCS12-FIPS-support.patch License: Apache-2.0 URL: http://www.openssl.org/ @@ -503,6 +505,10 @@ ln -s /etc/crypto-policies/back-ends/openssl_fips.config $RPM_BUILD_ROOT%{_sysco %ldconfig_scriptlets libs %changelog +* Wed Aug 07 2024 Dmitry Belyavskiy - 1:3.2.2-8 +- An interface to create PKCS #12 files in FIPS compliant way + Resolves: RHEL-36659 + * Wed Jul 10 2024 Dmitry Belyavskiy - 1:3.2.2-7 - Disallow SHA1 at SECLEVEL2 in OpenSSL Resolves: RHEL-39962