From ac73fddc30c176db1e9ce60ddf5dc5bc161637ae Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Wed, 30 Oct 2024 17:17:06 +0100
Subject: [PATCH] Integrate tlsfuzzer integration test

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
---
 .github/workflows/address-sanitizer.yml | 22 ++++++----
 .github/workflows/build.yml             | 10 ++++-
 .github/workflows/distcheck.yml         |  2 +-
 .gitmodules                             |  9 ++++
 .reuse/dep5                             |  2 +
 python-ecdsa                            |  1 +
 tests/cert.json.in                      | 36 ++++++++++++++++
 tests/meson.build                       |  1 +
 tests/ttlsfuzzer                        | 55 +++++++++++++++++++++++++
 tlsfuzzer                               |  1 +
 tlslite-ng                              |  1 +
 11 files changed, 130 insertions(+), 10 deletions(-)
 create mode 100644 .gitmodules
 create mode 160000 python-ecdsa
 create mode 100644 tests/cert.json.in
 create mode 100755 tests/ttlsfuzzer
 create mode 160000 tlsfuzzer
 create mode 160000 tlslite-ng

diff --git a/.github/workflows/address-sanitizer.yml b/.github/workflows/address-sanitizer.yml
index 47cc7821..cb06dbf7 100644
--- a/.github/workflows/address-sanitizer.yml
+++ b/.github/workflows/address-sanitizer.yml
@@ -22,30 +22,38 @@ jobs:
             container: debian:sid
     container: ${{ matrix.container }}
     steps:
-      - name: Checkout Repository
-        uses: actions/checkout@v4
       - name: Install Dependencies
         run: |
           if [ -f /etc/fedora-release ]; then
-            dnf -y install git clang gcc pkgconf-pkg-config meson \
-              openssl-devel openssl diffutils expect \
+            dnf -y install git clang gcc pkgconf-pkg-config meson which \
+              openssl-devel openssl diffutils expect python3 python3-six \
               softhsm opensc p11-kit-devel p11-kit-server gnutls-utils \
               nss-softokn nss-tools nss-softokn-devel \
               dnf-command\(debuginfo-install\) libasan
             dnf -y debuginfo-install openssl
           elif [ -f /etc/debian_version ]; then
-            cat .github/sid.debug.list > /etc/apt/sources.list.d/debug.list
             apt-get -q update
             apt-get -yq install git gcc clang meson \
               pkg-config libssl-dev openssl expect \
               procps libnss3 libnss3-tools libnss3-dev softhsm2 opensc p11-kit \
-              libp11-kit-dev p11-kit-modules gnutls-bin \
-              openssl-dbgsym libssl3t64-dbgsym
+              libp11-kit-dev p11-kit-modules gnutls-bin
+          fi
+      - name: Checkout Repository
+        uses: actions/checkout@v4
+      - name: Install Debug symbols on Debian
+        run: |
+          if [ -f /etc/debian_version ]; then
+            cat .github/sid.debug.list > /etc/apt/sources.list.d/debug.list
+            apt-get -q update
+            apt-get -yq install openssl-dbgsym libssl3t64-dbgsym
           fi
       - name: Setup
         # The detection on debian works ok, but on Fedora, we get linker script,
         # that is not compabitlbe with LD_PRELOAD so we force the absolute path.
         run: |
+          git config --global --add safe.directory \
+              /__w/pkcs11-provider/pkcs11-provider
+          git submodule update --init
           if [ -f /etc/fedora-release ]; then
             CC=gcc \
             meson setup builddir -Db_sanitize=address -Dpreload_libasan=/usr/lib64/libasan.so.8.0.0
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 80e7176e..0397b0f6 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -37,7 +37,7 @@ jobs:
               dnf -y install $dnf_opts \
                 git ${{ matrix.compiler }} meson \
                 pkgconf-pkg-config openssl-devel openssl \
-                diffutils expect valgrind opensc gnutls-utils
+                diffutils expect valgrind opensc gnutls-utils python3-six
               if [ "${{ matrix.token }}" = "softokn" ]; then
                 dnf -y install nss-softokn nss-tools nss-softokn-devel \
                   nss-devel
@@ -48,7 +48,7 @@ jobs:
               apt-get -q update
               apt-get -yq install git ${{ matrix.compiler }} meson \
                 pkg-config libssl-dev openssl expect \
-                valgrind procps opensc gnutls-bin
+                valgrind procps opensc gnutls-bin python3-six
               if [ "${{ matrix.token }}" = "softokn" ]; then
                 apt-get -yq install libnss3 libnss3-tools libnss3-dev
               elif [ "${{ matrix.token }}" = "softhsm" ]; then
@@ -73,6 +73,9 @@ jobs:
       - name: Setup
         if : ( steps.nss-version-check.outputs.skiptest != 'true' )
         run: |
+          git config --global --add safe.directory \
+              /__w/pkcs11-provider/pkcs11-provider
+          git submodule update --init
           CC=${{ matrix.compiler }} meson setup builddir
       - name: Build and Test
         if : ( steps.nss-version-check.outputs.skiptest != 'true' )
@@ -131,6 +134,9 @@ jobs:
         uses: actions/checkout@v4
       - name: Setup
         run: |
+          git config --global --add safe.directory \
+              /__w/pkcs11-provider/pkcs11-provider
+          git submodule update --init
           export PKG_CONFIG_PATH=$(brew --prefix openssl@3)/lib/pkgconfig
           export PATH=$(brew --prefix openssl@3)/bin:$PATH
 
diff --git a/.github/workflows/distcheck.yml b/.github/workflows/distcheck.yml
index f1f5f841..91f05c06 100644
--- a/.github/workflows/distcheck.yml
+++ b/.github/workflows/distcheck.yml
@@ -29,7 +29,7 @@ jobs:
             fi
             if [ -f /etc/redhat-release ]; then
               dnf -y install $dnf_opts \
-                git gcc meson expect \
+                git gcc meson expect python3 python3-six which \
                 pkgconf-pkg-config openssl-devel openssl xz \
                 nss-softokn nss-tools nss-softokn-devel \
                 softhsm opensc p11-kit-devel p11-kit-server \
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..0135f210
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,9 @@
+[submodule "tlsfuzzer"]
+	path = tlsfuzzer
+	url = https://github.com/tlsfuzzer/tlsfuzzer.git
+[submodule "python-ecdsa"]
+	path = python-ecdsa
+	url = https://github.com/tlsfuzzer/python-ecdsa.git
+[submodule "tlslite-ng"]
+	path = tlslite-ng
+	url = https://github.com/tlsfuzzer/tlslite-ng.git
diff --git a/.reuse/dep5 b/.reuse/dep5
index c0941da9..55b06df6 100644
--- a/.reuse/dep5
+++ b/.reuse/dep5
@@ -8,6 +8,7 @@ Source: https://github.com/latchset/pkcs11-provider/
 #
 Files: .github/*
        .gitignore
+       .gitmodules
        Makefile
        meson.build
        meson_options.txt
@@ -26,6 +27,7 @@ Files: .github/*
        tests/lsan.supp
        tools/openssl*.cnf
        tests/*.pem
+       tests/cert.json.in
 Copyright: (C) 2022 Simo Sorce <simo@redhat.com>
 License: Apache-2.0
 
diff --git a/python-ecdsa b/python-ecdsa
new file mode 160000
index 00000000..ea966690
--- /dev/null
+++ b/python-ecdsa
@@ -0,0 +1 @@
+Subproject commit ea9666903c109a8e88a37eb1c60d4e98f01f0299
diff --git a/tests/cert.json.in b/tests/cert.json.in
new file mode 100644
index 00000000..edaa631b
--- /dev/null
+++ b/tests/cert.json.in
@@ -0,0 +1,36 @@
+[
+    {"server_command": [@CHECKER@"openssl", "s_server", "-www",
+                        "-key", "@PRIURI@", "-cert", "@CRTURI@",
+                        "-verify", "1", "-CAfile", "tests/clientX509Cert.pem"],
+     "comment": "Use ANY certificate just to ensure that server tries to authorise a client",
+     "environment": {"PYTHONPATH" : "."},
+     "server_hostname": "localhost",
+     "server_port": @PORT@,
+     "tests" : [
+       {"name" : "test-tls13-certificate-verify.py",
+        "arguments" : ["-k", "tests/clientX509Key.pem",
+                       "-c", "tests/clientX509Cert.pem",
+                       "-s", "ecdsa_secp256r1_sha256 ecdsa_secp384r1_sha384 ecdsa_secp521r1_sha512 ed25519 ed448 8+26 8+27 8+28 rsa_pss_pss_sha256 rsa_pss_pss_sha384 rsa_pss_pss_sha512 rsa_pss_rsae_sha256 rsa_pss_rsae_sha384 rsa_pss_rsae_sha512 rsa_pkcs1_sha256 rsa_pkcs1_sha384 rsa_pkcs1_sha512 ecdsa_sha224 rsa_pkcs1_sha224",
+                       "-p", "@PORT@"]},
+       {"name" : "test-tls13-ecdsa-in-certificate-verify.py",
+          "arguments" : ["-k", "tests/serverECKey.pem",
+                         "-c", "tests/serverECCert.pem",
+                         "-s", "ecdsa_secp256r1_sha256 ecdsa_secp384r1_sha384 ecdsa_secp521r1_sha512 ed25519 ed448 8+26 8+27 8+28 rsa_pss_pss_sha256 rsa_pss_pss_sha384 rsa_pss_pss_sha512 rsa_pss_rsae_sha256 rsa_pss_rsae_sha384 rsa_pss_rsae_sha512 rsa_pkcs1_sha256 rsa_pkcs1_sha384 rsa_pkcs1_sha512 ecdsa_sha224 rsa_pkcs1_sha224",
+                         "-p", "@PORT@"]}
+     ]
+    },
+    {"server_command": [@CHECKER@"openssl", "s_server", "-www", "-key", "@ECPRIURI@", "-cert", "@ECCRTURI@"],
+     "comment": "Run test with ECDSA hostkey in pkcs11 provider",
+     "environment": {"PYTHONPATH" : "."},
+     "server_hostname": "localhost",
+     "server_port": @PORT@,
+     "tests" : [
+       {"name" : "test-tls13-conversation.py",
+        "arguments" : ["-p", "@PORT@"]},
+       {"name" : "test-conversation.py",
+        "arguments" : ["-p", "@PORT@",
+                       "-d"]}
+     ]
+    }
+]
+
diff --git a/tests/meson.build b/tests/meson.build
index 03119db0..ce874e66 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -137,6 +137,7 @@ tests = {
   'rand': {'suites': ['softokn', 'softhsm', 'kryoptic']},
   'readkeys': {'suites': ['softokn', 'softhsm', 'kryoptic']},
   'tls': {'suites': ['softokn', 'softhsm', 'kryoptic'], 'is_parallel': false},
+  'tlsfuzzer': {'suites': ['softokn', 'softhsm', 'kryoptic']},
   'uri': {'suites': ['softokn', 'softhsm', 'kryoptic']},
   'ecxc': {'suites': ['softhsm', 'kryoptic']},
   'cms': {'suites': ['softokn', 'kryoptic']},
diff --git a/tests/ttlsfuzzer b/tests/ttlsfuzzer
new file mode 100755
index 00000000..10f54e1c
--- /dev/null
+++ b/tests/ttlsfuzzer
@@ -0,0 +1,55 @@
+#!/bin/bash -e
+# Copyright (C) 2024 Jakub Jelen <jjelen@redhat.com>
+# SPDX-License-Identifier: Apache-2.0
+
+source "${TESTSSRCDIR}/helpers.sh"
+
+if [[ ! -d "${TESTSSRCDIR}/../tlsfuzzer" ]]; then
+    title "TLS fuzzer is not available -- skipping"
+    exit 77;
+fi
+
+TMPFILE="${PWD}/tls-fuzzer.$$.tmp"
+PORT=4433
+PYTHON=$(which python3)
+
+run_tests() {
+    # Prepare the tlsfuzzer configuration
+    sed -e "s|@PRIURI@|$PRIURI|g" -e "s/@CRTURI@/$CRTURI/g" \
+        -e "s|@ECPRIURI@|$ECPRIURI|g" -e "s/@ECCRTURI@/$ECCRTURI/g" \
+        -e "s/@PORT@/$PORT/g" "${TESTSSRCDIR}/cert.json.in" >"${TMPFILE}"
+
+    # Run openssl under checker program if needed
+    if [[ -n "$CHECKER" ]]; then
+        ARR=($CHECKER)
+        sed -e "s|@CHECKER@|$(printf "'%s', " "${ARR[@]}")|g" "${sed_inplace[@]}" "${TMPFILE}"
+    else
+        sed -e "s|@CHECKER@||g" "${sed_inplace[@]}" "${TMPFILE}"
+    fi
+
+    pushd "${TESTSSRCDIR}/../tlsfuzzer"
+    test -L ecdsa || ln -s ../python-ecdsa/src/ecdsa ecdsa
+    test -L tlslite || ln -s ../tlslite-ng/tlslite tlslite 2>/dev/null
+    PYTHONPATH=. "${PYTHON}" tests/scripts_retention.py "${TMPFILE}" openssl 821
+    rm -f "${TMPFILE}"
+    popd
+}
+
+title SECTION "Run TLS fuzzer with server key on provider"
+run_tests
+title ENDSECTION
+
+title SECTION "Run TLS fuzzer forcing the provider for all server operations"
+#We need to disable digest operations as OpenSSL depends on context duplication working
+ORIG_OPENSSL_CONF=${OPENSSL_CONF}
+sed -e "s/^#MORECONF/alg_section = algorithm_sec\n\n[algorithm_sec]\ndefault_properties = ?provider=pkcs11/" \
+    -e "s/^#pkcs11-module-block-operations/pkcs11-module-block-operations = digest/" \
+    "${OPENSSL_CONF}" > "${OPENSSL_CONF}.forcetoken"
+export OPENSSL_CONF=${OPENSSL_CONF}.forcetoken
+
+run_tests
+
+OPENSSL_CONF=${ORIG_OPENSSL_CONF}
+title ENDSECTION
+
+exit 0
diff --git a/tlsfuzzer b/tlsfuzzer
new file mode 160000
index 00000000..a0c066cd
--- /dev/null
+++ b/tlsfuzzer
@@ -0,0 +1 @@
+Subproject commit a0c066cdfd927bd10e3a154d7efd209797ed2cc0
diff --git a/tlslite-ng b/tlslite-ng
new file mode 160000
index 00000000..768c262e
--- /dev/null
+++ b/tlslite-ng
@@ -0,0 +1 @@
+Subproject commit 768c262e59ec0b4084bbb436a88c64fcb757e496