diff --git a/.github/README_WORKFLOWS.md b/.github/README_WORKFLOWS.md index 060e2f178..f115d04b2 100644 --- a/.github/README_WORKFLOWS.md +++ b/.github/README_WORKFLOWS.md @@ -415,6 +415,7 @@ flowchart TB - **PROTECCIO_IP**: Proteccio HSM IP address - **PROTECCIO_PASSWORD**: Proteccio HSM password - **PROTECCIO_SLOT**: Proteccio HSM slot +- **CRYPT2PAY_PASSWORD**: Crypt2pay HSM password ### Google CSE Secrets diff --git a/.github/reusable_scripts b/.github/reusable_scripts index 7f5dd42b5..27958a96a 160000 --- a/.github/reusable_scripts +++ b/.github/reusable_scripts @@ -1 +1 @@ -Subproject commit 7f5dd42b58a99268e11681ef120bc22b6ffbb2ea +Subproject commit 27958a96a092ebb9d5340fddd5b5f72095a8e009 diff --git a/.github/scripts/nix.sh b/.github/scripts/nix.sh index c9c3abad7..45781c3d9 100755 --- a/.github/scripts/nix.sh +++ b/.github/scripts/nix.sh @@ -531,6 +531,10 @@ test_command() { SCRIPT="$REPO_ROOT/.github/scripts/test/test_hsm_proteccio.sh" shift ;; + crypt2pay) + SCRIPT="$REPO_ROOT/.github/scripts/test/test_hsm_crypt2pay.sh" + shift + ;; *) echo "Error: Unknown HSM backend '$HSM_BACKEND'" >&2 echo "Valid backends for 'hsm': softhsm2, utimaco, proteccio, all" >&2 @@ -585,6 +589,8 @@ test_command() { --keep POSTGRES_HOST --keep POSTGRES_PORT \ --keep PROTECCIO_IP --keep PROTECCIO_PASSWORD --keep PROTECCIO_SLOT \ --keep PROTECCIO_PKCS11_LIB --keep PROTECCIO_PORT \ + --keep CRYPT2PAY_PASSWORD --keep CRYPT2PAY_SLOT_ID \ + --keep OVPN_CONF \ --keep VARIANT \ --keep TEST_GOOGLE_OAUTH_CLIENT_ID \ --keep TEST_GOOGLE_OAUTH_CLIENT_SECRET \ diff --git a/.github/scripts/test/test_hsm.sh b/.github/scripts/test/test_hsm.sh index b53f5011f..33e1d4899 100644 --- a/.github/scripts/test/test_hsm.sh +++ b/.github/scripts/test/test_hsm.sh @@ -12,5 +12,6 @@ echo "=========================================" bash "$SCRIPT_DIR/test_hsm_softhsm2.sh" "$@" bash "$SCRIPT_DIR/test_hsm_utimaco.sh" "$@" bash "$SCRIPT_DIR/test_hsm_proteccio.sh" "$@" +bash "$SCRIPT_DIR/test_hsm_crypt2pay.sh" "$@" echo "All HSM tests completed successfully." diff --git a/.github/scripts/test/test_hsm_crypt2pay.sh b/.github/scripts/test/test_hsm_crypt2pay.sh old mode 100644 new mode 100755 index 98a183f94..4dd4c3439 --- a/.github/scripts/test/test_hsm_crypt2pay.sh +++ b/.github/scripts/test/test_hsm_crypt2pay.sh @@ -2,10 +2,60 @@ set -eo pipefail set -x +# OpenVPN setup +if ! command -v openvpn >/dev/null 2>&1; then + echo "Installing OpenVPN..." + sudo apt-get update + sudo apt-get install -y openvpn +fi + +: "${OVPN_CONF:?OVPN_CONF not set}" + +# Strip route-nopull so that server-pushed routes are accepted. +# Keep pull-filter ignore "redirect-gateway" to avoid full traffic redirect. +OVPN_CONF_FIXED=$(echo "$OVPN_CONF" | grep -v '^route-nopull$') +echo "$OVPN_CONF_FIXED" | sudo tee /tmp/openvpn.ovpn > /dev/null + +# Kill any previous openvpn instances to avoid duplicate routes / stale tunnels +sudo killall openvpn 2>/dev/null || true +sleep 1 + +# Remove stale tun0 interface to avoid "File exists" route conflicts +sudo ip link del tun0 2>/dev/null || true +sleep 1 + +VPN_LOG=/tmp/vpn.log +sudo truncate -s 0 "$VPN_LOG" 2>/dev/null || sudo touch "$VPN_LOG" +sudo chmod 644 "$VPN_LOG" + +sudo openvpn --config /tmp/openvpn.ovpn \ + --log "$VPN_LOG" \ + --daemon + +echo "Waiting for VPN connection..." + +for _i in {1..30}; do + if grep -q "Initialization Sequence Completed" "$VPN_LOG"; then + echo "VPN connected" + break + fi + sleep 1 +done + +if ! grep -q "Initialization Sequence Completed" "$VPN_LOG"; then + echo "Error: VPN not connected" + cat "$VPN_LOG" + exit 1 +fi + +echo "VPN logs:" +tail -n 50 "$VPN_LOG" + # Crypt2pay-only tests (Linux only) SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) source "${SCRIPT_DIR}/../common.sh" +REPO_ROOT=$(get_repo_root "$SCRIPT_DIR") init_build_env "$@" setup_test_logging @@ -20,10 +70,42 @@ echo "=========================================" export HSM_USER_PASSWORD="${CRYPT2PAY_PASSWORD:?CRYPT2PAY_PASSWORD not set}" -# Note: This script assumes Crypt2pay HSM setup is already configured -# Users need to set up the Crypt2pay HSM environment and related variables +# Setup Crypt2pay HSM client tools +if ! source "$REPO_ROOT/.github/reusable_scripts/prepare_crypt2pay.sh"; then + echo "Warning: Failed to source prepare_crypt2pay.sh with return code $?." + if [ -f /lib/libpkcs11c2p.so ] && [ -f /etc/c2p/c2p.xml ]; then + echo "Continuing: Crypt2Pay client appears installed despite prepare script self-test failure." + else + echo "Error: Crypt2Pay client setup is incomplete." + exit 1 + fi +fi + +export C2P_CONF="${C2P_CONF:-/etc/c2p/c2p.xml}" + +# Extract the C2P HSM host and port from the config +C2P_HOST=$(grep -ioP '(?<=)[^<]+' "$C2P_CONF" | head -1) +C2P_PORT=$(grep -ioP '(?<=)[^<]+' "$C2P_CONF" | head -1) + +if [ -n "$C2P_HOST" ] && [ -n "$C2P_PORT" ]; then + echo "Checking HSM connectivity at $C2P_HOST:$C2P_PORT ..." + HSM_REACHABLE=false + for _i in {1..30}; do + if timeout 3 bash -c "echo >/dev/tcp/$C2P_HOST/$C2P_PORT" 2>/dev/null; then + echo "HSM service is reachable" + HSM_REACHABLE=true + break + fi + echo " retry $_i/30 - waiting 2s..." + sleep 2 + done + if [ "$HSM_REACHABLE" = false ]; then + echo "Error: HSM service $C2P_HOST:$C2P_PORT is not reachable over the VPN" + exit 1 + fi +fi -# CRYPT2PAY integration test (KMS) +# CRYPT2PAY integration test (KMS server) env \ PATH="$PATH" \ HSM_MODEL="crypt2pay" \ @@ -34,6 +116,7 @@ env \ ${FEATURES_FLAG[@]+"${FEATURES_FLAG[@]}"} \ -- tests::hsm::test_hsm_all --ignored --exact +# CRYPT2PAY PKCS#11 loader test env \ PATH="$PATH" \ HSM_MODEL="crypt2pay" \ diff --git a/.github/workflows/test_all.yml b/.github/workflows/test_all.yml index 43ce8a3c1..07d50ac3e 100644 --- a/.github/workflows/test_all.yml +++ b/.github/workflows/test_all.yml @@ -143,6 +143,7 @@ jobs: - utimaco - proteccio - softhsm2 + - crypt2pay features: [fips, non-fips] exclude: # parallel connections on proteccio is not supported @@ -184,11 +185,14 @@ jobs: PROTECCIO_IP: ${{ secrets.PROTECCIO_IP }} PROTECCIO_PASSWORD: ${{ secrets.PROTECCIO_PASSWORD }} PROTECCIO_SLOT: ${{ secrets.PROTECCIO_SLOT }} + CRYPT2PAY_PASSWORD: ${{ secrets.CRYPT2PAY_PASSWORD }} # Google variables TEST_GOOGLE_OAUTH_CLIENT_ID: ${{ secrets.TEST_GOOGLE_OAUTH_CLIENT_ID }} TEST_GOOGLE_OAUTH_CLIENT_SECRET: ${{ secrets.TEST_GOOGLE_OAUTH_CLIENT_SECRET }} TEST_GOOGLE_OAUTH_REFRESH_TOKEN: ${{ secrets.TEST_GOOGLE_OAUTH_REFRESH_TOKEN }} GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY }} + # OVPN for Crypt2Pay HSM tests + OVPN_CONF: ${{ secrets.OVPN_CONF }} run: | bash .github/scripts/nix.sh --variant ${{ matrix.features }} test hsm ${{ matrix.hsm-type }} diff --git a/CHANGELOG/ci_tests_c2p.md b/CHANGELOG/ci_tests_c2p.md new file mode 100644 index 000000000..9ddf0fc24 --- /dev/null +++ b/CHANGELOG/ci_tests_c2p.md @@ -0,0 +1,15 @@ +## CI + +- Make Crypt2Pay CI setup resilient to `prepare_crypt2pay.sh` self-test failures (`unsupported key type 'aes'`) by continuing when `/usr/lib/libpkcs11c2p.so` and `/etc/c2p/c2p.xml` are present. +- Strip `route-nopull` from OpenVPN config to accept server-pushed routes for proper VPN routing to the Crypt2Pay HSM. +- Add TCP connectivity check (30 retries) against the C2P HSM host/port before running tests to fail fast when the service is unreachable. +- Fix Crypt2Pay `prepare_crypt2pay.sh`: install CA into `ssl/authorities` (matching the `` config) instead of `ssl/`. +- Fix Crypt2Pay HSM port: the SSL service now runs on port 3001 (port 3002 is firewalled). +- Add bridge CA workaround in `prepare_crypt2pay.sh`: the C2P package ships a CA cert re-issued with a new subject DN (`O=Eviden, OU=Trustway, CN=CA-C2P`) but the HSM server cert still references the old issuer DN (`CN=CA-C2P`). A bridge CA with the old DN and matching public key is generated and installed under the server cert's dgst hash so the C2P SSL lookup succeeds. +- Clean up stale tun0 interface before starting OpenVPN to avoid route conflicts. +- Fix VPN log file permissions for non-root readability. + +## Bug Fixes + +- Fix `cargo fmt` issue in `session_impl.rs` (`debug!` macro line length). +- Remove unused `cosmian_logger` dev-dependency from `crypt2pay_pkcs11_loader` crate.