diff --git a/.github/workflows/address-sanitizer.yml b/.github/workflows/address-sanitizer.yml index 47cc7821..3f3c6daf 100644 --- a/.github/workflows/address-sanitizer.yml +++ b/.github/workflows/address-sanitizer.yml @@ -44,7 +44,7 @@ jobs: 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. + # that is not compatible with LD_PRELOAD so we force the absolute path. run: | if [ -f /etc/fedora-release ]; then CC=gcc \ @@ -54,6 +54,8 @@ jobs: meson setup builddir -Db_sanitize=address -Dpreload_libasan=/usr/lib/x86_64-linux-gnu/libasan.so.8.0.0 fi - name: Build and Test + # note, that this intentionally does not initialize submodules as + # the tlsfuzzer test does not work under address sanitizer well run: | meson compile -C builddir meson test --num-processes 1 -C builddir diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 80e7176e..522f494e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,9 +35,9 @@ jobs: fi if [ -f /etc/redhat-release ]; then dnf -y install $dnf_opts \ - git ${{ matrix.compiler }} meson \ + git ${{ matrix.compiler }} meson which \ 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' ) @@ -120,17 +123,20 @@ jobs: openssl@3 \ pkg-config \ opensc \ - p11-kit + p11-kit \ + six if [ "${{ matrix.token }}" = "softokn" ]; then brew install nss elif [ "${{ matrix.token }}" = "softhsm" ]; then - brew install \ - softhsm + brew install softhsm fi - name: Checkout Repository 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..a0c03f27 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 \ @@ -46,6 +46,9 @@ jobs: uses: actions/checkout@v4 - name: Setup run: | + git config --global --add safe.directory \ + /__w/pkcs11-provider/pkcs11-provider + git submodule update --init meson setup builddir - name: Distcheck run: | diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 384b7ea0..53f40d06 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -15,7 +15,7 @@ jobs: matrix: test: [libssh, httpd] name: ${{ matrix.test }} - container: fedora:rawhide + container: fedora:latest env: PKCS11_MODULE: /usr/lib64/ossl-modules/pkcs11.so steps: @@ -51,7 +51,7 @@ jobs: test-bind: name: bind runs-on: ubuntu-22.04 - container: fedora:rawhide + container: fedora:latest steps: - name: Get Date for DNF cache entry id: get-date diff --git a/.github/workflows/kryoptic.yml b/.github/workflows/kryoptic.yml index 9ae3a0fd..a463a582 100644 --- a/.github/workflows/kryoptic.yml +++ b/.github/workflows/kryoptic.yml @@ -34,7 +34,8 @@ jobs: gcc g++ perl-interpreter zlib-devel sqlite-devel \ 'perl(Module::Load::Conditional)' 'perl(File::Temp)' \ 'perl(IPC::Cmd)' 'perl(FindBin)' 'perl(lib)' \ - 'perl(File::Compare)' 'perl(File::Copy)' + 'perl(File::Compare)' 'perl(File::Copy)' \ + python3-six which - name: Checkout Repository uses: actions/checkout@v4 @@ -79,7 +80,10 @@ jobs: grep -q "0 failed" testout.log - name: Setup - run: + run: | + git config --global --add safe.directory \ + /__w/pkcs11-provider/pkcs11-provider + git submodule update --init meson setup builddir - name: Build run: 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..ebbd0c1f 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,7 +27,9 @@ Files: .github/* tests/lsan.supp tools/openssl*.cnf tests/*.pem -Copyright: (C) 2022 Simo Sorce + tests/cert.json.in + scripts/clean-dist.sh +Copyright: (C) 2022 - 2024 Simo Sorce License: Apache-2.0 # diff --git a/meson.build b/meson.build index 95b9aaa5..80980ac8 100644 --- a/meson.build +++ b/meson.build @@ -84,6 +84,8 @@ endforeach configure_file(output: 'config.h', configuration: conf) +meson.add_dist_script('scripts/clean-dist.sh') + subdir('src') subdir('docs') subdir('tests') 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/scripts/clean-dist.sh b/scripts/clean-dist.sh new file mode 100755 index 00000000..e8ec7ddc --- /dev/null +++ b/scripts/clean-dist.sh @@ -0,0 +1,6 @@ +#!/bin/bash -e + +cd "$MESON_DIST_ROOT" + +# Remove the submodules +rm -rf tlsfuzzer python-ecdsa tlslite-ng diff --git a/tests/cert.json.in b/tests/cert.json.in new file mode 100644 index 00000000..e3181062 --- /dev/null +++ b/tests/cert.json.in @@ -0,0 +1,36 @@ +[ + {"server_command": [@CHECKER@"openssl", "s_server", "-www", "-port", "@PORT@", + "-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", "@SIGALGS@", + "-p", "@PORT@"]}, + {"name" : "test-tls13-ecdsa-in-certificate-verify.py", + "arguments" : ["-k", "tests/serverECKey.pem", + "-c", "tests/serverECCert.pem", + "-s", "@SIGALGS@", + "-p", "@PORT@"]} + ] + }, + {"server_command": [@CHECKER@"openssl", "s_server", "-www", "-port", "@PORT@", "-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/helpers.sh b/tests/helpers.sh index 6fc1f2cb..7883b759 100755 --- a/tests/helpers.sh +++ b/tests/helpers.sh @@ -72,3 +72,17 @@ kill_children() { # make sure it is killed before we continue jobs -p | xargs -r kill -9 || true } + +# macOS uses BSD sed, which expects the argument after -i (with a space after +# it!) to be the backup suffix, while GNU sed expects a potential backup suffix +# directly after -i and interprets -i as in-place editing with no +# backup. +# +# Use "${sed_inplace[@]}" to make that work transparently by setting it to the +# arguments required to achieve in-place editing without backups depending on +# the version of sed. +if sed --version 2>/dev/null | grep -q 'GNU sed'; then + export sed_inplace=("-i") +else + export sed_inplace=("-i" "") +fi diff --git a/tests/kryoptic-init.sh b/tests/kryoptic-init.sh index 0b626d4d..ecff6ae1 100755 --- a/tests/kryoptic-init.sh +++ b/tests/kryoptic-init.sh @@ -40,3 +40,5 @@ pkcs11-tool --module "${P11LIB}" --so-pin "${PINVALUE}" \ --login --login-type so --init-pin --pin "${PINVALUE}" 2>&1 export TOKENCONFIGVARS="export KRYOPTIC_CONF=$TOKDIR/kryoptic.sql" + +export TESTPORT="34000" 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/setup.sh b/tests/setup.sh index bc5cec1b..900cc202 100755 --- a/tests/setup.sh +++ b/tests/setup.sh @@ -57,20 +57,6 @@ if [ -z "$certtool" ]; then exit 0 fi -# macOS uses BSD sed, which expects the argument after -i (with a space after -# it!) to be the backup suffix, while GNU sed expects a potential backup suffix -# directly after -i and interprets -i as in-place editing with no -# backup. -# -# Use "${sed_inplace[@]}" to make that work transparently by setting it to the -# arguments required to achieve in-place editing without backups depending on -# the version of sed. -if sed --version 2>/dev/null | grep -q 'GNU sed'; then - sed_inplace=("-i") -else - sed_inplace=("-i" "") -fi - # NSS uses the second slot for certificates, so we need to provide the token # label in the args to allow pkcs11-tool to find the right slot P11DEFARGS=("--module=${P11LIB}" "--login" "--pin=${PINVALUE}" "--token-label=${TOKENLABEL}") @@ -210,7 +196,7 @@ echo "${ECPEERCRTURI}" echo "" -## Softtokn does not support edwrds curves yet +## Softtokn does not support edwards curves yet if [ "${TOKENTYPE}" != "softokn" ]; then # generate ED25519 @@ -400,6 +386,8 @@ export OPENSSL_CONF="${OPENSSL_CONF}" export TESTSSRCDIR="${TESTSSRCDIR}" export TESTBLDDIR="${TESTBLDDIR}" +export TESTPORT="${TESTPORT}" + export CACRT="${CACRT_PEM}" export TOKDIR="${TOKDIR}" diff --git a/tests/softhsm-init.sh b/tests/softhsm-init.sh index 9bd0f687..41d40437 100755 --- a/tests/softhsm-init.sh +++ b/tests/softhsm-init.sh @@ -65,3 +65,5 @@ softhsm2-util --init-token --label "${TOKENLABEL}" --free --pin "${PINVALUE}" -- export TOKENOPTIONS="pkcs11-module-quirks = no-deinit no-operation-state" export TOKENCONFIGVARS="export SOFTHSM2_CONF=${TMPPDIR}/softhsm.conf" + +export TESTPORT="32000" diff --git a/tests/softokn-init.sh b/tests/softokn-init.sh index 73e93ecc..026156a2 100755 --- a/tests/softokn-init.sh +++ b/tests/softokn-init.sh @@ -21,3 +21,5 @@ export TOKENLABELURI="NSS%20Certificate%20DB" export TOKENOPTIONS="pkcs11-module-quirks = no-operation-state no-allowed-mechanisms" export TOKENCONFIGVARS="export NSS_LIB_PARAMS=configDir=${TOKDIR}" + +export TESTPORT="30000" diff --git a/tests/ttlsfuzzer b/tests/ttlsfuzzer new file mode 100755 index 00000000..682be7e7 --- /dev/null +++ b/tests/ttlsfuzzer @@ -0,0 +1,63 @@ +#!/bin/bash -e +# Copyright (C) 2024 Jakub Jelen +# SPDX-License-Identifier: Apache-2.0 + +source "${TESTSSRCDIR}/helpers.sh" + +if [[ ! -d "${TESTSSRCDIR}/../tlsfuzzer/tlsfuzzer" ]]; then + title "TLS fuzzer is not available -- skipping" + exit 77; +fi + +TMPFILE="${PWD}/tls-fuzzer.$$.tmp" +PORT="$TESTPORT" +PYTHON=$(which python3) + +if [[ -f /etc/debian_version ]] && grep Ubuntu /etc/lsb-release; then + # the ubuntu builds miss Brainpool curves, but Debian has them already + SIGALGS="ecdsa_secp256r1_sha256 ecdsa_secp384r1_sha384 ecdsa_secp521r1_sha512 ed25519 ed448 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" +else + SIGALGS="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" +fi + +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" \ + -e "s/@SIGALGS@/$SIGALGS/g" "${TESTSSRCDIR}/cert.json.in" >"${TMPFILE}" + + # Run openssl under checker program if needed + if [[ -n "$CHECKER" ]]; then + IFS=" " read -r -a 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