summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-10-30 13:51:33 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-11-03 16:10:57 +0000
commit418b2e12b5d589f81987ccdaae09b4cc33384ee6 (patch)
tree1521ddaa1154377e2a1041783684a746a9cb2777
parent00ae9ab6d51929b17c43e1424b434a951a59bd58 (diff)
downloadgnutls-418b2e12b5d589f81987ccdaae09b4cc33384ee6.tar.gz
tests: added PKCS#11 module loading test
This checks: 1. Whether all modules are loaded from p11-kit when no explicit gnutls_pkcs11_init() is called and pkcs11 calls are accessed. 2. Whether only the trusted modules are loaded from p11-kit and no other PKCS#11 calls than PKCS#11 cert validation is performed. 3. Whether the trusted modules are loaded when gnutls_pkcs11_init() is called with manual flag. Resolves #315 Resolves #316 Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--.gitlab-ci.yml8
-rw-r--r--configure.ac8
-rw-r--r--lib/libgnutls.map1
-rw-r--r--lib/pkcs11.c41
-rw-r--r--tests/Makefile.am11
-rwxr-xr-xtests/destructive/p11-kit-load.sh144
-rw-r--r--tests/pkcs11/list-tokens.c117
7 files changed, 320 insertions, 10 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8e7467cbb4..74748f48b6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -158,9 +158,9 @@ asan/Fedora/x86_64:
- make -j$(nproc)
- LSAN_OPTIONS="suppressions=$(pwd)/fuzz/lsan.supp" make check -j$(nproc)
- CFLAGS="-fsanitize=address -g -O2" LDFLAGS="-static-libasan"
- ./configure --disable-doc --with-default-trust-store-pkcs11="pkcs11:" --disable-guile
+ ./configure --disable-doc --with-default-trust-store-pkcs11="pkcs11:" --disable-guile --enable-destructive-tests
- make -j$(nproc)
- - make -C tests check -j$(nproc) TESTS=trust-store SUBDIRS=.
+ - make -C tests check -j$(nproc) TESTS="trust-store destructive/p11-kit-load.sh" SUBDIRS=.
tags:
- shared
except:
@@ -383,9 +383,9 @@ ubsan-Werror/Fedora/x86_64:
- make -j$(nproc) -C src CFLAGS="-Werror -O2 -g -fsanitize=undefined -Wno-error=parentheses -Wno-error=unused-macros"
- make -j$(nproc)
- make check -j$(nproc)
- - CFLAGS="-fsanitize=undefined -fsanitize=bool -fsanitize=alignment -fsanitize=null -fsanitize=bounds-strict -fsanitize=enum -fno-sanitize-recover -g -O2" LDFLAGS="-static-libubsan" ./configure --disable-non-suiteb-curves --disable-guile --disable-doc --with-default-trust-store-pkcs11="pkcs11:"
+ - CFLAGS="-fsanitize=undefined -fsanitize=bool -fsanitize=alignment -fsanitize=null -fsanitize=bounds-strict -fsanitize=enum -fno-sanitize-recover -g -O2" LDFLAGS="-static-libubsan" ./configure --disable-non-suiteb-curves --disable-guile --disable-doc --with-default-trust-store-pkcs11="pkcs11:" --enable-destructive-tests
- make -j$(nproc)
- - make -C tests check -j$(nproc) TESTS=trust-store SUBDIRS=.
+ - make -C tests check -j$(nproc) TESTS="trust-store destructive/p11-kit-load.sh" SUBDIRS=.
tags:
- shared
except:
diff --git a/configure.ac b/configure.ac
index b5e6cafdfa..6b46887509 100644
--- a/configure.ac
+++ b/configure.ac
@@ -254,6 +254,11 @@ AC_ARG_ENABLE(tests,
enable_tests=$enableval, enable_tests=$enable_tools)
AM_CONDITIONAL(ENABLE_TESTS, test "$enable_tests" != "no")
+AC_ARG_ENABLE(destructive-tests,
+ AS_HELP_STRING([--enable-destructive-tests], [compile and run tests which touch outside gnutls' code boundary]),
+ enable_destructive_tests=$enableval, enable_destructive_tests=no)
+AM_CONDITIONAL(ENABLE_DESTRUCTIVE_TESTS, test "$enable_destructive_tests" != "no")
+
AC_ARG_ENABLE(fuzzer-target,
AS_HELP_STRING([--enable-fuzzer-target], [make a library intended for testing - not production]),
enable_fuzzer_target=$enableval, enable_fuzzer_target=no)
@@ -729,6 +734,8 @@ if test "x$with_default_trust_store_pkcs11" != x; then
["$with_default_trust_store_pkcs11"], [use the given pkcs11 uri as default trust store])
fi
+AM_CONDITIONAL([HAVE_PKCS11_TRUST_STORE], [test -n "${with_default_trust_store_pkcs11}"])
+
AC_ARG_WITH([default-trust-store-dir],
[AS_HELP_STRING([--with-default-trust-store-dir=DIR],
[use the given directory as default trust store])])
@@ -981,6 +988,7 @@ AC_MSG_NOTICE([summary of build options:
Local unistring: ${included_unistring}
Use nettle-mini: ${mini_nettle}
Documentation: ${enable_doc} (manpages: ${enable_manpages})
+ Destructive tests: ${enable_destructive_tests}
])
AC_MSG_NOTICE([External hardware support:
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 43a6b13212..16c582c6f6 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1241,6 +1241,7 @@ GNUTLS_PRIVATE_3_4 {
_gnutls_mpi_log;
_gnutls_mpi_release;
# Internal symbols needed by tests/:
+ _gnutls_pkcs11_token_get_url;
_gnutls_pkcs12_string_to_key;
_gnutls_bin2hex;
_gnutls_mac_to_entry;
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index ceb05bbe8d..5955f19c61 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -2192,11 +2192,18 @@ find_token_modname_cb(struct ck_function_list *module, struct pkcs11_session_inf
return 0;
}
+/* Internal symbol used by tests */
+int
+_gnutls_pkcs11_token_get_url(unsigned int seq,
+ gnutls_pkcs11_url_type_t detailed, char **url,
+ unsigned flags);
+
/**
- * gnutls_pkcs11_token_get_url:
+ * _gnutls_pkcs11_token_get_url:
* @seq: sequence number starting from 0
* @detailed: non zero if a detailed URL is required
* @url: will contain an allocated url
+ * @flags: zero or 1. When 1 no initialization is performed.
*
* This function will return the URL for each token available
* in system. The url has to be released using gnutls_free()
@@ -2205,16 +2212,18 @@ find_token_modname_cb(struct ck_function_list *module, struct pkcs11_session_inf
* %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if the sequence number
* exceeds the available tokens, otherwise a negative error value.
*
- * Since: 2.12.0
**/
int
-gnutls_pkcs11_token_get_url(unsigned int seq,
- gnutls_pkcs11_url_type_t detailed, char **url)
+_gnutls_pkcs11_token_get_url(unsigned int seq,
+ gnutls_pkcs11_url_type_t detailed, char **url,
+ unsigned flags)
{
int ret;
struct find_token_num tn;
- PKCS11_CHECK_INIT;
+ if (!(flags & 1)) {
+ PKCS11_CHECK_INIT;
+ }
memset(&tn, 0, sizeof(tn));
tn.seq = seq;
@@ -2239,6 +2248,28 @@ gnutls_pkcs11_token_get_url(unsigned int seq,
}
/**
+ * gnutls_pkcs11_token_get_url:
+ * @seq: sequence number starting from 0
+ * @detailed: non zero if a detailed URL is required
+ * @url: will contain an allocated url
+ *
+ * This function will return the URL for each token available
+ * in system. The url has to be released using gnutls_free()
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
+ * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if the sequence number
+ * exceeds the available tokens, otherwise a negative error value.
+ *
+ * Since: 2.12.0
+ **/
+int
+gnutls_pkcs11_token_get_url(unsigned int seq,
+ gnutls_pkcs11_url_type_t detailed, char **url)
+{
+ return _gnutls_pkcs11_token_get_url(seq, detailed, url, 0);
+}
+
+/**
* gnutls_pkcs11_token_get_info:
* @url: should contain a PKCS 11 URL
* @ttype: Denotes the type of information requested
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 250f42640b..18d8b3eaa4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -88,6 +88,7 @@ noinst_LTLIBRARIES = libutils.la
libutils_la_SOURCES = utils.h utils.c seccomp.c utils-adv.c
libutils_la_LIBADD = ../lib/libgnutls.la
+indirect_tests =
ctests = mini-record-2 simple gc set_pkcs12_cred cert certuniqueid tls-neg-ext-key \
mpi certificate_set_x509_crl dn parse_ca x509-dn x509-dn-decode record-sizes \
hostname-check cve-2008-4989 pkcs12_s2k chainverify record-sizes-range \
@@ -309,7 +310,6 @@ name_constraints_merge_CPPFLAGS = $(AM_CPPFLAGS) \
-I$(top_builddir)/gl \
$(NETTLE_CFLAGS)
-check_PROGRAMS = $(ctests)
dist_check_SCRIPTS = rfc2253-escape-test rsa-md5-collision/rsa-md5-collision.sh systemkey.sh
if !WINDOWS
@@ -323,12 +323,21 @@ dist_check_SCRIPTS += fastopen.sh pkgconfig.sh starttls.sh starttls-ftp.sh start
if ENABLE_PKCS11
dist_check_SCRIPTS += p11-kit-trust.sh
+
+if ENABLE_DESTRUCTIVE_TESTS
+if HAVE_PKCS11_TRUST_STORE
+dist_check_SCRIPTS += destructive/p11-kit-load.sh
+indirect_tests += pkcs11/list-tokens
+endif
+endif
+
endif
if ENABLE_DANE
dist_check_SCRIPTS += danetool.sh
endif
endif
+check_PROGRAMS = $(ctests) $(indirect_tests)
TESTS = $(ctests) $(dist_check_SCRIPTS)
TESTS_ENVIRONMENT = \
diff --git a/tests/destructive/p11-kit-load.sh b/tests/destructive/p11-kit-load.sh
new file mode 100755
index 0000000000..2fe6394fe2
--- /dev/null
+++ b/tests/destructive/p11-kit-load.sh
@@ -0,0 +1,144 @@
+#!/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 <http://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)}"
+
+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/;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)
+DIR=$(${PKGCONFIG} --var=p11_system_config_modules p11-kit-1)
+rm -f ${DIR}/*
+
+cat <<_EOF_ >${DIR}/p11-kit-trust.module
+module: p11-kit-trust.so
+trust-policy: yes
+_EOF_
+
+cat <<_EOF_ >${DIR}/softhsm.module
+module: libsofthsm2.so
+_EOF_
+
+# Check whether p11tool would list them both
+
+nr=$(${P11TOOL} --list-tokens|grep -c ^Token)
+if test "$nr" != 2;then
+ echo "Error: did not find 2 modules"
+ ${P11TOOL} --list-tokens
+fi
+
+# Check whether p11tool with a specific provider would list only that
+
+nr=$(${P11TOOL} --provider "${SOFTHSM_MODULE}" --list-tokens|grep -c ^Token)
+if test "$nr" != 1;then
+ echo "Error: did not find softhsm modules"
+ ${P11TOOL} --list-tokens --provider "${SOFTHSM_MODULE}"
+fi
+
+
+# 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} --list-tokens|grep -c ^Token)
+if test "$nr" != 2;then
+ echo "Error: did not find 2 modules"
+ ${P11TOOL} --list-tokens
+fi
+
+
+# Check whether both modules are found when gnutls_pkcs11_init
+# is not called but a pkcs11 operation is called.
+${builddir}/pkcs11/list-tokens -d|wc -l
+if test "$nr" != 2;then
+ echo "Error in test 1: did not find 2 modules"
+ ${builddir}/pkcs11/list-tokens -d
+fi
+
+# Check whether both modules are found when gnutls_pkcs11_init
+# is called with the auto flag
+${builddir}/pkcs11/list-tokens -a|wc -l
+if test "$nr" != 2;then
+ echo "Error in test 2: did not find 2 modules"
+ ${builddir}/pkcs11/list-tokens -a
+fi
+
+# Check whether only trusted modules are listed when the
+# trusted flag is given to gnutls_pkcs11_init().
+${builddir}/pkcs11/list-tokens -t|wc -l
+if test "$nr" != 1;then
+ echo "Error in test 3: did not find the trusted module"
+ ${builddir}/pkcs11/list-tokens -t
+fi
+
+# Check whether only trusted is listed after certificate verification
+# is performed.
+${builddir}/pkcs11/list-tokens -v|wc -l
+if test "$nr" != 1;then
+ echo "Error in test 4: did not find 1 module"
+ ${builddir}/pkcs11/list-tokens -v
+fi
+
+# Check whether only trusted is listed when gnutls_pkcs11_init
+# is called with manual flag and a certificate verification is performed.
+${builddir}/pkcs11/list-tokens -m -v|wc -l
+if test "$nr" != 1;then
+ echo "Error in test 5: did not find 1 module"
+ ${builddir}/pkcs11/list-tokens -m -v
+fi
+
+exit 0
diff --git a/tests/pkcs11/list-tokens.c b/tests/pkcs11/list-tokens.c
new file mode 100644
index 0000000000..a835ef9c60
--- /dev/null
+++ b/tests/pkcs11/list-tokens.c
@@ -0,0 +1,117 @@
+/*
+ * 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 <http://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>
+#include <assert.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);
+}
+
+int
+_gnutls_pkcs11_token_get_url(unsigned int seq,
+ gnutls_pkcs11_url_type_t detailed, char **url,
+ unsigned flags);
+
+int main(int argc, char **argv)
+{
+ int ret;
+ unsigned i;
+ int opt;
+ char *url;
+ gnutls_certificate_credentials_t cred;
+ unsigned flag = 1;
+
+ 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);
+ //gnutls_global_set_log_level(4711);
+
+ while((opt = getopt(argc, argv, "mvatd")) != -1) {
+ switch(opt) {
+ case 'm':
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
+ if (ret != 0) {
+ fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
+ exit(1);
+ }
+ break;
+ case 'd':
+ flag = 0;
+ break;
+ case 'a':
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO, NULL);
+ if (ret != 0) {
+ fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
+ exit(1);
+ }
+ break;
+ case 't':
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO_TRUSTED, NULL);
+ if (ret != 0) {
+ fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
+ exit(1);
+ }
+ break;
+ case 'v':
+ assert(gnutls_certificate_allocate_credentials(&cred) >= 0);
+ assert(gnutls_certificate_set_x509_system_trust(cred) >= 0);
+ gnutls_certificate_free_credentials(cred);
+ break;
+ default:
+ fprintf(stderr, "Unknown option %c\n", (char)opt);
+ exit(1);
+ }
+ }
+
+
+ for (i=0;;i++) {
+ ret = _gnutls_pkcs11_token_get_url(i, 0, &url, flag);
+ if (ret < 0)
+ break;
+ printf("%s\n", url);
+ free(url);
+ }
+
+ gnutls_global_deinit();
+}