|
|
cde47b |
From fa5147c86941512921282b84819b896a0d4f29bb Mon Sep 17 00:00:00 2001
|
|
|
cde47b |
From: Daiki Ueno <dueno@redhat.com>
|
|
|
cde47b |
Date: Wed, 19 Jun 2019 17:21:16 +0200
|
|
|
cde47b |
Subject: [PATCH] pkcs11: ignore login error when traversing tokens
|
|
|
cde47b |
|
|
|
cde47b |
If a token is a general access device, it is expected that login
|
|
|
cde47b |
attempt to that token returns error:
|
|
|
cde47b |
https://github.com/p11-glue/p11-kit/blob/master/trust/module.c#L852
|
|
|
cde47b |
|
|
|
cde47b |
On the other hand, _pkcs11_traverse_tokens treats the error as fatal
|
|
|
cde47b |
and stops iteration. This behavior prevents object search without
|
|
|
cde47b |
token specifier if such tokens are registered in the system.
|
|
|
cde47b |
|
|
|
cde47b |
Reported by Stanislav Zidek in
|
|
|
cde47b |
https://bugzilla.redhat.com/show_bug.cgi?id=1705478
|
|
|
cde47b |
|
|
|
cde47b |
Signed-off-by: Daiki Ueno <dueno@redhat.com>
|
|
|
cde47b |
---
|
|
|
cde47b |
.gitignore | 1 +
|
|
|
cde47b |
lib/pkcs11.c | 8 +-
|
|
|
cde47b |
tests/Makefile.am | 2 +-
|
|
|
cde47b |
tests/p11-kit-load.sh | 23 ++++++
|
|
|
cde47b |
tests/pkcs11/list-objects.c | 150 ++++++++++++++++++++++++++++++++++++
|
|
|
cde47b |
5 files changed, 182 insertions(+), 2 deletions(-)
|
|
|
cde47b |
create mode 100644 tests/pkcs11/list-objects.c
|
|
|
cde47b |
|
|
|
cde47b |
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
|
|
|
cde47b |
index de5309b29..2ef0e3e02 100644
|
|
|
cde47b |
--- a/lib/pkcs11.c
|
|
|
cde47b |
+++ b/lib/pkcs11.c
|
|
|
cde47b |
@@ -1617,7 +1617,13 @@ _pkcs11_traverse_tokens(find_func_t find_func, void *input,
|
|
|
cde47b |
info, flags);
|
|
|
cde47b |
if (ret < 0) {
|
|
|
cde47b |
gnutls_assert();
|
|
|
cde47b |
- return ret;
|
|
|
cde47b |
+ pkcs11_close_session(&sinfo);
|
|
|
cde47b |
+
|
|
|
cde47b |
+ /* treat the error as fatal only if
|
|
|
cde47b |
+ * the token requires login */
|
|
|
cde47b |
+ if (l_tinfo.flags & CKF_LOGIN_REQUIRED)
|
|
|
cde47b |
+ return ret;
|
|
|
cde47b |
+ continue;
|
|
|
cde47b |
}
|
|
|
cde47b |
|
|
|
cde47b |
ret =
|
|
|
cde47b |
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
|
|
cde47b |
index a67f1549c..7fe954f63 100644
|
|
|
cde47b |
--- a/tests/Makefile.am
|
|
|
cde47b |
+++ b/tests/Makefile.am
|
|
|
cde47b |
@@ -496,7 +496,7 @@ dist_check_SCRIPTS += p11-kit-trust.sh testpkcs11.sh certtool-pkcs11.sh
|
|
|
cde47b |
if HAVE_PKCS11_TRUST_STORE
|
|
|
cde47b |
if P11KIT_0_23_11_API
|
|
|
cde47b |
dist_check_SCRIPTS += p11-kit-load.sh
|
|
|
cde47b |
-indirect_tests += pkcs11/list-tokens
|
|
|
cde47b |
+indirect_tests += pkcs11/list-tokens pkcs11/list-objects
|
|
|
cde47b |
endif
|
|
|
cde47b |
endif
|
|
|
cde47b |
|
|
|
cde47b |
diff --git a/tests/p11-kit-load.sh b/tests/p11-kit-load.sh
|
|
|
cde47b |
index 3201a2c5f..419900f6a 100755
|
|
|
cde47b |
--- a/tests/p11-kit-load.sh
|
|
|
cde47b |
+++ b/tests/p11-kit-load.sh
|
|
|
cde47b |
@@ -22,6 +22,7 @@
|
|
|
cde47b |
srcdir="${srcdir:-.}"
|
|
|
cde47b |
builddir="${builddir:-.}"
|
|
|
cde47b |
CERTTOOL="${CERTTOOL:-../src/certtool${EXEEXT}}"
|
|
|
cde47b |
+P11TOOL="${P11TOOL:-../src/p11tool${EXEEXT}}"
|
|
|
cde47b |
DIFF="${DIFF:-diff}"
|
|
|
cde47b |
PKGCONFIG="${PKG_CONFIG:-$(which pkg-config)}"
|
|
|
cde47b |
TMP_SOFTHSM_DIR="./softhsm-load.$$.tmp"
|
|
|
cde47b |
@@ -90,6 +91,12 @@ if test $? != 0; then
|
|
|
cde47b |
exit 1
|
|
|
cde47b |
fi
|
|
|
cde47b |
|
|
|
cde47b |
+GNUTLS_PIN="${PIN}" ${P11TOOL} --login --label GnuTLS-Test-RSA --generate-privkey rsa --provider "${SOFTHSM_MODULE}" pkcs11: --outfile /dev/null
|
|
|
cde47b |
+if test $? != 0; then
|
|
|
cde47b |
+ echo "failed to generate privkey"
|
|
|
cde47b |
+ exit 1
|
|
|
cde47b |
+fi
|
|
|
cde47b |
+
|
|
|
cde47b |
FILTERTOKEN="sed s/token=.*//g"
|
|
|
cde47b |
|
|
|
cde47b |
# Check whether both are listed
|
|
|
cde47b |
@@ -175,6 +182,22 @@ if test "$nr" != 2;then
|
|
|
cde47b |
exit 1
|
|
|
cde47b |
fi
|
|
|
cde47b |
|
|
|
cde47b |
+# Check whether public key and privkey are listed.
|
|
|
cde47b |
+nr=$(GNUTLS_PIN="${PIN}" ${builddir}/pkcs11/list-objects -o ${P11DIR} -t all pkcs11:token=GnuTLS-Test|sort -u|wc -l)
|
|
|
cde47b |
+if test "$nr" != 2;then
|
|
|
cde47b |
+ echo "Error in test 8: did not find all objects"
|
|
|
cde47b |
+ ${builddir}/pkcs11/list-objects -o ${P11DIR} -t all pkcs11:token=GnuTLS-Test
|
|
|
cde47b |
+ exit 1
|
|
|
cde47b |
+fi
|
|
|
cde47b |
+
|
|
|
cde47b |
+# Check whether all privkeys are listed even if trust module is registered.
|
|
|
cde47b |
+nr=$(GNUTLS_PIN="${PIN}" ${builddir}/pkcs11/list-objects -o ${P11DIR} -t privkey pkcs11:|sort -u|wc -l)
|
|
|
cde47b |
+if test "$nr" != 1;then
|
|
|
cde47b |
+ echo "Error in test 9: did not find privkey objects"
|
|
|
cde47b |
+ ${builddir}/pkcs11/list-objects -o ${P11DIR} -t privkey pkcs11:
|
|
|
cde47b |
+ exit 1
|
|
|
cde47b |
+fi
|
|
|
cde47b |
+
|
|
|
cde47b |
rm -f ${P11DIR}/*
|
|
|
cde47b |
rm -rf ${TMP_SOFTHSM_DIR}
|
|
|
cde47b |
|
|
|
cde47b |
diff --git a/tests/pkcs11/list-objects.c b/tests/pkcs11/list-objects.c
|
|
|
cde47b |
new file mode 100644
|
|
|
cde47b |
index 000000000..ab30cd568
|
|
|
cde47b |
--- /dev/null
|
|
|
cde47b |
+++ b/tests/pkcs11/list-objects.c
|
|
|
cde47b |
@@ -0,0 +1,150 @@
|
|
|
cde47b |
+/*
|
|
|
cde47b |
+ * Copyright (C) 2016-2017 Red Hat, Inc.
|
|
|
cde47b |
+ *
|
|
|
cde47b |
+ * Author: Nikos Mavrogiannopoulos
|
|
|
cde47b |
+ *
|
|
|
cde47b |
+ * This file is part of GnuTLS.
|
|
|
cde47b |
+ *
|
|
|
cde47b |
+ * GnuTLS is free software; you can redistribute it and/or modify it
|
|
|
cde47b |
+ * under the terms of the GNU General Public License as published by
|
|
|
cde47b |
+ * the Free Software Foundation; either version 3 of the License, or
|
|
|
cde47b |
+ * (at your option) any later version.
|
|
|
cde47b |
+ *
|
|
|
cde47b |
+ * GnuTLS is distributed in the hope that it will be useful, but
|
|
|
cde47b |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
cde47b |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
cde47b |
+ * General Public License for more details.
|
|
|
cde47b |
+ *
|
|
|
cde47b |
+ * You should have received a copy of the GNU Lesser General Public License
|
|
|
cde47b |
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
|
cde47b |
+ */
|
|
|
cde47b |
+
|
|
|
cde47b |
+#ifdef HAVE_CONFIG_H
|
|
|
cde47b |
+#include <config.h>
|
|
|
cde47b |
+#endif
|
|
|
cde47b |
+
|
|
|
cde47b |
+#include <stdio.h>
|
|
|
cde47b |
+#include <stdlib.h>
|
|
|
cde47b |
+#include <string.h>
|
|
|
cde47b |
+#include <unistd.h>
|
|
|
cde47b |
+#include <sys/types.h>
|
|
|
cde47b |
+#include <sys/wait.h>
|
|
|
cde47b |
+
|
|
|
cde47b |
+#include <gnutls/gnutls.h>
|
|
|
cde47b |
+#include <gnutls/x509.h>
|
|
|
cde47b |
+#include <gnutls/abstract.h>
|
|
|
cde47b |
+#include <getopt.h>
|
|
|
cde47b |
+#define P11_KIT_FUTURE_UNSTABLE_API
|
|
|
cde47b |
+#include <p11-kit/p11-kit.h>
|
|
|
cde47b |
+#include "cert-common.h"
|
|
|
cde47b |
+
|
|
|
cde47b |
+/* lists the registered PKCS#11 modules by p11-kit.
|
|
|
cde47b |
+ */
|
|
|
cde47b |
+
|
|
|
cde47b |
+static void tls_log_func(int level, const char *str)
|
|
|
cde47b |
+{
|
|
|
cde47b |
+ fprintf(stderr, "|<%d>| %s", level, str);
|
|
|
cde47b |
+}
|
|
|
cde47b |
+
|
|
|
cde47b |
+static const char *opt_pin;
|
|
|
cde47b |
+
|
|
|
cde47b |
+static
|
|
|
cde47b |
+int pin_func(void* userdata, int attempt, const char* url, const char *label,
|
|
|
cde47b |
+ unsigned flags, char *pin, size_t pin_max)
|
|
|
cde47b |
+{
|
|
|
cde47b |
+ if (attempt == 0) {
|
|
|
cde47b |
+ strcpy(pin, opt_pin);
|
|
|
cde47b |
+ return 0;
|
|
|
cde47b |
+ }
|
|
|
cde47b |
+ return -1;
|
|
|
cde47b |
+}
|
|
|
cde47b |
+
|
|
|
cde47b |
+int main(int argc, char **argv)
|
|
|
cde47b |
+{
|
|
|
cde47b |
+ int ret;
|
|
|
cde47b |
+ unsigned i;
|
|
|
cde47b |
+ int opt;
|
|
|
cde47b |
+ char *url, *mod;
|
|
|
cde47b |
+ unsigned flags;
|
|
|
cde47b |
+ unsigned obj_flags = 0;
|
|
|
cde47b |
+ int attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL;
|
|
|
cde47b |
+ gnutls_pkcs11_obj_t *crt_list;
|
|
|
cde47b |
+ unsigned int crt_list_size = 0;
|
|
|
cde47b |
+ const char *envvar;
|
|
|
cde47b |
+
|
|
|
cde47b |
+ ret = gnutls_global_init();
|
|
|
cde47b |
+ if (ret != 0) {
|
|
|
cde47b |
+ fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
|
|
|
cde47b |
+ exit(1);
|
|
|
cde47b |
+ }
|
|
|
cde47b |
+
|
|
|
cde47b |
+ gnutls_global_set_log_function(tls_log_func);
|
|
|
cde47b |
+
|
|
|
cde47b |
+ while((opt = getopt(argc, argv, "o:t:")) != -1) {
|
|
|
cde47b |
+ switch(opt) {
|
|
|
cde47b |
+ case 'o':
|
|
|
cde47b |
+ mod = strdup(optarg);
|
|
|
cde47b |
+ p11_kit_override_system_files(NULL, NULL, mod, mod, NULL);
|
|
|
cde47b |
+ break;
|
|
|
cde47b |
+ case 't':
|
|
|
cde47b |
+ /* specify the object type to list */
|
|
|
cde47b |
+ if (strcmp(optarg, "all") == 0)
|
|
|
cde47b |
+ attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL;
|
|
|
cde47b |
+ else if (strcmp(optarg, "privkey") == 0)
|
|
|
cde47b |
+ attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY;
|
|
|
cde47b |
+ else {
|
|
|
cde47b |
+ fprintf(stderr, "Unknown object type %s\n", optarg);
|
|
|
cde47b |
+ exit(1);
|
|
|
cde47b |
+ }
|
|
|
cde47b |
+ break;
|
|
|
cde47b |
+ default:
|
|
|
cde47b |
+ fprintf(stderr, "Unknown option %c\n", (char)opt);
|
|
|
cde47b |
+ exit(1);
|
|
|
cde47b |
+ }
|
|
|
cde47b |
+ }
|
|
|
cde47b |
+
|
|
|
cde47b |
+ if (optind == argc) {
|
|
|
cde47b |
+ fprintf(stderr, "specify URL\n");
|
|
|
cde47b |
+ exit(1);
|
|
|
cde47b |
+ }
|
|
|
cde47b |
+ url = argv[optind];
|
|
|
cde47b |
+
|
|
|
cde47b |
+ envvar = getenv("GNUTLS_PIN");
|
|
|
cde47b |
+ if (envvar && *envvar != '\0') {
|
|
|
cde47b |
+ opt_pin = envvar;
|
|
|
cde47b |
+ obj_flags |= GNUTLS_PKCS11_OBJ_FLAG_LOGIN;
|
|
|
cde47b |
+ gnutls_pkcs11_set_pin_function(pin_func, NULL);
|
|
|
cde47b |
+ }
|
|
|
cde47b |
+
|
|
|
cde47b |
+ ret = gnutls_pkcs11_token_get_flags(url, &flags);
|
|
|
cde47b |
+ if (ret < 0) {
|
|
|
cde47b |
+ flags = 0;
|
|
|
cde47b |
+ }
|
|
|
cde47b |
+
|
|
|
cde47b |
+ ret =
|
|
|
cde47b |
+ gnutls_pkcs11_obj_list_import_url2(&crt_list, &crt_list_size,
|
|
|
cde47b |
+ url, attrs, obj_flags);
|
|
|
cde47b |
+ if (ret != 0) {
|
|
|
cde47b |
+ fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
|
|
|
cde47b |
+ exit(1);
|
|
|
cde47b |
+ }
|
|
|
cde47b |
+
|
|
|
cde47b |
+ for (i = 0; i < crt_list_size; i++) {
|
|
|
cde47b |
+ char *output;
|
|
|
cde47b |
+
|
|
|
cde47b |
+ ret =
|
|
|
cde47b |
+ gnutls_pkcs11_obj_export_url(crt_list[i], 0,
|
|
|
cde47b |
+ &output);
|
|
|
cde47b |
+ if (ret != 0) {
|
|
|
cde47b |
+ fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
|
|
|
cde47b |
+ exit(1);
|
|
|
cde47b |
+ }
|
|
|
cde47b |
+
|
|
|
cde47b |
+ fprintf(stdout, "%s\n", output);
|
|
|
cde47b |
+ gnutls_free(output);
|
|
|
cde47b |
+ gnutls_pkcs11_obj_deinit(crt_list[i]);
|
|
|
cde47b |
+ }
|
|
|
cde47b |
+ gnutls_free(crt_list);
|
|
|
cde47b |
+
|
|
|
cde47b |
+ gnutls_global_deinit();
|
|
|
cde47b |
+}
|
|
|
cde47b |
--
|
|
|
cde47b |
2.21.0
|
|
|
cde47b |
|