Blame SOURCES/gnutls-3.6.8-pkcs11-login-error.patch

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