libressl/0056-cms-allow-keys-support-different-RI-types.patch

113 lines
3.9 KiB
Diff
Raw Permalink Normal View History

From a93a2217ebca9eb7b6190a142e71bbc2a7a0db97 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 8 Apr 2020 18:00:40 +0300
Subject: [PATCH 56/87] cms: allow keys support different RI types
GOST keys support both KeyTransport and KeyAgreement. Instead of
checking that RI type matches one of EVP_PKEY, check if EVP_PKEY
supports this RI type.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/cms/cms_env.c | 20 ++++++++++++++++++++
src/lib/libcrypto/cms/cms_lcl.h | 1 +
src/lib/libcrypto/cms/cms_smime.c | 14 ++++++--------
src/lib/libcrypto/evp/evp.h | 1 +
4 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/src/lib/libcrypto/cms/cms_env.c b/src/lib/libcrypto/cms/cms_env.c
index f5e9280d4..17778a4fe 100644
--- a/src/lib/libcrypto/cms/cms_env.c
+++ b/src/lib/libcrypto/cms/cms_env.c
@@ -989,3 +989,23 @@ cms_pkey_get_ri_type(EVP_PKEY *pk)
}
return CMS_RECIPINFO_TRANS;
}
+
+/* Some PKEYs (GOST) support different RecipientInfo types */
+int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type)
+{
+ int supportedRiType;
+
+ if (pk->ameth != NULL && pk->ameth->pkey_ctrl != NULL) {
+ int i, r;
+
+ i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED, ri_type, &r);
+ if (i > 0)
+ return r;
+ }
+
+ supportedRiType = cms_pkey_get_ri_type(pk);
+ if (supportedRiType < 0)
+ return 0;
+
+ return (supportedRiType == ri_type);
+}
diff --git a/src/lib/libcrypto/cms/cms_lcl.h b/src/lib/libcrypto/cms/cms_lcl.h
index fdfd12160..d400f5028 100644
--- a/src/lib/libcrypto/cms/cms_lcl.h
+++ b/src/lib/libcrypto/cms/cms_lcl.h
@@ -460,6 +460,7 @@ int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain);
CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd);
int cms_pkey_get_ri_type(EVP_PKEY *pk);
+int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type);
/* KARI routines */
int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
EVP_PKEY *pk, unsigned int flags);
diff --git a/src/lib/libcrypto/cms/cms_smime.c b/src/lib/libcrypto/cms/cms_smime.c
index 367810f40..d02ec5db1 100644
--- a/src/lib/libcrypto/cms/cms_smime.c
+++ b/src/lib/libcrypto/cms/cms_smime.c
@@ -677,21 +677,19 @@ CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
{
STACK_OF(CMS_RecipientInfo) *ris;
CMS_RecipientInfo *ri;
- int i, r, ri_type;
+ int i, r;
int debug = 0, match_ri = 0;
ris = CMS_get0_RecipientInfos(cms);
if (ris)
debug = cms->d.envelopedData->encryptedContentInfo->debug;
- ri_type = cms_pkey_get_ri_type(pk);
- if (ri_type == CMS_RECIPINFO_NONE) {
- CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
- return 0;
- }
for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
+ int ri_type;
+
ri = sk_CMS_RecipientInfo_value(ris, i);
- if (CMS_RecipientInfo_type(ri) != ri_type)
+ ri_type = CMS_RecipientInfo_type(ri);
+ if (!cms_pkey_is_ri_type_supported(pk, ri_type))
continue;
match_ri = 1;
if (ri_type == CMS_RECIPINFO_AGREE) {
@@ -734,7 +732,7 @@ CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
}
}
/* If no cert, key transport and not debugging always return success */
- if (cert == NULL && ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) {
+ if (cert == NULL && cms_pkey_get_ri_type(pk) == CMS_RECIPINFO_TRANS && match_ri && !debug) {
ERR_clear_error();
return 1;
}
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 981351d76..48c7e7360 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -1036,6 +1036,7 @@ void EVP_PBE_cleanup(void);
#define ASN1_PKEY_CTRL_CMS_SIGN 0x5
#define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7
#define ASN1_PKEY_CTRL_CMS_RI_TYPE 0x8
+#define ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED 0x9
int EVP_PKEY_asn1_get_count(void);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
--
2.17.1