URL: https://github.com/SSSD/sssd/pull/5855 Author: alexey-tikhonov Title: #5855: CKM_RSA_PKCS support. Action: synchronized
To pull the PR as Git branch: git remote add ghsssd https://github.com/SSSD/sssd git fetch ghsssd pull/5855/head:pr5855 git checkout pr5855
From 820a328ea37c5d99721fcc37486a05b984ac331e Mon Sep 17 00:00:00 2001 From: Alexey Tikhonov <atikh...@redhat.com> Date: Thu, 28 Oct 2021 13:49:11 +0200 Subject: [PATCH 1/3] P11: refactoring of get_preferred_rsa_mechanism() Flattened code structure and more accurate errors handling. --- src/p11_child/p11_child_openssl.c | 75 +++++++++++++++++-------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c index 27ee18bba6..3bceae651b 100644 --- a/src/p11_child/p11_child_openssl.c +++ b/src/p11_child/p11_child_openssl.c @@ -1313,7 +1313,7 @@ static CK_RV get_preferred_rsa_mechanism(TALLOC_CTX *mem_ctx, CK_RV rv; size_t c; size_t m; - struct prefs { + const struct prefs { CK_MECHANISM_TYPE mech; const char *mech_name; const EVP_MD *evp_md; @@ -1327,44 +1327,51 @@ static CK_RV get_preferred_rsa_mechanism(TALLOC_CTX *mem_ctx, { 0, NULL, NULL, NULL } }; - *preferred_mechanism = CKM_SHA1_RSA_PKCS; - *preferred_evp_md = EVP_sha1(); - rv = module->C_GetMechanismList(slot_id, NULL, &count); - if (rv == CKR_OK && count > 0) { - mechanism_list = talloc_size(mem_ctx, - count * sizeof(CK_MECHANISM_TYPE)); - if (mechanism_list != NULL) { - rv = module->C_GetMechanismList(slot_id, mechanism_list, &count); - if (rv == CKR_OK) { - for (m = 0; m < count; m++) { - DEBUG(SSSDBG_TRACE_ALL, "Found mechanism [%lu].\n", - mechanism_list[m]); - } - for (c = 0; prefs[c].mech != 0; c++) { - for (m = 0; m < count; m++) { - if (prefs[c].mech == mechanism_list[m]) { - *preferred_mechanism = prefs[c].mech; - *preferred_evp_md = prefs[c].evp_md; - DEBUG(SSSDBG_FUNC_DATA, - "Using PKCS#11 mechanism [%lu][%s] and " - "local message digest [%s].\n", - *preferred_mechanism, prefs[c].mech_name, - prefs[c].md_name); - break; - } - } - if (m != count) { - break; - } - } + if (rv != CKR_OK) { + DEBUG(SSSDBG_MINOR_FAILURE, "C_GetMechanismList failed: [%lu][%s]\n", + rv, p11_kit_strerror(rv)); + return rv; + } + if (count == 0) { + DEBUG(SSSDBG_MINOR_FAILURE, "No mechanism found\n"); + return CKR_GENERAL_ERROR; + } + + mechanism_list = talloc_size(mem_ctx, count * sizeof(CK_MECHANISM_TYPE)); + if (mechanism_list == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Failed to allocate memory\n"); + return CKR_GENERAL_ERROR; + } + + rv = module->C_GetMechanismList(slot_id, mechanism_list, &count); + if (rv != CKR_OK) { + DEBUG(SSSDBG_MINOR_FAILURE, "2nd C_GetMechanismList failed: [%lu][%s]\n", + rv, p11_kit_strerror(rv)); + return rv; + } + + for (m = 0; m < count; m++) { + DEBUG(SSSDBG_TRACE_ALL, "Found mechanism [%lu].\n", mechanism_list[m]); + } + for (c = 0; prefs[c].mech != 0; c++) { + for (m = 0; m < count; m++) { + if (prefs[c].mech == mechanism_list[m]) { + *preferred_mechanism = prefs[c].mech; + *preferred_evp_md = prefs[c].evp_md; + DEBUG(SSSDBG_FUNC_DATA, + "Using PKCS#11 mechanism [%lu][%s] and " + "local message digest [%s].\n", + *preferred_mechanism, prefs[c].mech_name, + prefs[c].md_name); + talloc_free(mechanism_list); + return CKR_OK; } } } - talloc_free(mechanism_list); - - return rv; + DEBUG(SSSDBG_MINOR_FAILURE, "No match found\n"); + return CKR_GENERAL_ERROR; } static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, From f8572b87a0acc7451282b973da80c8e9421c04cf Mon Sep 17 00:00:00 2001 From: Alexey Tikhonov <atikh...@redhat.com> Date: Thu, 28 Oct 2021 14:05:58 +0200 Subject: [PATCH 2/3] P11: add support of 'CKM_RSA_PKCS' mechanism Resolves: https://github.com/SSSD/sssd/issues/5854 --- src/p11_child/p11_child_openssl.c | 51 ++++++++++++++++++------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c index 3bceae651b..be9bc42421 100644 --- a/src/p11_child/p11_child_openssl.c +++ b/src/p11_child/p11_child_openssl.c @@ -1137,24 +1137,29 @@ static CK_KEY_TYPE get_key_type(CK_FUNCTION_LIST *module, return type; } -static int do_hash(TALLOC_CTX *mem_ctx, const EVP_MD *evp_md, - CK_BYTE *in, size_t in_len, - CK_BYTE **hash, size_t *hash_len) +static int do_sha512(TALLOC_CTX *mem_ctx, CK_BYTE *in, size_t in_len, + bool add_info, CK_BYTE **_hash, size_t *_hash_len) { EVP_MD_CTX *md_ctx = NULL; int ret; unsigned char md_value[EVP_MAX_MD_SIZE]; unsigned int md_len; CK_BYTE *out = NULL; + const CK_BYTE info[] = + { /* https://datatracker.ietf.org/doc/html/rfc3447#page-43 : + the DER encoding T of the DigestInfo value for SHA-512 */ + 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 + }; + const unsigned int info_len = add_info ? sizeof(info) : 0; md_ctx = EVP_MD_CTX_create(); if (md_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "EVP_MD_CTX_create failed.\n"); - ret = ENOMEM; - goto done; + return ENOMEM; } - ret = EVP_DigestInit(md_ctx, evp_md); + ret = EVP_DigestInit(md_ctx, EVP_sha512()); if (ret != 1) { DEBUG(SSSDBG_OP_FAILURE, "EVP_DigestInit failed.\n"); ret = EINVAL; @@ -1175,27 +1180,26 @@ static int do_hash(TALLOC_CTX *mem_ctx, const EVP_MD *evp_md, goto done; } - out = talloc_size(mem_ctx, md_len * sizeof(CK_BYTE)); + out = talloc_size(mem_ctx, info_len + md_len * sizeof(CK_BYTE)); if (out == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); ret = ENOMEM; goto done; } - memcpy(out, md_value, md_len); + if (add_info) { + memcpy(out, info, info_len); + } + + memcpy(out + info_len, md_value, md_len); - *hash = out; - *hash_len = md_len; + *_hash = out; + *_hash_len = info_len + md_len; ret = EOK; done: - EVP_MD_CTX_free(md_ctx); - if (ret != EOK) { - free(out); - } - return ret; } @@ -1323,6 +1327,7 @@ static CK_RV get_preferred_rsa_mechanism(TALLOC_CTX *mem_ctx, { CKM_SHA384_RSA_PKCS, "CKM_SHA384_RSA_PKCS", EVP_sha384(), "sha384" }, { CKM_SHA256_RSA_PKCS, "CKM_SHA256_RSA_PKCS", EVP_sha256(), "sha256" }, { CKM_SHA224_RSA_PKCS, "CKM_SHA224_RSA_PKCS", EVP_sha224(), "sha224" }, + { CKM_RSA_PKCS, "CKM_RSA_PKCS", NULL, "-none-" }, { CKM_SHA1_RSA_PKCS, "CKM_SHA1_RSA_PKCS", EVP_sha1(), "sha1" }, { 0, NULL, NULL, NULL } }; @@ -1360,8 +1365,8 @@ static CK_RV get_preferred_rsa_mechanism(TALLOC_CTX *mem_ctx, *preferred_mechanism = prefs[c].mech; *preferred_evp_md = prefs[c].evp_md; DEBUG(SSSDBG_FUNC_DATA, - "Using PKCS#11 mechanism [%lu][%s] and " - "local message digest [%s].\n", + "Using PKCS#11 mechanism [%lu][%s] with " + "message digest [%s].\n", *preferred_mechanism, prefs[c].mech_name, prefs[c].md_name); talloc_free(mechanism_list); @@ -1447,12 +1452,11 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, DEBUG(SSSDBG_TRACE_ALL, "Found RSA key using mechanism [%lu].\n", preferred_mechanism); mechanism.mechanism = preferred_mechanism; - card_does_hash = true; + card_does_hash = (evp_md != NULL); break; case CKK_EC: DEBUG(SSSDBG_TRACE_ALL, "Found ECC key using CKM_ECDSA.\n"); mechanism.mechanism = CKM_ECDSA; - evp_md = EVP_sha512(); card_does_hash = false; break; case CK_UNAVAILABLE_INFORMATION: @@ -1482,8 +1486,10 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, val_to_sign = random_value; val_to_sign_len = sizeof(random_value); } else { - ret = do_hash(cert, evp_md, random_value, sizeof(random_value), - &hash_val, &hash_len); + evp_md = EVP_sha512(); + ret = do_sha512(cert, random_value, sizeof(random_value), + (mechanism.mechanism == CKM_RSA_PKCS), /* add_info */ + &hash_val, &hash_len); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "do_hash failed.\n"); return ret; @@ -1559,7 +1565,8 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, } else { ret = EVP_VerifyFinal(md_ctx, signature, signature_size, cert_pub_key); if (ret != 1) { - DEBUG(SSSDBG_OP_FAILURE, "EVP_VerifyFinal failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, "EVP_VerifyFinal failed: '%s'\n", + ERR_reason_error_string(ERR_peek_last_error())); ret = EINVAL; goto done; } From 0822cb0a27cff128cc6e8e6561ec6b475019837a Mon Sep 17 00:00:00 2001 From: Alexey Tikhonov <atikh...@redhat.com> Date: Thu, 4 Nov 2021 22:17:45 +0100 Subject: [PATCH 3/3] TESTS: added two tests to check cert auth with specific RSA mechanisms: CKM_RSA_PKCS and CKM_SHA384_RSA_PKCS. (CKM_SHA384_RSA_PKCS is arbitrary chosen as one of CKM_SHA*_RSA_PKCS family) --- src/tests/cmocka/test_pam_srv.c | 24 ++++++++++++++++++++++++ src/tests/test_CA/Makefile.am | 26 +++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c index e00b585c13..c86c32a907 100644 --- a/src/tests/cmocka/test_pam_srv.c +++ b/src/tests/cmocka/test_pam_srv.c @@ -329,6 +329,24 @@ static int pam_test_setup_no_verification(void **state) pam_test_setup_common(); return 0; } + +static int pam_test_setup_mech_rsa_pkcs(void **state) +{ + int rc = pam_test_setup_no_verification(state); + if (rc != 0) { + return rc; + } + return putenv(discard_const("SOFTHSM2_CONF=" ABS_BUILD_DIR "/src/tests/test_CA/softhsm2_mech_rsa_pkcs.conf")); +} + +static int pam_test_setup_mech_rsa_sha384_pkcs(void **state) +{ + int rc = pam_test_setup_no_verification(state); + if (rc != 0) { + return rc; + } + return putenv(discard_const("SOFTHSM2_CONF=" ABS_BUILD_DIR "/src/tests/test_CA/softhsm2_mech_rsa_sha384_pkcs.conf")); +} #endif /* HAVE_TEST_CA */ static int pam_cached_test_setup(void **state) @@ -3663,6 +3681,12 @@ int main(int argc, const char *argv[]) cmocka_unit_test_setup_teardown(test_pam_cert_auth, pam_test_setup_no_verification, pam_test_teardown), + cmocka_unit_test_setup_teardown(test_pam_cert_auth, + pam_test_setup_mech_rsa_pkcs, + pam_test_teardown), + cmocka_unit_test_setup_teardown(test_pam_cert_auth, + pam_test_setup_mech_rsa_sha384_pkcs, + pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_pss_cert_auth, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_ecc_cert_auth, diff --git a/src/tests/test_CA/Makefile.am b/src/tests/test_CA/Makefile.am index fdef3ab40f..59048214b1 100644 --- a/src/tests/test_CA/Makefile.am +++ b/src/tests/test_CA/Makefile.am @@ -29,7 +29,7 @@ pubkeys_h = $(addprefix SSSD_test_cert_pubsshkey_,$(addsuffix .h,$(ids))) pkcs12 = $(addprefix SSSD_test_cert_pkcs12_,$(addsuffix .pem,$(ids))) -extra = softhsm2_none softhsm2_one softhsm2_two softhsm2_2tokens softhsm2_ocsp softhsm2_2certs_same_id softhsm2_pss_one SSSD_test_cert_x509_0001.der SSSD_test_cert_x509_0007.der +extra = softhsm2_none softhsm2_one softhsm2_mech_rsa_pkcs softhsm2_mech_rsa_sha384_pkcs softhsm2_two softhsm2_2tokens softhsm2_ocsp softhsm2_2certs_same_id softhsm2_pss_one SSSD_test_cert_x509_0001.der SSSD_test_cert_x509_0007.der if HAVE_FAKETIME extra += SSSD_test_CA_expired_crl.pem endif @@ -119,6 +119,30 @@ softhsm2_one.conf: @echo "objectstore.backend = file" >> $@ @echo "slots.removable = true" >> $@ +softhsm2_mech_rsa_pkcs: softhsm2_mech_rsa_pkcs.conf + mkdir $@ + SOFTHSM2_CONF=./$< $(SOFTHSM2_UTIL) --init-token --label "SSSD Test Token" --pin 123456 --so-pin 123456 --free + GNUTLS_PIN=123456 SOFTHSM2_CONF=./$< $(P11TOOL) --provider=$(SOFTHSM2_PATH) --write --no-mark-private --load-certificate=SSSD_test_cert_x509_0001.pem --login --label 'SSSD test cert 0001' --id 'C554C9F82C2A9D58B70921C143304153A8A42F17' + GNUTLS_PIN=123456 SOFTHSM2_CONF=./$< $(P11TOOL) --provider=$(SOFTHSM2_PATH) --write --load-privkey=$(srcdir)/SSSD_test_cert_key_0001.pem --login --label 'SSSD test cert 0001' --id 'C554C9F82C2A9D58B70921C143304153A8A42F17' + +softhsm2_mech_rsa_pkcs.conf: + @echo "directories.tokendir = "$(abs_top_builddir)"/src/tests/test_CA/softhsm2_mech_rsa_pkcs" > $@ + @echo "objectstore.backend = file" >> $@ + @echo "slots.removable = true" >> $@ + @echo "slots.mechanisms = CKM_RSA_PKCS" >> $@ + +softhsm2_mech_rsa_sha384_pkcs: softhsm2_mech_rsa_sha384_pkcs.conf + mkdir $@ + SOFTHSM2_CONF=./$< $(SOFTHSM2_UTIL) --init-token --label "SSSD Test Token" --pin 123456 --so-pin 123456 --free + GNUTLS_PIN=123456 SOFTHSM2_CONF=./$< $(P11TOOL) --provider=$(SOFTHSM2_PATH) --write --no-mark-private --load-certificate=SSSD_test_cert_x509_0001.pem --login --label 'SSSD test cert 0001' --id 'C554C9F82C2A9D58B70921C143304153A8A42F17' + GNUTLS_PIN=123456 SOFTHSM2_CONF=./$< $(P11TOOL) --provider=$(SOFTHSM2_PATH) --write --load-privkey=$(srcdir)/SSSD_test_cert_key_0001.pem --login --label 'SSSD test cert 0001' --id 'C554C9F82C2A9D58B70921C143304153A8A42F17' + +softhsm2_mech_rsa_sha384_pkcs.conf: + @echo "directories.tokendir = "$(abs_top_builddir)"/src/tests/test_CA/softhsm2_mech_rsa_sha384_pkcs" > $@ + @echo "objectstore.backend = file" >> $@ + @echo "slots.removable = true" >> $@ + @echo "slots.mechanisms = CKM_SHA384_RSA_PKCS" >> $@ + #Export cert from softhsm2 via p11tool, should produce the same as openssl SSSD_test_cert_x509_0001.der: softhsm2_one.conf $(eval ID_VAR = $(shell GNUTLS_PIN=123456 SOFTHSM2_CONF=./$< $(P11TOOL) --provider=$(SOFTHSM2_PATH) --info|cut -d' ' -f2|grep ^pkcs11))
_______________________________________________ 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 Do not reply to spam on the list, report it: https://pagure.io/fedora-infrastructure