libressl/0029-pkcs12-add-support-for-GOST-PFX-files.patch

110 lines
3.5 KiB
Diff
Raw Normal View History

From 63d60fe4403982e7491286b9e1e47c0a4a9ed4d5 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 25 Mar 2020 13:31:41 +0300
Subject: [PATCH 29/87] pkcs12: add support for GOST PFX files
Russian standard body has changed the way MAC key is calculated for
PKCS12 files. Generate proper keys depending on the digest type used for
MAC generation.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/pkcs12/p12_key.c | 18 ++++++++++++++++++
src/lib/libcrypto/pkcs12/p12_mutl.c | 28 +++++++++++++++++++++-------
src/lib/libcrypto/pkcs12/pkcs12.h | 5 +++++
3 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/src/lib/libcrypto/pkcs12/p12_key.c b/src/lib/libcrypto/pkcs12/p12_key.c
index d419a9d83..9a5297a23 100644
--- a/src/lib/libcrypto/pkcs12/p12_key.c
+++ b/src/lib/libcrypto/pkcs12/p12_key.c
@@ -195,3 +195,21 @@ end:
EVP_MD_CTX_cleanup(&ctx);
return ret;
}
+
+int
+PKCS12_key_gen_gost(const char *pass, int passlen, unsigned char *salt,
+ int saltlen, int iter, int n, unsigned char *out,
+ const EVP_MD *md_type)
+{
+ unsigned char buf[96];
+
+ if (n != PKCS12_GOST_KEY_LEN)
+ return 0;
+
+ if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, md_type, sizeof(buf), buf))
+ return 0;
+
+ memcpy(out, buf + sizeof(buf) - PKCS12_GOST_KEY_LEN, PKCS12_GOST_KEY_LEN);
+
+ return 1;
+}
diff --git a/src/lib/libcrypto/pkcs12/p12_mutl.c b/src/lib/libcrypto/pkcs12/p12_mutl.c
index f3132ec75..023bbbd92 100644
--- a/src/lib/libcrypto/pkcs12/p12_mutl.c
+++ b/src/lib/libcrypto/pkcs12/p12_mutl.c
@@ -74,6 +74,7 @@ PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
unsigned char *mac, unsigned int *maclen)
{
const EVP_MD *md_type;
+ int md_type_nid;
HMAC_CTX hmac;
unsigned char key[EVP_MAX_MD_SIZE], *salt;
int saltlen, iter;
@@ -97,13 +98,26 @@ PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
PKCS12error(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
return 0;
}
- md_size = EVP_MD_size(md_type);
- if (md_size < 0)
- return 0;
- if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
- md_size, key, md_type)) {
- PKCS12error(PKCS12_R_KEY_GEN_ERROR);
- return 0;
+ md_type_nid = EVP_MD_type(md_type);
+ if ((md_type_nid == NID_id_GostR3411_94 ||
+ md_type_nid == NID_id_tc26_gost3411_2012_256 ||
+ md_type_nid == NID_id_tc26_gost3411_2012_512) &&
+ getenv("LEGACY_GOST_PKCS12") == NULL) {
+ md_size = PKCS12_GOST_KEY_LEN;
+ if (!PKCS12_key_gen_gost(pass, passlen, salt, saltlen, iter,
+ md_size, key, md_type)) {
+ PKCS12error(PKCS12_R_KEY_GEN_ERROR);
+ return 0;
+ }
+ } else {
+ md_size = EVP_MD_size(md_type);
+ if (md_size < 0)
+ return 0;
+ if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
+ md_size, key, md_type)) {
+ PKCS12error(PKCS12_R_KEY_GEN_ERROR);
+ return 0;
+ }
}
HMAC_CTX_init(&hmac);
if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) ||
diff --git a/src/lib/libcrypto/pkcs12/pkcs12.h b/src/lib/libcrypto/pkcs12/pkcs12.h
index 56635f9d7..4dab109bb 100644
--- a/src/lib/libcrypto/pkcs12/pkcs12.h
+++ b/src/lib/libcrypto/pkcs12/pkcs12.h
@@ -91,6 +91,11 @@ extern "C" {
#define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc
#endif
+#define PKCS12_GOST_KEY_LEN 32
+int PKCS12_key_gen_gost(const char *pass, int passlen, unsigned char *salt,
+ int saltlen, int iter, int n, unsigned char *out,
+ const EVP_MD *md_type);
+
/* MS key usage constants */
#define KEY_EX 0x10
--
2.17.1