From a7421b5260cd2edd07ec5c0fefd240e76c5a0f03 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 9 Nov 2018 14:01:20 +0100
Subject: [PATCH 69/74] test_pam_srv: add test for certificate with EC keys
Add an authentication test with a certificate with EC keys.
Related to https://pagure.io/SSSD/sssd/issue/3887
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
src/tests/cmocka/test_pam_srv.c | 114 ++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index b29961255..f55e6222e 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -42,9 +42,13 @@
#ifdef HAVE_TEST_CA
#include "tests/test_CA/SSSD_test_cert_x509_0001.h"
#include "tests/test_CA/SSSD_test_cert_x509_0002.h"
+
+#include "tests/test_ECC_CA/SSSD_test_ECC_cert_x509_0001.h"
#else
#define SSSD_TEST_CERT_0001 ""
#define SSSD_TEST_CERT_0002 ""
+
+#define SSSD_TEST_ECC_CERT_0001 ""
#endif
#define TESTS_PATH "tp_" BASE_FILE_STEM
@@ -58,10 +62,16 @@
#define NSS_DB_PATH_2CERTS TESTS_PATH "_2certs"
#define NSS_DB_2CERTS "sql:"NSS_DB_PATH_2CERTS
+
+#define NSS_DB_PATH_ECC TESTS_PATH "_ecc"
+#define NSS_DB_ECC "sql:"NSS_DB_PATH_ECC
+
#ifdef HAVE_NSS
#define CA_DB NSS_DB
+#define ECC_CA_DB NSS_DB_ECC
#else
#define CA_DB ABS_BUILD_DIR"/src/tests/test_CA/SSSD_test_CA.pem"
+#define ECC_CA_DB ABS_BUILD_DIR"/src/tests/test_ECC_CA/SSSD_test_ECC_CA.pem"
#endif
#define TEST_TOKEN_NAME "SSSD Test Token"
@@ -122,6 +132,13 @@ static errno_t setup_nss_db(void)
return ret;
}
+ ret = mkdir(NSS_DB_PATH_ECC, 0775);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Failed to create " NSS_DB_PATH_ECC ".\n");
+ return ret;
+ }
+
child_pid = fork();
if (child_pid == 0) { /* child */
ret = execlp("certutil", "certutil", "-N", "--empty-password", "-d",
@@ -154,6 +171,22 @@ static errno_t setup_nss_db(void)
return ret;
}
+ child_pid = fork();
+ if (child_pid == 0) { /* child */
+ ret = execlp("certutil", "certutil", "-N", "--empty-password", "-d",
+ NSS_DB_ECC, NULL);
+ if (ret == -1) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "execl() failed.\n");
+ exit(-1);
+ }
+ } else if (child_pid > 0) {
+ wait(&status);
+ } else {
+ ret = errno;
+ DEBUG(SSSDBG_FATAL_FAILURE, "fork() failed\n");
+ return ret;
+ }
+
fp = fopen(NSS_DB_PATH"/pkcs11.txt", "w");
if (fp == NULL) {
DEBUG(SSSDBG_FATAL_FAILURE, "fopen() failed.\n");
@@ -196,6 +229,27 @@ static errno_t setup_nss_db(void)
return ret;
}
+ fp = fopen(NSS_DB_PATH_ECC"/pkcs11.txt", "w");
+ if (fp == NULL) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "fopen() failed.\n");
+ return ret;
+ }
+ ret = fprintf(fp, "library=libsoftokn3.so\nname=soft\n");
+ if (ret < 0) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "fprintf() failed.\n");
+ return ret;
+ }
+ ret = fprintf(fp, "parameters=configdir='sql:%s/src/tests/test_ECC_CA/p11_ecc_nssdb' dbSlotDescription='SSSD Test ECC Slot' dbTokenDescription='SSSD Test ECC Token' secmod='secmod.db' flags=readOnly \n\n", ABS_BUILD_DIR);
+ if (ret < 0) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "fprintf() failed.\n");
+ return ret;
+ }
+ ret = fclose(fp);
+ if (ret != 0) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "fclose() failed.\n");
+ return ret;
+ }
+
return EOK;
}
@@ -242,6 +296,26 @@ static void cleanup_nss_db(void)
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Failed to remove " NSS_DB_PATH "\n");
}
+
+ ret = unlink(NSS_DB_PATH_ECC"/cert9.db");
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove cert9.db.\n");
+ }
+
+ ret = unlink(NSS_DB_PATH_ECC"/key4.db");
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove key4.db.\n");
+ }
+
+ ret = unlink(NSS_DB_PATH_ECC"/pkcs11.txt");
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove pkcs11.db.\n");
+ }
+
+ ret = rmdir(NSS_DB_PATH_ECC);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove " NSS_DB_PATH "\n");
+ }
}
struct pam_ctx *mock_pctx(TALLOC_CTX *mem_ctx)
@@ -2347,6 +2421,44 @@ void test_pam_cert_auth(void **state)
assert_int_equal(ret, EOK);
}
+void test_pam_ecc_cert_auth(void **state)
+{
+ int ret;
+
+#ifndef HAVE_NSS
+ putenv(discard_const("SOFTHSM2_CONF=" ABS_BUILD_DIR "/src/tests/test_ECC_CA/softhsm2_ecc_one.conf"));
+#endif
+ set_cert_auth_param(pam_test_ctx->pctx, ECC_CA_DB);
+
+ /* Here the last option must be set to true because the backend is only
+ * connected once. During authentication the backend is connected first to
+ * see if it can handle Smartcard authentication, but before that the user
+ * is looked up. Since the first mocked reply already adds the certificate
+ * to the user entry the lookup by certificate will already find the user
+ * in the cache and no second request to the backend is needed. */
+ mock_input_pam_cert(pam_test_ctx, "pamuser", "123456",
+ "SSSD Test ECC Token",
+ TEST_MODULE_NAME,
+ "190E513C9A3DFAACDE5D2D0592F0FDFF559C10CB", NULL,
+ test_lookup_by_cert_cb, SSSD_TEST_ECC_CERT_0001, true);
+
+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+ /* Assume backend cannot handle Smartcard credentials */
+ pam_test_ctx->exp_pam_status = PAM_BAD_ITEM;
+
+
+ set_cmd_cb(test_pam_simple_check_success);
+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
+ pam_test_ctx->pam_cmds);
+ assert_int_equal(ret, EOK);
+
+ /* Wait until the test finishes with EOK */
+ ret = test_ev_loop(pam_test_ctx->tctx);
+ assert_int_equal(ret, EOK);
+}
+
void test_pam_cert_auth_no_logon_name(void **state)
{
int ret;
@@ -3022,6 +3134,8 @@ 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_ecc_cert_auth,
+ pam_test_setup, pam_test_teardown),
cmocka_unit_test_setup_teardown(test_pam_cert_auth_double_cert,
pam_test_setup, pam_test_teardown),
cmocka_unit_test_setup_teardown(test_pam_cert_preauth_2certs_one_mapping,
--
2.19.1