]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
tests: added PKCS#11 module loading test
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 30 Oct 2017 12:51:33 +0000 (13:51 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 3 Nov 2017 16:10:57 +0000 (16:10 +0000)
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>
.gitlab-ci.yml
configure.ac
lib/libgnutls.map
lib/pkcs11.c
tests/Makefile.am
tests/destructive/p11-kit-load.sh [new file with mode: 0755]
tests/pkcs11/list-tokens.c [new file with mode: 0644]

index 8e7467cbb4fba84ed2c22b2f8c63945b7df68fe6..74748f48b6a7ee7e7c0f5cdb0ade334dd07d51d7 100644 (file)
@@ -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:
index b5e6cafdfaee3dc74064fbce6995412beccb514c..6b4688750915713fdf3ac503b6d97c3447b1e04a 100644 (file)
@@ -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:
index 43a6b13212d0641267514489808982104832e3e0..16c582c6f64d9d938aaa230518a667c70620d1eb 100644 (file)
@@ -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;
index ceb05bbe8d9f85e6a486634b62bf1ffc1f41d983..5955f19c61c9d72403fe8e6bd8cc315292587214 100644 (file)
@@ -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;
@@ -2238,6 +2247,28 @@ gnutls_pkcs11_token_get_url(unsigned int seq,
        return 0;
 }
 
+/**
+ * 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
index 250f42640bc677c7d0dbeb7dd8cfae0aaf789832..18d8b3eaa48c85aa99174e9e87177f6e9c39daf4 100644 (file)
@@ -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 (executable)
index 0000000..2fe6394
--- /dev/null
@@ -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 (file)
index 0000000..a835ef9
--- /dev/null
@@ -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();
+}