diff --git a/.github/scripts/check-workflow-result.sh b/.github/scripts/check-workflow-result.sh index 53326c55..bb70cbe7 100755 --- a/.github/scripts/check-workflow-result.sh +++ b/.github/scripts/check-workflow-result.sh @@ -1,7 +1,7 @@ #!/bin/bash # check-workflow-result.sh # -# Copyright (C) 2006-2025 wolfSSL Inc. +# Copyright (C) 2006-2026 wolfSSL Inc. # # This file is part of wolfProvider. # @@ -296,6 +296,22 @@ if [ "$WOLFPROV_FORCE_FAIL" = "WOLFPROV_FORCE_FAIL=1" ]; then echo "FAIL: iperf exited $TEST_RESULT but iperf-test.log is missing or does not show the credential encryption failure" exit 1 fi + # ----- MOSQUITTO ----- + elif [ "$TEST_SUITE" = "mosquitto" ]; then + # The broker must fail to create its TLS context + if [ "$TEST_RESULT" -ne 0 ] \ + && [ -f "mosquitto-test.log" ] \ + && grep -q 'Error: Unable to create TLS context' \ + mosquitto-test.log; then + echo "PASS: mosquitto broker failed to create its TLS context as expected with force fail enabled" + exit 0 + elif [ "$TEST_RESULT" -eq 0 ]; then + echo "FAIL: mosquitto tests unexpectedly succeeded with force fail enabled" + exit 1 + else + echo "FAIL: mosquitto exited $TEST_RESULT but mosquitto-test.log is missing or does not show the TLS context failure" + exit 1 + fi else if [ $TEST_RESULT -eq 0 ]; then echo "$TEST_SUITE tests unexpectedly succeeded with force fail enabled" diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 3179b0ea..6caf8e6f 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -169,6 +169,7 @@ exercised, with and without `WOLFPROV_FORCE_FAIL=1`. | `xmlsec.yml` | xmlsec | XML-DSig + XML-Enc (RSA-SHA256, AES-128/256-GCM) | | `libeac3.yml` | OpenEAC (eID auth) | ePassport BAC/PACE + EAC3 chip auth | | `librelp.yml` | rsyslog RELP transport | TLS session resumption (the recent FIPS 5.9.1 regression site) | +| `mosquitto.yml` | Eclipse Mosquitto MQTT broker + client lib | broker TLS + TLS-PSK tests (certificate auth, CRL, PSK publish and bridge) | | `net-snmp.yml` | Net-SNMP | SNMPv3 USM (HMAC-SHA + AES priv) | | `qt5network5.yml` | Qt5 Network (QSslSocket) | Qt's TLS path through the wolfprov-backed libssl | | `systemd.yml` | systemd | journald-remote TLS, systemd-timesyncd NTS | diff --git a/.github/workflows/mosquitto.yml b/.github/workflows/mosquitto.yml new file mode 100644 index 00000000..01f9d6c3 --- /dev/null +++ b/.github/workflows/mosquitto.yml @@ -0,0 +1,127 @@ +name: Mosquitto Tests + + +on: + workflow_call: + inputs: + wolfssl_refs_json: + description: "JSON array of wolfssl refs to test; empty = use discover_versions output" + required: false + type: string + default: "" + workflow_dispatch: {} + +jobs: + discover_versions: + uses: ./.github/workflows/_discover-versions.yml + + build_wolfprovider: + needs: discover_versions + uses: ./.github/workflows/build-wolfprovider.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ inputs.wolfssl_refs_json != '' && fromJson(inputs.wolfssl_refs_json) || fromJson(needs.discover_versions.outputs.wolfssl_ref_array) }} + openssl_ref: ${{ fromJson(needs.discover_versions.outputs.openssl_ref_array) }} + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true ] + + test_mosquitto: + runs-on: ubuntu-22.04 + needs: [build_wolfprovider, discover_versions] + container: + image: ghcr.io/wolfssl/wolfprovider-test-deps:bookworm + env: + DEBIAN_FRONTEND: noninteractive + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + mosquitto_ref: [ 'v2.1.2' ] + wolfssl_ref: ${{ inputs.wolfssl_refs_json != '' && fromJson(inputs.wolfssl_refs_json) || fromJson(needs.discover_versions.outputs.wolfssl_ref_array) }} + openssl_ref: ${{ fromJson(needs.discover_versions.outputs.openssl_ref_array) }} + fips_ref: [ 'FIPS', 'non-FIPS' ] + force_fail: ['WOLFPROV_FORCE_FAIL=1', ''] + replace_default: [ true ] + env: + WOLFSSL_PACKAGES_PATH: /tmp/wolfssl-packages + OPENSSL_PACKAGES_PATH: /tmp/openssl-packages + WOLFPROV_PACKAGES_PATH: /tmp/wolfprov-packages + # Leave out optional features whose libraries are not in the image + MOSQ_OPTS: >- + WITH_DOCS=no WITH_WEBSOCKETS=no WITH_EDITLINE=no WITH_SQLITE=no + WITH_HTTP_API=no WITH_ARGON2=no + steps: + - name: Checkout wolfProvider + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Download packages from build job + uses: actions/download-artifact@v4 + with: + name: debian-packages-${{ matrix.fips_ref }}${{ matrix.replace_default && '-replace-default' || '' }}-${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }} + path: /tmp + + - name: Install wolfSSL/OpenSSL/wolfprov packages + run: | + apt install --reinstall -y --allow-downgrades --allow-change-held-packages \ + ${{ env.WOLFSSL_PACKAGES_PATH }}/libwolfssl_*.deb + + apt install --reinstall -y --allow-downgrades --allow-change-held-packages \ + ${{ env.OPENSSL_PACKAGES_PATH }}/openssl_*.deb \ + ${{ env.OPENSSL_PACKAGES_PATH }}/libssl3_*.deb \ + ${{ env.OPENSSL_PACKAGES_PATH }}/libssl-dev_*.deb + + apt install --reinstall -y --allow-downgrades --allow-change-held-packages \ + ${{ env.WOLFPROV_PACKAGES_PATH }}/libwolfprov_*.deb + + # Keep later apt installs from replacing the wolfprov-patched libssl3 + apt-mark hold libssl3 libssl-dev openssl libwolfssl libwolfprov + + - name: Verify wolfProvider is properly installed + run: | + $GITHUB_WORKSPACE/scripts/verify-install.sh \ + ${{ matrix.replace_default && '--replace-default' || '' }} \ + ${{ matrix.fips_ref == 'FIPS' && '--fips' || '' }} + + - name: Checkout mosquitto + uses: actions/checkout@v4 + with: + repository: eclipse-mosquitto/mosquitto + path: mosquitto + ref: ${{ matrix.mosquitto_ref }} + + - name: Build mosquitto + working-directory: mosquitto + run: | + make -j $MOSQ_OPTS binary + make -C test/broker $MOSQ_OPTS test-compile + + - name: Run mosquitto TLS tests + working-directory: mosquitto + shell: bash + run: | + set +o pipefail # keep -e from aborting before PIPESTATUS is read + + # Non-root, so the broker does not drop privileges and lose file access + useradd --create-home mosqtest + chown -R mosqtest . + cd test/broker + + if [ -n "${{ matrix.force_fail }}" ]; then + # The other tests use Python TLS, which force fail breaks first + TESTS=./08-tls-psk-pub.py + else + # Group 08 is the broker TLS and TLS-PSK tests + TESTS="make 08" + fi + runuser -u mosqtest -- env ${{ matrix.force_fail }} $TESTS \ + 2>&1 | tee mosquitto-test.log + TEST_RESULT=${PIPESTATUS[0]} + $GITHUB_WORKSPACE/.github/scripts/check-workflow-result.sh $TEST_RESULT ${{ matrix.force_fail }} mosquitto diff --git a/.github/workflows/nightly-osp.yml b/.github/workflows/nightly-osp.yml index e12e1461..26e429c3 100644 --- a/.github/workflows/nightly-osp.yml +++ b/.github/workflows/nightly-osp.yml @@ -50,6 +50,7 @@ jobs: libssh2-current: { uses: ./.github/workflows/libssh2.yml, } libtss2-current: { uses: ./.github/workflows/libtss2.yml, } libwebsockets-current: { uses: ./.github/workflows/libwebsockets.yml, } + mosquitto-current: { uses: ./.github/workflows/mosquitto.yml, } net-snmp-current: { uses: ./.github/workflows/net-snmp.yml, } nginx-current: { uses: ./.github/workflows/nginx.yml, } nginx-pqc-current: { uses: ./.github/workflows/nginx-pqc.yml, } @@ -97,6 +98,7 @@ jobs: - libssh2-current - libtss2-current - libwebsockets-current + - mosquitto-current - net-snmp-current - nginx-current - nginx-pqc-current @@ -145,6 +147,7 @@ jobs: libssh2-584: { needs: wave1-done, if: always(), uses: ./.github/workflows/libssh2.yml, with: { wolfssl_refs_json: '["v5.8.4-stable"]' } } libtss2-584: { needs: wave1-done, if: always(), uses: ./.github/workflows/libtss2.yml, with: { wolfssl_refs_json: '["v5.8.4-stable"]' } } libwebsockets-584: { needs: wave1-done, if: always(), uses: ./.github/workflows/libwebsockets.yml, with: { wolfssl_refs_json: '["v5.8.4-stable"]' } } + mosquitto-584: { needs: wave1-done, if: always(), uses: ./.github/workflows/mosquitto.yml, with: { wolfssl_refs_json: '["v5.8.4-stable"]' } } net-snmp-584: { needs: wave1-done, if: always(), uses: ./.github/workflows/net-snmp.yml, with: { wolfssl_refs_json: '["v5.8.4-stable"]' } } nginx-584: { needs: wave1-done, if: always(), uses: ./.github/workflows/nginx.yml, with: { wolfssl_refs_json: '["v5.8.4-stable"]' } } openldap-584: { needs: wave1-done, if: always(), uses: ./.github/workflows/openldap.yml, with: { wolfssl_refs_json: '["v5.8.4-stable"]' } } diff --git a/.github/workflows/pr-osp-select.yml b/.github/workflows/pr-osp-select.yml index c85bfd42..a9b94ce6 100644 --- a/.github/workflows/pr-osp-select.yml +++ b/.github/workflows/pr-osp-select.yml @@ -127,6 +127,10 @@ jobs: needs: select if: contains(needs.select.outputs.run, ' all ') || contains(needs.select.outputs.run, ' libwebsockets ') uses: ./.github/workflows/libwebsockets.yml + mosquitto: + needs: select + if: contains(needs.select.outputs.run, ' all ') || contains(needs.select.outputs.run, ' mosquitto ') + uses: ./.github/workflows/mosquitto.yml net-snmp: needs: select if: contains(needs.select.outputs.run, ' all ') || contains(needs.select.outputs.run, ' net-snmp ') diff --git a/docker/wolfprovider-test-deps/Dockerfile b/docker/wolfprovider-test-deps/Dockerfile index a154a74a..7bf3a869 100644 --- a/docker/wolfprovider-test-deps/Dockerfile +++ b/docker/wolfprovider-test-deps/Dockerfile @@ -66,7 +66,7 @@ RUN apt-get update \ libpng-dev libjpeg-dev libusb-1.0-0-dev libuv1-dev libverto-dev \ libavahi-client-dev libavahi-compat-libdnssd-dev libmemcached-dev \ libutf8proc-dev libxxhash-dev libkeyutils-dev libcom-err2 \ - libcjose-dev libeac-dev libefivar-dev libncurses5-dev \ + libcjose-dev libcjson-dev libeac-dev libefivar-dev libncurses5-dev \ libncursesw5-dev libiberty-dev libltdl-dev libltdl7 \ libperl-dev linux-libc-dev binutils-dev uuid-dev \ # X11 (x11vnc, qt5network5)