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

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 2b2a5b135d454cde6dc7132e9e63481201b8a4c7 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 a17e5e6f78304fd457beae9fef885d6644cab330 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
---
 Makefile.am                            |  11 ++
 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 --
 6 files changed, 205 insertions(+), 164 deletions(-)
 create mode 100644 src/p11_child/p11_child_common_utils.c

diff --git a/Makefile.am b/Makefile.am
index 043a7ebb44..fa28b1dfd5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3034,12 +3034,22 @@ 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) \
+    $(NULL)
+endif
 test_utils_LDADD = \
     $(CMOCKA_LIBS) \
     $(POPT_LIBS) \
@@ -4660,6 +4670,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/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 0209a41574e962a9201a9634172c505fcf987444 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Mon, 1 Jul 2019 14:39:49 +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
---
 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 +++++++++++++++++++++++++-
 4 files changed, 83 insertions(+), 1 deletion(-)

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