Blame SOURCES/0006-p11_child-prefer-better-digest-function-if-card-supp.patch

d6181b
From 7f0a8f5060b28dc35e152d7290b583de99361d80 Mon Sep 17 00:00:00 2001
d6181b
From: Sumit Bose <sbose@redhat.com>
d6181b
Date: Tue, 2 Jul 2019 17:11:50 +0200
d6181b
Subject: [PATCH 6/7] p11_child: prefer better digest function if card supports
d6181b
 it
d6181b
d6181b
To improve FIPS compliance and security in general p11_child now checks
d6181b
which message digest functions (hashes) are support for RSA keys and
d6181b
tries to use the highest bit length supported.
d6181b
d6181b
For EC keys sha512 is used unconditionally.
d6181b
d6181b
Related to https://pagure.io/SSSD/sssd/issue/4039
d6181b
d6181b
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
d6181b
---
d6181b
 src/p11_child/p11_child_openssl.c | 87 +++++++++++++++++++++++++++++--
d6181b
 1 file changed, 82 insertions(+), 5 deletions(-)
d6181b
d6181b
diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c
d6181b
index 007f58c52..7233f39fd 100644
d6181b
--- a/src/p11_child/p11_child_openssl.c
d6181b
+++ b/src/p11_child/p11_child_openssl.c
d6181b
@@ -1097,7 +1097,75 @@ static int rs_to_seq(TALLOC_CTX *mem_ctx, CK_BYTE *rs_sig, CK_ULONG rs_sig_len,
d6181b
     return EOK;
d6181b
 }
d6181b
 
d6181b
+static CK_RV get_preferred_rsa_mechanism(TALLOC_CTX *mem_ctx,
d6181b
+                                         CK_FUNCTION_LIST *module,
d6181b
+                                         CK_SLOT_ID slot_id,
d6181b
+                                         CK_MECHANISM_TYPE *preferred_mechanism,
d6181b
+                                         const EVP_MD **preferred_evp_md)
d6181b
+{
d6181b
+    CK_ULONG count;
d6181b
+    CK_MECHANISM_TYPE *mechanism_list = NULL;
d6181b
+    CK_RV rv;
d6181b
+    size_t c;
d6181b
+    size_t m;
d6181b
+    struct prefs {
d6181b
+        CK_MECHANISM_TYPE mech;
d6181b
+        const char *mech_name;
d6181b
+        const EVP_MD *evp_md;
d6181b
+        const char *md_name;
d6181b
+    } prefs[] = {
d6181b
+        { CKM_SHA512_RSA_PKCS, "CKM_SHA512_RSA_PKCS", EVP_sha512(), "sha512" },
d6181b
+        { CKM_SHA384_RSA_PKCS, "CKM_SHA384_RSA_PKCS", EVP_sha384(), "sha384" },
d6181b
+        { CKM_SHA256_RSA_PKCS, "CKM_SHA256_RSA_PKCS", EVP_sha256(), "sha256" },
d6181b
+        { CKM_SHA224_RSA_PKCS, "CKM_SHA224_RSA_PKCS", EVP_sha224(), "sha224" },
d6181b
+        { CKM_SHA1_RSA_PKCS,   "CKM_SHA1_RSA_PKCS",   EVP_sha1(),   "sha1" },
d6181b
+        { 0, NULL }
d6181b
+    };
d6181b
+
d6181b
+    *preferred_mechanism = CKM_SHA1_RSA_PKCS;
d6181b
+    *preferred_evp_md = EVP_sha1();
d6181b
+
d6181b
+    rv = module->C_GetMechanismList(slot_id, NULL, &count);
d6181b
+    if (rv == CKR_OK && count > 0) {
d6181b
+        mechanism_list = talloc_size(mem_ctx,
d6181b
+                                     count * sizeof(CK_MECHANISM_TYPE));
d6181b
+        if (mechanism_list != NULL) {
d6181b
+            rv = module->C_GetMechanismList(slot_id, mechanism_list, &count);
d6181b
+            if (rv == CKR_OK) {
d6181b
+                if (DEBUG_IS_SET(SSSDBG_TRACE_ALL)) {
d6181b
+                    for (m = 0; m < count; m++) {
d6181b
+                        DEBUG(SSSDBG_TRACE_ALL, "Found mechanism [%lu].\n",
d6181b
+                                                mechanism_list[m]);
d6181b
+                    }
d6181b
+                }
d6181b
+                for (c = 0; prefs[c].mech != 0; c++) {
d6181b
+                    for (m = 0; m < count; m++) {
d6181b
+                        if (prefs[c].mech == mechanism_list[m]) {
d6181b
+                            *preferred_mechanism = prefs[c].mech;
d6181b
+                            *preferred_evp_md = prefs[c].evp_md;
d6181b
+                            DEBUG(SSSDBG_FUNC_DATA,
d6181b
+                                  "Using PKCS#11 mechanism [%lu][%s] and "
d6181b
+                                  "local message digest [%s].\n",
d6181b
+                                  *preferred_mechanism, prefs[c].mech_name,
d6181b
+                                  prefs[c].md_name);
d6181b
+                            break;
d6181b
+                        }
d6181b
+                    }
d6181b
+                    if (m != count) {
d6181b
+                        break;
d6181b
+                    }
d6181b
+                }
d6181b
+            }
d6181b
+        }
d6181b
+    }
d6181b
+
d6181b
+    talloc_free(mechanism_list);
d6181b
+
d6181b
+    return rv;
d6181b
+}
d6181b
+
d6181b
 static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
d6181b
+                     CK_SLOT_ID slot_id,
d6181b
                      struct cert_list *cert)
d6181b
 {
d6181b
     CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
d6181b
@@ -1108,6 +1176,7 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
d6181b
       {CKA_ID, NULL, 0}
d6181b
     };
d6181b
     CK_MECHANISM mechanism = { CK_UNAVAILABLE_INFORMATION, NULL, 0 };
d6181b
+    CK_MECHANISM_TYPE preferred_mechanism;
d6181b
     CK_OBJECT_HANDLE priv_key_object;
d6181b
     CK_ULONG object_count;
d6181b
     CK_BYTE random_value[128];
d6181b
@@ -1157,15 +1226,23 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
d6181b
 
d6181b
     switch (get_key_type(module, session, priv_key_object)) {
d6181b
     case CKK_RSA:
d6181b
-        DEBUG(SSSDBG_TRACE_ALL, "Found RSA key using CKM_SHA1_RSA_PKCS.\n");
d6181b
-        mechanism.mechanism = CKM_SHA1_RSA_PKCS;
d6181b
-        evp_md = EVP_sha1();
d6181b
+        rv = get_preferred_rsa_mechanism(cert, module, slot_id,
d6181b
+                                         &preferred_mechanism, &evp_md);
d6181b
+        if (rv != CKR_OK) {
d6181b
+            DEBUG(SSSDBG_OP_FAILURE, "get_preferred_rsa_mechanism failed, "
d6181b
+                                     "using default CKM_SHA1_RSA_PKCS.\n");
d6181b
+            preferred_mechanism = CKM_SHA1_RSA_PKCS;
d6181b
+            evp_md = EVP_sha1();
d6181b
+        }
d6181b
+        DEBUG(SSSDBG_TRACE_ALL, "Found RSA key using mechanism [%lu].\n",
d6181b
+                                preferred_mechanism);
d6181b
+        mechanism.mechanism = preferred_mechanism;
d6181b
         card_does_hash = true;
d6181b
         break;
d6181b
     case CKK_EC:
d6181b
         DEBUG(SSSDBG_TRACE_ALL, "Found ECC key using CKM_ECDSA.\n");
d6181b
         mechanism.mechanism = CKM_ECDSA;
d6181b
-        evp_md = EVP_sha1();
d6181b
+        evp_md = EVP_sha512();
d6181b
         card_does_hash = false;
d6181b
         break;
d6181b
     case CK_UNAVAILABLE_INFORMATION:
d6181b
@@ -1662,7 +1739,7 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx,
d6181b
             goto done;
d6181b
         }
d6181b
 
d6181b
-        ret = sign_data(module, session, cert_list);
d6181b
+        ret = sign_data(module, session, slot_id, cert_list);
d6181b
         if (ret != EOK) {
d6181b
             DEBUG(SSSDBG_OP_FAILURE, "sign_data failed.\n");
d6181b
             ret = EACCES;
d6181b
-- 
d6181b
2.20.1
d6181b