diff options
author | Daiki Ueno <ueno@gnu.org> | 2019-07-11 07:40:28 +0000 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2019-07-11 07:40:28 +0000 |
commit | a1335c3e798c51b23da7881f6b42912568f10093 (patch) | |
tree | a0c9451630ed948d3fa6fd72a105f171aaa2ecb4 | |
parent | 869f629ad1108be3ba86b4d88a35d5a990ae9cdb (diff) | |
parent | 49da45a3ddac3d2613456326b96016382b48570b (diff) | |
download | gnutls-a1335c3e798c51b23da7881f6b42912568f10093.tar.gz |
Merge branch 'tmp-pkcs11-login-error' into 'master'
pkcs11: ignore login error when traversing tokens
See merge request gnutls/gnutls!1031
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | lib/pkcs11.c | 8 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/destructive/p11-kit-load.sh | 185 | ||||
-rwxr-xr-x | tests/p11-kit-load.sh | 23 | ||||
-rw-r--r-- | tests/pkcs11/list-objects.c | 150 |
6 files changed, 182 insertions, 187 deletions
diff --git a/.gitignore b/.gitignore index 85ae942f12..37f34bdcea 100644 --- a/.gitignore +++ b/.gitignore @@ -562,6 +562,7 @@ tests/pkcs11-privkey-safenet-always-auth tests/pkcs11-token-raw tests/pkcs11/gnutls_pcert_list_import_x509_file tests/pkcs11/gnutls_x509_crt_list_import_url +tests/pkcs11/list-objects tests/pkcs11/pkcs11-chainverify tests/pkcs11/pkcs11-combo tests/pkcs11/pkcs11-ec-privkey-test diff --git a/lib/pkcs11.c b/lib/pkcs11.c index de5309b296..2ef0e3e025 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -1617,7 +1617,13 @@ _pkcs11_traverse_tokens(find_func_t find_func, void *input, info, flags); if (ret < 0) { gnutls_assert(); - return ret; + pkcs11_close_session(&sinfo); + + /* treat the error as fatal only if + * the token requires login */ + if (l_tinfo.flags & CKF_LOGIN_REQUIRED) + return ret; + continue; } ret = diff --git a/tests/Makefile.am b/tests/Makefile.am index 53f36dd717..34e3c5a970 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -508,7 +508,7 @@ dist_check_SCRIPTS += p11-kit-trust.sh testpkcs11.sh certtool-pkcs11.sh if HAVE_PKCS11_TRUST_STORE if P11KIT_0_23_11_API dist_check_SCRIPTS += p11-kit-load.sh -indirect_tests += pkcs11/list-tokens +indirect_tests += pkcs11/list-tokens pkcs11/list-objects endif endif diff --git a/tests/destructive/p11-kit-load.sh b/tests/destructive/p11-kit-load.sh deleted file mode 100644 index c6a381881b..0000000000 --- a/tests/destructive/p11-kit-load.sh +++ /dev/null @@ -1,185 +0,0 @@ -#!/bin/sh - -# Copyright (C) 2017 Red Hat, Inc. -# -# This file is part of p11-kit. -# -# p11-kit 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. -# -# p11-kit 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 Lesser General Public License -# along with this program. If not, see <https://www.gnu.org/licenses/> - -#set -e - -srcdir="${srcdir:-.}" -builddir="${builddir:-.}" -P11TOOL="${P11TOOL:-../src/p11tool${EXEEXT}}" -CERTTOOL="${CERTTOOL:-../src/certtool${EXEEXT}}" -DIFF="${DIFF:-diff}" -PKGCONFIG="${PKG_CONFIG:-$(which pkg-config)}" -TMP_SOFTHSM_DIR="./softhsm-load.$$.tmp" -P11DIR="p11-kit-conf.$$.tmp" -PIN=1234 -PUK=1234 - -for lib in ${libdir} ${libdir}/pkcs11 /usr/lib64/pkcs11/ /usr/lib/pkcs11/ /usr/lib/x86_64-linux-gnu/pkcs11/;do - if test -f "${lib}/p11-kit-trust.so"; then - TRUST_MODULE="${lib}/p11-kit-trust.so" - echo "located ${MODULE}" - break - fi -done - -for lib in ${libdir} ${libdir}/pkcs11 /usr/lib64/pkcs11/ /usr/lib/pkcs11/ /usr/lib/x86_64-linux-gnu/pkcs11/ /usr/lib/softhsm/;do - if test -f "${lib}/libsofthsm2.so"; then - SOFTHSM_MODULE="${lib}/libsofthsm2.so" - echo "located ${MODULE}" - break - fi -done - -${PKGCONFIG} --version >/dev/null || exit 77 - -if ! test -x "${P11TOOL}"; then - echo "p11tool was not found" - exit 77 -fi - -if ! test -f "${TRUST_MODULE}"; then - echo "p11-kit trust module was not found" - exit 77 -fi - -if ! test -f "${SOFTHSM_MODULE}"; then - echo "softhsm module was not found" - exit 77 -fi - -# Create pkcs11.conf with two modules, a trusted (p11-kit-trust) -# and softhsm (not trusted) -mkdir -p ${P11DIR} - -cat <<_EOF_ >${P11DIR}/p11-kit-trust.module -module: p11-kit-trust.so -trust-policy: yes -_EOF_ - -cat <<_EOF_ >${P11DIR}/softhsm.module -module: libsofthsm2.so -_EOF_ - -# Setup softhsm -rm -rf ${TMP_SOFTHSM_DIR} -mkdir -p ${TMP_SOFTHSM_DIR} -SOFTHSM2_CONF=${TMP_SOFTHSM_DIR}/conf -export SOFTHSM2_CONF -echo "objectstore.backend = file" > "${SOFTHSM2_CONF}" -echo "directories.tokendir = ${TMP_SOFTHSM_DIR}" >> "${SOFTHSM2_CONF}" - -softhsm2-util --init-token --slot 0 --label "GnuTLS-Test" --so-pin "${PUK}" --pin "${PIN}" >/dev/null #2>&1 -if test $? != 0; then - echo "failed to initialize softhsm" - exit 1 -fi - -FILTERTOKEN="sed s/token=.*//g" - -# Check whether both are listed - -nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -a|${FILTERTOKEN}|sort -u|wc -l) -#nr=$(${P11TOOL} --list-tokens|grep 'Module:'|sort -u|wc -l) -if test "$nr" != 2;then - echo "Error: did not find 2 modules ($nr)" - ${builddir}/pkcs11/list-tokens -o ${P11DIR} - exit 1 -fi - -## Check whether p11tool with a specific provider would list only that -## That is, check whether p11tool will list the trust module -## if we only load softhsm (it should as trust modules -## are always loaded).ould list them both - - -#nr=$(${P11TOOL} --provider "${SOFTHSM_MODULE}" --list-tokens|grep -c ^Token) -nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -m -s "${SOFTHSM_MODULE}"|${FILTERTOKEN}|sort -u|wc -l) -if test "$nr" != 1;then - echo "Error: did not find softhsm modules" - ${builddir}/pkcs11/list-tokens -o ${P11DIR} -m -s "${SOFTHSM_MODULE}" - exit 1 -fi - -# Check whether both modules are found when gnutls_pkcs11_init -# is not called but a pkcs11 operation is called. -nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -d|${FILTERTOKEN}|sort -u|wc -l) -if test "$nr" != 2;then - echo "Error in test 1: did not find 2 modules" - ${builddir}/pkcs11/list-tokens -o ${P11DIR} -d - exit 1 -fi - -# Check whether both modules are found when gnutls_pkcs11_init -# is called with the auto flag -nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -a|${FILTERTOKEN}|sort -u|wc -l) -if test "$nr" != 2;then - echo "Error in test 2: did not find 2 modules" - ${builddir}/pkcs11/list-tokens -o ${P11DIR} -a - exit 1 -fi - -# Check whether only trusted modules are listed when the -# trusted flag is given to gnutls_pkcs11_init(). -nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -t|${FILTERTOKEN}|sort -u|wc -l) -if test "$nr" != 1;then - echo "Error in test 3: did not find the trusted module" - ${builddir}/pkcs11/list-tokens -o ${P11DIR} -t - exit 1 -fi - -# Check whether only trusted is listed after certificate verification -# is performed. -nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -v|${FILTERTOKEN}|sort -u|wc -l) -if test "$nr" != 1;then - echo "Error in test 4: did not find 1 module" - echo xxx - GNUTLS_DEBUG_LEVEL=4 P11_KIT_DEBUG=all ${builddir}/pkcs11/list-tokens -o ${P11DIR} -v - exit 1 -fi - -# Check whether only trusted is listed when gnutls_pkcs11_init -# is called with manual flag and a certificate verification is performed. -nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -m -v|${FILTERTOKEN}|sort -u|wc -l) -if test "$nr" != 1;then - echo "Error in test 5: did not find 1 module" - ${builddir}/pkcs11/list-tokens -o ${P11DIR} -m -v - exit 1 -fi - -# Check whether all modules are listed after certificate verification -# is performed then a PKCS#11 function is called. -nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -v -d|${FILTERTOKEN}|sort -u|wc -l) -if test "$nr" != 2;then - echo "Error in test 6: did not find all modules" - ${builddir}/pkcs11/list-tokens -o ${P11DIR} -v -d - exit 1 -fi - -# Check whether all modules are listed after a private key operation. -nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -p|${FILTERTOKEN}|sort -u|wc -l) -if test "$nr" != 2;then - echo "Error in test 7: did not find all modules" - ${builddir}/pkcs11/list-tokens -o ${P11DIR} -p - exit 1 -fi - -rm -f ${P11DIR}/* -rm -rf ${TMP_SOFTHSM_DIR} - -exit 0 diff --git a/tests/p11-kit-load.sh b/tests/p11-kit-load.sh index 3201a2c5fc..419900f6a3 100755 --- a/tests/p11-kit-load.sh +++ b/tests/p11-kit-load.sh @@ -22,6 +22,7 @@ srcdir="${srcdir:-.}" builddir="${builddir:-.}" CERTTOOL="${CERTTOOL:-../src/certtool${EXEEXT}}" +P11TOOL="${P11TOOL:-../src/p11tool${EXEEXT}}" DIFF="${DIFF:-diff}" PKGCONFIG="${PKG_CONFIG:-$(which pkg-config)}" TMP_SOFTHSM_DIR="./softhsm-load.$$.tmp" @@ -90,6 +91,12 @@ if test $? != 0; then exit 1 fi +GNUTLS_PIN="${PIN}" ${P11TOOL} --login --label GnuTLS-Test-RSA --generate-privkey rsa --provider "${SOFTHSM_MODULE}" pkcs11: --outfile /dev/null +if test $? != 0; then + echo "failed to generate privkey" + exit 1 +fi + FILTERTOKEN="sed s/token=.*//g" # Check whether both are listed @@ -175,6 +182,22 @@ if test "$nr" != 2;then exit 1 fi +# Check whether public key and privkey are listed. +nr=$(GNUTLS_PIN="${PIN}" ${builddir}/pkcs11/list-objects -o ${P11DIR} -t all pkcs11:token=GnuTLS-Test|sort -u|wc -l) +if test "$nr" != 2;then + echo "Error in test 8: did not find all objects" + ${builddir}/pkcs11/list-objects -o ${P11DIR} -t all pkcs11:token=GnuTLS-Test + exit 1 +fi + +# Check whether all privkeys are listed even if trust module is registered. +nr=$(GNUTLS_PIN="${PIN}" ${builddir}/pkcs11/list-objects -o ${P11DIR} -t privkey pkcs11:|sort -u|wc -l) +if test "$nr" != 1;then + echo "Error in test 9: did not find privkey objects" + ${builddir}/pkcs11/list-objects -o ${P11DIR} -t privkey pkcs11: + exit 1 +fi + rm -f ${P11DIR}/* rm -rf ${TMP_SOFTHSM_DIR} diff --git a/tests/pkcs11/list-objects.c b/tests/pkcs11/list-objects.c new file mode 100644 index 0000000000..ab30cd568b --- /dev/null +++ b/tests/pkcs11/list-objects.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2016-2017 Red Hat, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GnuTLS. + * + * GnuTLS 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. + * + * GnuTLS 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 Lesser General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/> + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <gnutls/gnutls.h> +#include <gnutls/x509.h> +#include <gnutls/abstract.h> +#include <getopt.h> +#define P11_KIT_FUTURE_UNSTABLE_API +#include <p11-kit/p11-kit.h> +#include "cert-common.h" + +/* lists the registered PKCS#11 modules by p11-kit. + */ + +static void tls_log_func(int level, const char *str) +{ + fprintf(stderr, "|<%d>| %s", level, str); +} + +static const char *opt_pin; + +static +int pin_func(void* userdata, int attempt, const char* url, const char *label, + unsigned flags, char *pin, size_t pin_max) +{ + if (attempt == 0) { + strcpy(pin, opt_pin); + return 0; + } + return -1; +} + +int main(int argc, char **argv) +{ + int ret; + unsigned i; + int opt; + char *url, *mod; + unsigned flags; + unsigned obj_flags = 0; + int attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL; + gnutls_pkcs11_obj_t *crt_list; + unsigned int crt_list_size = 0; + const char *envvar; + + ret = gnutls_global_init(); + if (ret != 0) { + fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret)); + exit(1); + } + + gnutls_global_set_log_function(tls_log_func); + + while((opt = getopt(argc, argv, "o:t:")) != -1) { + switch(opt) { + case 'o': + mod = strdup(optarg); + p11_kit_override_system_files(NULL, NULL, mod, mod, NULL); + break; + case 't': + /* specify the object type to list */ + if (strcmp(optarg, "all") == 0) + attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL; + else if (strcmp(optarg, "privkey") == 0) + attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY; + else { + fprintf(stderr, "Unknown object type %s\n", optarg); + exit(1); + } + break; + default: + fprintf(stderr, "Unknown option %c\n", (char)opt); + exit(1); + } + } + + if (optind == argc) { + fprintf(stderr, "specify URL\n"); + exit(1); + } + url = argv[optind]; + + envvar = getenv("GNUTLS_PIN"); + if (envvar && *envvar != '\0') { + opt_pin = envvar; + obj_flags |= GNUTLS_PKCS11_OBJ_FLAG_LOGIN; + gnutls_pkcs11_set_pin_function(pin_func, NULL); + } + + ret = gnutls_pkcs11_token_get_flags(url, &flags); + if (ret < 0) { + flags = 0; + } + + ret = + gnutls_pkcs11_obj_list_import_url2(&crt_list, &crt_list_size, + url, attrs, obj_flags); + if (ret != 0) { + fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret)); + exit(1); + } + + for (i = 0; i < crt_list_size; i++) { + char *output; + + ret = + gnutls_pkcs11_obj_export_url(crt_list[i], 0, + &output); + if (ret != 0) { + fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(stdout, "%s\n", output); + gnutls_free(output); + gnutls_pkcs11_obj_deinit(crt_list[i]); + } + gnutls_free(crt_list); + + gnutls_global_deinit(); +} |