URL: https://github.com/SSSD/sssd/pull/837
Author: sumit-bose
 Title: #837: p11_child: make OCSP digest configurable
Action: opened

PR body:
"""
Currently sha1 is used to create the certid for an OCSP request. Since sha1
is not recommend for new applications anymore and not FIPS compliant this
patch changes the default to sha256 and makes the digest function
configurable as well.

Related to https://pagure.io/SSSD/sssd/issue/4032
"""

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/837/head:pr837
git checkout pr837
From d80bd2e9d4290ada3793b68cafed8c18a577b5f4 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Tue, 25 Jun 2019 12:46:10 +0200
Subject: [PATCH 1/3] utils: remove unused prototype (cert_to_ssh_key)

This is a leftover from a previous cleanup done in the context of
https://pagure.io/SSSD/sssd/issue/3489.
---
 src/util/cert.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/src/util/cert.h b/src/util/cert.h
index d528029561..2fccc8be9f 100644
--- a/src/util/cert.h
+++ b/src/util/cert.h
@@ -48,11 +48,6 @@ errno_t bin_to_ldap_filter_value(TALLOC_CTX *mem_ctx,
                                  const uint8_t *blob, size_t blob_size,
                                  char **_str);
 
-errno_t cert_to_ssh_key(TALLOC_CTX *mem_ctx, const char *ca_db,
-                        const uint8_t *der_blob, size_t der_size,
-                        struct cert_verify_opts *cert_verify_opts,
-                        uint8_t **key, size_t *key_size);
-
 errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx,
                               uint8_t *der_blob, size_t der_size,
                               uint8_t **key_blob, size_t *key_size);

From e4a0513a4b3e8503b0881226d0aae656eb129560 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Tue, 25 Jun 2019 12:57:29 +0200
Subject: [PATCH 2/3] utils: move parse_cert_verify_opts() into separate file

parse_cert_verify_opts() is only used by p11_child, so it makes sense to
move the sources nearer together. The related test is still in
test_utils but it can be split out as well if there are more p11_child
related unit tests.

Related to https://pagure.io/SSSD/sssd/issue/4032
---
 src/p11_child/p11_child.h              |  11 ++
 src/p11_child/p11_child_common_utils.c | 182 +++++++++++++++++++++++++
 src/tests/cmocka/test_utils.c          |   1 +
 src/util/util.c                        | 153 ---------------------
 src/util/util.h                        |  11 --
 5 files changed, 194 insertions(+), 164 deletions(-)
 create mode 100644 src/p11_child/p11_child_common_utils.c

diff --git a/src/p11_child/p11_child.h b/src/p11_child/p11_child.h
index 92ecf74a89..d31a76f92d 100644
--- a/src/p11_child/p11_child.h
+++ b/src/p11_child/p11_child.h
@@ -30,6 +30,14 @@
 #define PKCS11_FINIALIZE_INITIALIZE_WAIT_TIME 3
 struct p11_ctx;
 
+struct cert_verify_opts {
+    bool do_ocsp;
+    bool do_verification;
+    char *ocsp_default_responder;
+    char *ocsp_default_responder_signing_cert;
+    char *crl_file;
+};
+
 enum op_mode {
     OP_NONE,
     OP_AUTH,
@@ -55,4 +63,7 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx,
                 enum op_mode mode, const char *pin,
                 const char *module_name_in, const char *token_name_in,
                 const char *key_id_in, const char *uri, char **_multi);
+
+errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts,
+                               struct cert_verify_opts **cert_verify_opts);
 #endif /* __P11_CHILD_H__ */
diff --git a/src/p11_child/p11_child_common_utils.c b/src/p11_child/p11_child_common_utils.c
new file mode 100644
index 0000000000..0374eff0ab
--- /dev/null
+++ b/src/p11_child/p11_child_common_utils.c
@@ -0,0 +1,182 @@
+/*
+    SSSD
+
+    Helper child to commmunicate with SmartCard -- common code
+
+    Authors:
+        Sumit Bose <sb...@redhat.com>
+
+    Copyright (C) 2019 Red Hat
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+#include <talloc.h>
+
+#include "util/util.h"
+#include "p11_child/p11_child.h"
+
+static struct cert_verify_opts *init_cert_verify_opts(TALLOC_CTX *mem_ctx)
+{
+    struct cert_verify_opts *cert_verify_opts;
+
+    cert_verify_opts = talloc_zero(mem_ctx, struct cert_verify_opts);
+    if (cert_verify_opts == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+        return NULL;
+    }
+
+    cert_verify_opts->do_ocsp = true;
+    cert_verify_opts->do_verification = true;
+    cert_verify_opts->ocsp_default_responder = NULL;
+    cert_verify_opts->ocsp_default_responder_signing_cert = NULL;
+    cert_verify_opts->crl_file = NULL;
+
+    return cert_verify_opts;
+}
+
+#define OCSP_DEFAUL_RESPONDER "ocsp_default_responder="
+#define OCSP_DEFAUL_RESPONDER_LEN (sizeof(OCSP_DEFAUL_RESPONDER) - 1)
+
+#define OCSP_DEFAUL_RESPONDER_SIGNING_CERT \
+                                          "ocsp_default_responder_signing_cert="
+#define OCSP_DEFAUL_RESPONDER_SIGNING_CERT_LEN \
+                                (sizeof(OCSP_DEFAUL_RESPONDER_SIGNING_CERT) - 1)
+#define CRL_FILE "crl_file="
+#define CRL_FILE_LEN (sizeof(CRL_FILE) -1)
+
+errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts,
+                               struct cert_verify_opts **_cert_verify_opts)
+{
+    int ret;
+    TALLOC_CTX *tmp_ctx;
+    char **opts;
+    size_t c;
+    struct cert_verify_opts *cert_verify_opts;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+        return ENOMEM;
+    }
+
+    cert_verify_opts = init_cert_verify_opts(tmp_ctx);
+    if (cert_verify_opts == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "init_cert_verify_opts failed.\n");
+        ret = ENOMEM;
+        goto done;
+    }
+
+    if (verify_opts == NULL) {
+        ret = EOK;
+        goto done;
+    }
+
+    ret = split_on_separator(tmp_ctx, verify_opts, ',', true, true, &opts,
+                             NULL);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "split_on_separator failed.\n");
+        goto done;
+    }
+
+    for (c = 0; opts[c] != NULL; c++) {
+        if (strcasecmp(opts[c], "no_ocsp") == 0) {
+            DEBUG(SSSDBG_TRACE_ALL,
+                  "Found 'no_ocsp' option, disabling OCSP.\n");
+            cert_verify_opts->do_ocsp = false;
+        } else if (strcasecmp(opts[c], "no_verification") == 0) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "Found 'no_verification' option, "
+                  "disabling verification completely. "
+                  "This should not be used in production.\n");
+            cert_verify_opts->do_verification = false;
+        } else if (strncasecmp(opts[c], OCSP_DEFAUL_RESPONDER,
+                               OCSP_DEFAUL_RESPONDER_LEN) == 0) {
+            cert_verify_opts->ocsp_default_responder =
+                             talloc_strdup(cert_verify_opts,
+                                           &opts[c][OCSP_DEFAUL_RESPONDER_LEN]);
+            if (cert_verify_opts->ocsp_default_responder == NULL
+                    || *cert_verify_opts->ocsp_default_responder == '\0') {
+                DEBUG(SSSDBG_CRIT_FAILURE,
+                      "Failed to parse ocsp_default_responder option [%s].\n",
+                      opts[c]);
+                ret = EINVAL;
+                goto done;
+            }
+
+            DEBUG(SSSDBG_TRACE_ALL, "Using OCSP default responder [%s]\n",
+                                    cert_verify_opts->ocsp_default_responder);
+        } else if (strncasecmp(opts[c],
+                               OCSP_DEFAUL_RESPONDER_SIGNING_CERT,
+                               OCSP_DEFAUL_RESPONDER_SIGNING_CERT_LEN) == 0) {
+            cert_verify_opts->ocsp_default_responder_signing_cert =
+                talloc_strdup(cert_verify_opts,
+                              &opts[c][OCSP_DEFAUL_RESPONDER_SIGNING_CERT_LEN]);
+            if (cert_verify_opts->ocsp_default_responder_signing_cert == NULL
+                    || *cert_verify_opts->ocsp_default_responder_signing_cert
+                                                                      == '\0') {
+                DEBUG(SSSDBG_CRIT_FAILURE,
+                      "Failed to parse ocsp_default_responder_signing_cert "
+                      "option [%s].\n", opts[c]);
+                ret = EINVAL;
+                goto done;
+            }
+
+            DEBUG(SSSDBG_TRACE_ALL,
+                  "Using OCSP default responder signing cert nickname [%s]\n",
+                  cert_verify_opts->ocsp_default_responder_signing_cert);
+        } else if (strncasecmp(opts[c], CRL_FILE, CRL_FILE_LEN) == 0) {
+            cert_verify_opts->crl_file = talloc_strdup(cert_verify_opts,
+                                                       &opts[c][CRL_FILE_LEN]);
+            if (cert_verify_opts->crl_file == NULL
+                    || *cert_verify_opts->crl_file == '\0') {
+                DEBUG(SSSDBG_CRIT_FAILURE,
+                      "Failed to parse crl_file option [%s].\n", opts[c]);
+                ret = EINVAL;
+                goto done;
+            }
+        } else {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "Unsupported certificate verification option [%s], " \
+                  "skipping.\n", opts[c]);
+        }
+    }
+
+#ifdef HAVE_NSS
+    if ((cert_verify_opts->ocsp_default_responder == NULL
+            && cert_verify_opts->ocsp_default_responder_signing_cert != NULL)
+        || (cert_verify_opts->ocsp_default_responder != NULL
+            && cert_verify_opts->ocsp_default_responder_signing_cert == NULL)) {
+
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "ocsp_default_responder and ocsp_default_responder_signing_cert "
+              "must be used together.\n");
+
+        ret = EINVAL;
+        goto done;
+    }
+#endif
+
+    ret = EOK;
+
+done:
+    if (ret == EOK) {
+        *_cert_verify_opts = talloc_steal(mem_ctx, cert_verify_opts);
+    }
+
+    talloc_free(tmp_ctx);
+
+    return ret;
+}
diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c
index cf1c2ae678..4bff56bb97 100644
--- a/src/tests/cmocka/test_utils.c
+++ b/src/tests/cmocka/test_utils.c
@@ -26,6 +26,7 @@
 
 #include "tests/cmocka/common_mock.h"
 #include "util/sss_nss.h"
+#include "p11_child/p11_child.h"
 #include "test_utils.h"
 
 #define TESTS_PATH "tp_" BASE_FILE_STEM
diff --git a/src/util/util.c b/src/util/util.c
index a893fac56d..b72877e278 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -1010,159 +1010,6 @@ errno_t sss_unique_filename(TALLOC_CTX *owner, char *path_tmpl)
     return ret;
 }
 
-static struct cert_verify_opts *init_cert_verify_opts(TALLOC_CTX *mem_ctx)
-{
-    struct cert_verify_opts *cert_verify_opts;
-
-    cert_verify_opts = talloc_zero(mem_ctx, struct cert_verify_opts);
-    if (cert_verify_opts == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
-        return NULL;
-    }
-
-    cert_verify_opts->do_ocsp = true;
-    cert_verify_opts->do_verification = true;
-    cert_verify_opts->ocsp_default_responder = NULL;
-    cert_verify_opts->ocsp_default_responder_signing_cert = NULL;
-    cert_verify_opts->crl_file = NULL;
-
-    return cert_verify_opts;
-}
-
-#define OCSP_DEFAUL_RESPONDER "ocsp_default_responder="
-#define OCSP_DEFAUL_RESPONDER_LEN (sizeof(OCSP_DEFAUL_RESPONDER) - 1)
-
-#define OCSP_DEFAUL_RESPONDER_SIGNING_CERT \
-                                          "ocsp_default_responder_signing_cert="
-#define OCSP_DEFAUL_RESPONDER_SIGNING_CERT_LEN \
-                                (sizeof(OCSP_DEFAUL_RESPONDER_SIGNING_CERT) - 1)
-#define CRL_FILE "crl_file="
-#define CRL_FILE_LEN (sizeof(CRL_FILE) -1)
-
-errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts,
-                               struct cert_verify_opts **_cert_verify_opts)
-{
-    int ret;
-    TALLOC_CTX *tmp_ctx;
-    char **opts;
-    size_t c;
-    struct cert_verify_opts *cert_verify_opts;
-
-    tmp_ctx = talloc_new(NULL);
-    if (tmp_ctx == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
-        return ENOMEM;
-    }
-
-    cert_verify_opts = init_cert_verify_opts(tmp_ctx);
-    if (cert_verify_opts == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, "init_cert_verify_opts failed.\n");
-        ret = ENOMEM;
-        goto done;
-    }
-
-    if (verify_opts == NULL) {
-        ret = EOK;
-        goto done;
-    }
-
-    ret = split_on_separator(tmp_ctx, verify_opts, ',', true, true, &opts,
-                             NULL);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_OP_FAILURE, "split_on_separator failed.\n");
-        goto done;
-    }
-
-    for (c = 0; opts[c] != NULL; c++) {
-        if (strcasecmp(opts[c], "no_ocsp") == 0) {
-            DEBUG(SSSDBG_TRACE_ALL,
-                  "Found 'no_ocsp' option, disabling OCSP.\n");
-            cert_verify_opts->do_ocsp = false;
-        } else if (strcasecmp(opts[c], "no_verification") == 0) {
-            DEBUG(SSSDBG_CRIT_FAILURE,
-                  "Found 'no_verification' option, "
-                  "disabling verification completely. "
-                  "This should not be used in production.\n");
-            cert_verify_opts->do_verification = false;
-        } else if (strncasecmp(opts[c], OCSP_DEFAUL_RESPONDER,
-                               OCSP_DEFAUL_RESPONDER_LEN) == 0) {
-            cert_verify_opts->ocsp_default_responder =
-                             talloc_strdup(cert_verify_opts,
-                                           &opts[c][OCSP_DEFAUL_RESPONDER_LEN]);
-            if (cert_verify_opts->ocsp_default_responder == NULL
-                    || *cert_verify_opts->ocsp_default_responder == '\0') {
-                DEBUG(SSSDBG_CRIT_FAILURE,
-                      "Failed to parse ocsp_default_responder option [%s].\n",
-                      opts[c]);
-                ret = EINVAL;
-                goto done;
-            }
-
-            DEBUG(SSSDBG_TRACE_ALL, "Using OCSP default responder [%s]\n",
-                                    cert_verify_opts->ocsp_default_responder);
-        } else if (strncasecmp(opts[c],
-                               OCSP_DEFAUL_RESPONDER_SIGNING_CERT,
-                               OCSP_DEFAUL_RESPONDER_SIGNING_CERT_LEN) == 0) {
-            cert_verify_opts->ocsp_default_responder_signing_cert =
-                talloc_strdup(cert_verify_opts,
-                              &opts[c][OCSP_DEFAUL_RESPONDER_SIGNING_CERT_LEN]);
-            if (cert_verify_opts->ocsp_default_responder_signing_cert == NULL
-                    || *cert_verify_opts->ocsp_default_responder_signing_cert
-                                                                      == '\0') {
-                DEBUG(SSSDBG_CRIT_FAILURE,
-                      "Failed to parse ocsp_default_responder_signing_cert "
-                      "option [%s].\n", opts[c]);
-                ret = EINVAL;
-                goto done;
-            }
-
-            DEBUG(SSSDBG_TRACE_ALL,
-                  "Using OCSP default responder signing cert nickname [%s]\n",
-                  cert_verify_opts->ocsp_default_responder_signing_cert);
-        } else if (strncasecmp(opts[c], CRL_FILE, CRL_FILE_LEN) == 0) {
-            cert_verify_opts->crl_file = talloc_strdup(cert_verify_opts,
-                                                       &opts[c][CRL_FILE_LEN]);
-            if (cert_verify_opts->crl_file == NULL
-                    || *cert_verify_opts->crl_file == '\0') {
-                DEBUG(SSSDBG_CRIT_FAILURE,
-                      "Failed to parse crl_file option [%s].\n", opts[c]);
-                ret = EINVAL;
-                goto done;
-            }
-        } else {
-            DEBUG(SSSDBG_CRIT_FAILURE,
-                  "Unsupported certificate verification option [%s], " \
-                  "skipping.\n", opts[c]);
-        }
-    }
-
-#ifdef HAVE_NSS
-    if ((cert_verify_opts->ocsp_default_responder == NULL
-            && cert_verify_opts->ocsp_default_responder_signing_cert != NULL)
-        || (cert_verify_opts->ocsp_default_responder != NULL
-            && cert_verify_opts->ocsp_default_responder_signing_cert == NULL)) {
-
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "ocsp_default_responder and ocsp_default_responder_signing_cert "
-              "must be used together.\n");
-
-        ret = EINVAL;
-        goto done;
-    }
-#endif
-
-    ret = EOK;
-
-done:
-    if (ret == EOK) {
-        *_cert_verify_opts = talloc_steal(mem_ctx, cert_verify_opts);
-    }
-
-    talloc_free(tmp_ctx);
-
-    return ret;
-}
-
 bool is_user_or_group_name(const char *sudo_user_value)
 {
     if (sudo_user_value == NULL) {
diff --git a/src/util/util.h b/src/util/util.h
index c5680d89ae..bc69415b7f 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -365,17 +365,6 @@ int split_on_separator(TALLOC_CTX *mem_ctx, const char *str,
 
 char **parse_args(const char *str);
 
-struct cert_verify_opts {
-    bool do_ocsp;
-    bool do_verification;
-    char *ocsp_default_responder;
-    char *ocsp_default_responder_signing_cert;
-    char *crl_file;
-};
-
-errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts,
-                               struct cert_verify_opts **cert_verify_opts);
-
 errno_t sss_hash_create(TALLOC_CTX *mem_ctx,
                         unsigned long count,
                         hash_table_t **tbl);

From a4c20fe30548b340930e6f37e094089e1c350859 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Tue, 25 Jun 2019 12:52:55 +0200
Subject: [PATCH 3/3] p11_child: make OCSP digest configurable

Currently sha1 is used to create the certid for an OCSP request. Since
sha1 is not recommend for new applications anymore and not FIPS
compliant this patch changes the default to sha256 and makes the digest
function configurable as well.

Related to https://pagure.io/SSSD/sssd/issue/4032
---
 Makefile.am                            | 13 +++++++++++
 src/man/sssd.conf.5.xml                | 20 +++++++++++++++++
 src/p11_child/p11_child.h              |  8 +++++++
 src/p11_child/p11_child_common_utils.c | 25 +++++++++++++++++++++
 src/p11_child/p11_child_openssl.c      | 31 +++++++++++++++++++++++++-
 5 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index 043a7ebb44..1c5aaad5ad 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3034,12 +3034,24 @@ test_ipa_idmap_LDADD = \
 test_utils_SOURCES = \
     src/tests/cmocka/test_utils.c \
     src/tests/cmocka/test_string_utils.c \
+    src/p11_child/p11_child_common_utils.c \
     $(NULL)
 if BUILD_SSH
 test_utils_SOURCES += src/tests/cmocka/test_sss_ssh.c
 endif
 test_utils_CFLAGS = \
     $(AM_CFLAGS)
+if HAVE_NSS
+test_utils_CFLAGS += \
+    $(NSS_CFLAGS) \
+    $(NULL)
+else
+test_utils_CFLAGS += \
+    $(P11_KIT_CFLAGS) \
+    $(CRYPTO_CFLAGS) \
+    $(SSL_CFLAGS) \
+    $(NULL)
+endif
 test_utils_LDADD = \
     $(CMOCKA_LIBS) \
     $(POPT_LIBS) \
@@ -4660,6 +4672,7 @@ proxy_child_LDADD = \
 
 p11_child_SOURCES = \
     src/p11_child/p11_child_common.c \
+    src/p11_child/p11_child_common_utils.c \
     src/util/atomic_io.c \
     src/util/util.c \
     src/util/util_ext.c \
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 591c01bd00..1a76a70f06 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -462,6 +462,26 @@
                                         the client.</para>
                                     </listitem>
                                 </varlistentry>
+                                <varlistentry>
+                                    <term>ocsp_dgst</term>
+                                    <listitem>
+                                        <para>Digest (hash) function used to
+                                        create the certificate ID for the OCSP
+                                        request. Allowed values are:
+                                        <itemizedlist>
+                                          <listitem><para>sha1</para></listitem>
+                                          <listitem><para>sha256</para></listitem>
+                                          <listitem><para>sha384</para></listitem>
+                                          <listitem><para>sha512</para></listitem>
+                                        </itemizedlist></para>
+                                        <para>
+                                            Default: sha256
+                                        </para>
+                                        <para>(NSS Version) This option is
+                                        ignored, because NSS uses sha1
+                                        unconditionally.</para>
+                                    </listitem>
+                                </varlistentry>
                                 <varlistentry>
                                     <term>no_verification</term>
                                     <listitem>
diff --git a/src/p11_child/p11_child.h b/src/p11_child/p11_child.h
index d31a76f92d..7dec5310b6 100644
--- a/src/p11_child/p11_child.h
+++ b/src/p11_child/p11_child.h
@@ -25,6 +25,13 @@
 #ifndef __P11_CHILD_H__
 #define __P11_CHILD_H__
 
+/* for CK_MECHANISM_TYPE */
+#ifdef HAVE_NSS
+#include <pkcs11t.h>
+#else
+#include <p11-kit/pkcs11.h>
+#endif
+
 /* Time to wait during a C_Finalize C_Initialize cycle to discover
  * new slots. */
 #define PKCS11_FINIALIZE_INITIALIZE_WAIT_TIME 3
@@ -36,6 +43,7 @@ struct cert_verify_opts {
     char *ocsp_default_responder;
     char *ocsp_default_responder_signing_cert;
     char *crl_file;
+    CK_MECHANISM_TYPE ocsp_dgst;
 };
 
 enum op_mode {
diff --git a/src/p11_child/p11_child_common_utils.c b/src/p11_child/p11_child_common_utils.c
index 0374eff0ab..abfd97cf75 100644
--- a/src/p11_child/p11_child_common_utils.c
+++ b/src/p11_child/p11_child_common_utils.c
@@ -43,6 +43,7 @@ static struct cert_verify_opts *init_cert_verify_opts(TALLOC_CTX *mem_ctx)
     cert_verify_opts->ocsp_default_responder = NULL;
     cert_verify_opts->ocsp_default_responder_signing_cert = NULL;
     cert_verify_opts->crl_file = NULL;
+    cert_verify_opts->ocsp_dgst = CKM_SHA256;
 
     return cert_verify_opts;
 }
@@ -57,6 +58,9 @@ static struct cert_verify_opts *init_cert_verify_opts(TALLOC_CTX *mem_ctx)
 #define CRL_FILE "crl_file="
 #define CRL_FILE_LEN (sizeof(CRL_FILE) -1)
 
+#define OCSP_DGST "ocsp_dgst="
+#define OCSP_DGST_LEN (sizeof(OCSP_DGST) -1)
+
 errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts,
                                struct cert_verify_opts **_cert_verify_opts)
 {
@@ -147,6 +151,27 @@ errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts,
                 ret = EINVAL;
                 goto done;
             }
+        } else if (strncasecmp(opts[c], OCSP_DGST, OCSP_DGST_LEN) == 0) {
+#ifdef HAVE_NSS
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "Option [%s] is not supported in NSS build, ignored.\n",
+                  OCSP_DGST);
+#else
+            if (strcmp("sha1", &opts[c][OCSP_DGST_LEN]) == 0) {
+                cert_verify_opts->ocsp_dgst = CKM_SHA_1;
+            } else  if (strcmp("sha256", &opts[c][OCSP_DGST_LEN]) == 0) {
+                cert_verify_opts->ocsp_dgst = CKM_SHA256;
+            } else  if (strcmp("sha384", &opts[c][OCSP_DGST_LEN]) == 0) {
+                cert_verify_opts->ocsp_dgst = CKM_SHA384;
+            } else  if (strcmp("sha512", &opts[c][OCSP_DGST_LEN]) == 0) {
+                cert_verify_opts->ocsp_dgst = CKM_SHA512;
+            } else {
+                DEBUG(SSSDBG_CRIT_FAILURE,
+                      "Unsupported digest for OCSP [%s], "
+                      "using default sha256.\n", &opts[c][OCSP_DGST_LEN]);
+                cert_verify_opts->ocsp_dgst = CKM_SHA256;
+            }
+#endif
         } else {
             DEBUG(SSSDBG_CRIT_FAILURE,
                   "Unsupported certificate verification option [%s], " \
diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c
index 75e4bef8e1..017b022a82 100644
--- a/src/p11_child/p11_child_openssl.c
+++ b/src/p11_child/p11_child_openssl.c
@@ -179,6 +179,28 @@ OCSP_RESPONSE *process_responder(OCSP_REQUEST *req,
     return resp;
 }
 
+static const EVP_MD *get_dgst(CK_MECHANISM_TYPE ocsp_dgst)
+{
+    switch (ocsp_dgst) {
+    case CKM_SHA_1:
+        return EVP_sha1();
+        break;
+    case CKM_SHA256:
+        return EVP_sha256();
+        break;
+    case CKM_SHA384:
+        return EVP_sha384();
+        break;
+    case CKM_SHA512:
+        return EVP_sha512();
+        break;
+    default:
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported digest type [%lu].\n",
+                                   ocsp_dgst);
+    }
+    return NULL;
+}
+
 static errno_t do_ocsp(struct p11_ctx *p11_ctx, X509 *cert)
 {
     OCSP_REQUEST *ocsp_req = NULL;
@@ -204,6 +226,7 @@ static errno_t do_ocsp(struct p11_ctx *p11_ctx, X509 *cert)
     X509_NAME *issuer_name = NULL;
     X509_OBJECT *x509_obj;
     STACK_OF(X509_OBJECT) *store_objects;
+    const EVP_MD *ocsp_dgst = NULL;
 
     ocsp_urls = X509_get1_ocsp(cert);
     if (ocsp_urls == NULL
@@ -268,7 +291,13 @@ static errno_t do_ocsp(struct p11_ctx *p11_ctx, X509 *cert)
         goto done;
     }
 
-    cid = OCSP_cert_to_id(EVP_sha1(), cert, issuer);
+    ocsp_dgst = get_dgst(p11_ctx->cert_verify_opts->ocsp_dgst);
+    if (ocsp_dgst == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "Cannot determine configured digest function "
+                                 "for OCSP, using default sha256.\n");
+        ocsp_dgst = EVP_sha256();
+    }
+    cid = OCSP_cert_to_id(ocsp_dgst, cert, issuer);
     if (cid == NULL) {
         DEBUG(SSSDBG_OP_FAILURE, "OCSP_cert_to_id failed.\n");
         ret = EIO;
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/sssd-devel@lists.fedorahosted.org

Reply via email to