diff --git a/.github/scripts/check-workflow-result.sh b/.github/scripts/check-workflow-result.sh
index 53326c55..bd2a7053 100755
--- a/.github/scripts/check-workflow-result.sh
+++ b/.github/scripts/check-workflow-result.sh
@@ -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
+ # ----- GIT-SSH-DR -----
+ elif [ "$TEST_SUITE" = "git-ssh-dr" ]; then
+ # Every client operation must fail on wolfProvider's RNG
+ if [ "$TEST_RESULT" -ne 0 ] \
+ && [ -f "git-ssh-dr-test.log" ] \
+ && grep -Eq '^Result: 0 succeeded, [1-9][0-9]* failed on the RNG, 0 failed otherwise, 0 skipped$' \
+ git-ssh-dr-test.log; then
+ echo "PASS: every git over SSH operation failed on the RNG as expected with force fail enabled"
+ exit 0
+ elif [ "$TEST_RESULT" -eq 0 ]; then
+ echo "FAIL: git over SSH tests unexpectedly succeeded with force fail enabled"
+ exit 1
+ else
+ echo "FAIL: git-ssh-dr exited $TEST_RESULT but git-ssh-dr-test.log is missing or shows operations that did not fail on the RNG"
+ 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 3cd5e204..eb6af695 100644
--- a/.github/workflows/README.md
+++ b/.github/workflows/README.md
@@ -143,7 +143,7 @@ exercised, with and without `WOLFPROV_FORCE_FAIL=1`.
| `pam-pkcs11.yml` | PAM PKCS#11 module | smartcard login via PKCS#11 token + wolfprov-backed verify |
| `opensc.yml` | OpenSC smartcard middleware | PKCS#15 / pkcs11-tool cert + key ops |
| `sscep.yml` | SCEP enrollment client | CSR signing + SCEP message envelope decrypt/encrypt |
-| `git-ssh-dr.yml` | git over SSH (wolfSSL custom) | ed25519/RSA host key + signing path through OpenSSH stack |
+| `git-ssh-dr.yml` | git over SSH to a local sshd (wolfSSL custom) | RNG, SHA-2 and AES in Debian's OpenSSH: `aes-ctr` (RSA, DH group14, aes128-ctr, hmac-sha2-256) and `aes-gcm` (ECDSA P-521, ECDH P-256, aes256-gcm) suites |
| `libfido2.yml` | FIDO2 / WebAuthn | CTAP2 ECDSA signatures, HMAC-secret extension |
#### TPM, disk crypto, hashing
diff --git a/.github/workflows/git-ssh-dr.yml b/.github/workflows/git-ssh-dr.yml
index 2a2a4419..3d5e63e2 100644
--- a/.github/workflows/git-ssh-dr.yml
+++ b/.github/workflows/git-ssh-dr.yml
@@ -47,8 +47,8 @@ jobs:
openssl_ref: ${{ fromJson(needs.discover_versions.outputs.openssl_ref_array) }}
fips_ref: [ 'FIPS', 'non-FIPS' ]
replace_default: [ true ]
- key_type: [ 'rsa', 'ecdsa', 'ed25519', 'chacha20-poly1305' ]
- iterations: [ 10 ] # Total of 80 runs
+ suite: [ 'aes-ctr', 'aes-gcm' ]
+ iterations: [ 10 ]
force_fail: ['WOLFPROV_FORCE_FAIL=1', '']
env:
WOLFSSL_PACKAGES_PATH: /tmp/wolfssl-packages
@@ -94,16 +94,11 @@ jobs:
- name: Run git + replace default + ssh test
shell: bash
run: |
- echo "=== Running Git + replace default + ssh Test ==="
- echo "Using the local test script for consistent testing"
- # Run the test with the matrix parameters
- echo "Testing with key type: ${{ matrix.key_type }}"
- echo "Running ${{ matrix.iterations }} iterations"
-
- # Run the scripts test
+ set +o pipefail
${{ matrix.force_fail }} ./scripts/test-git-ssh-dr.sh \
- --key-types "${{ matrix.key_type }}" \
+ --suite "${{ matrix.suite }}" \
--iterations "${{ matrix.iterations }}" \
- --verbose
+ --verbose 2>&1 | tee git-ssh-dr-test.log
+ TEST_RESULT=${PIPESTATUS[0]}
- echo "=== Test completed for ${{ matrix.key_type }} ==="
+ $GITHUB_WORKSPACE/.github/scripts/check-workflow-result.sh $TEST_RESULT ${{ matrix.force_fail }} git-ssh-dr
diff --git a/scripts/test-git-ssh-dr.sh b/scripts/test-git-ssh-dr.sh
index 08ce4789..494e3540 100755
--- a/scripts/test-git-ssh-dr.sh
+++ b/scripts/test-git-ssh-dr.sh
@@ -17,32 +17,49 @@
# You should have received a copy of the GNU General Public License
# along with wolfProvider. If not, see .
#
-# Local test script for wolfProvider git operations
-# This script tests git operations with wolfProvider
-# as the default replace provider
-
-echo "=== wolfProvider Git Operations Local Test ==="
-echo "Testing git operations with wolfProvider default replace functionality"
-echo ""
+# Git over SSH with wolfProvider as the replace-default provider.
+#
+# Starts a local sshd and runs ssh-keygen and git clone, push, pull and fetch
+# against it over ssh://. Client and server allow only the algorithms of one
+# suite, and every git operation checks the negotiated algorithms:
+#
+# aes-ctr RSA 4096 keys (rsa-sha2-512), diffie-hellman-group14-sha256,
+# aes128-ctr, hmac-sha2-256
+# aes-gcm ECDSA P-521 keys (ecdsa-sha2-nistp521), ecdh-sha2-nistp256,
+# aes256-gcm@openssh.com
+#
+# OpenSSH gets its RNG, SHA-2 digests and AES ciphers from libcrypto, so
+# from wolfProvider. With WOLFPROV_FORCE_FAIL=1 only the client operations
+# run with force fail. The script exits 0 only when every operation succeeds,
+# and its Result line counts the operations that failed with FORCE_FAIL_REASON.
+#
+# Force fail stops ssh and ssh-keygen in seed_rng(), before any key exchange
+# or cipher, so only the normal runs show the AES and SHA-2 paths working.
+# Ed25519, curve25519 and chacha20-poly1305, OpenSSH's defaults, are left
+# out: OpenSSH computes them itself and asks wolfProvider only for RNG and
+# SHA-2, which both suites already use.
+#
+# Runs as root with /usr/sbin/sshd, binds sshd to 127.0.0.1:2222, and works
+# in a new mktemp directory under /tmp.
-# Configuration
-KEY_TYPES=("rsa" "ecdsa" "ed25519" "chacha20-poly1305")
+SUITE="aes-ctr"
ITERATIONS=10
-GITHUB_ITERATIONS=5
-TEST_BASE_DIR="/tmp/git-wolfprovider-test"
-SSH_TEST_ENABLED=${SSH_TEST_ENABLED:-true}
+VERBOSE_OUTPUT=false
+WOLFPROV_FORCE_FAIL=${WOLFPROV_FORCE_FAIL:-0}
-# Non-interactive settings
-VERBOSE_OUTPUT=${VERBOSE_OUTPUT:-false}
-QUIET_MODE=${QUIET_MODE:-false}
-MAX_LOG_LINES=${MAX_LOG_LINES:-5}
+# OpenSSH exits in seed_rng() when wolfProvider's RNG fails.
+FORCE_FAIL_REASON="PRNG is not seeded"
-# Force fail functionality
-WOLFPROV_FORCE_FAIL=${WOLFPROV_FORCE_FAIL:-0}
-FORCE_FAIL_PASSED=0
-FAIL=0
+SSH_PORT=2222
+# Seconds before a single setup step or client command is killed
+OP_TIMEOUT=120
+# Set by init_workspace(), together with every path inside it
+TEST_BASE_DIR=""
+# Commit that the next pull or fetch must bring in, set by advance_remote()
+REMOTE_HEAD=""
-source "scripts/cmd-test/cmd-test-common.sh"
+OPS=("keygen" "clone" "push" "pull" "fetch")
+declare -A OK_COUNT RNG_COUNT FAIL_COUNT SKIP_COUNT
# Colors for output
RED='\033[0;31m'
@@ -74,925 +91,461 @@ print_status() {
esac
}
-# Function to handle force fail scenarios
-check_force_fail() {
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- ((FORCE_FAIL_PASSED++))
- fi
+is_force_fail() {
+ [ "${WOLFPROV_FORCE_FAIL}" = "1" ]
}
-# Function to setup git test environment
-setup_git_environment() {
- echo "=== Setting up Git Test Environment ==="
+# Print the last lines of a log file, if it has any
+show_log() {
+ local title=$1
+ local file=$2
- # Clean up any existing test directory
- rm -rf "$TEST_BASE_DIR"
- mkdir -p "$TEST_BASE_DIR"
- cd "$TEST_BASE_DIR"
-
- # Configure git
- git config --global user.name "Test User"
- git config --global user.email "test@example.com"
- git config --global init.defaultBranch main
-
- # Create bare repository
- git init --bare test-repo.git
- print_status "SUCCESS" "Created bare repository at $TEST_BASE_DIR/test-repo.git"
-
- # Create workspace and initial commit
- mkdir test-workspace
- cd test-workspace
- git init
- echo "# Test Repository" > README.md
- git add README.md
- git commit -m "Initial commit"
- git remote add origin "$TEST_BASE_DIR/test-repo.git"
- git push origin main
- print_status "SUCCESS" "Created initial commit and pushed to bare repository"
-
- cd "$TEST_BASE_DIR"
- echo ""
+ if [ -s "$file" ]; then
+ echo "--- $title (last 20 lines of $file) ---"
+ tail -20 "$file"
+ fi
}
-# Function to verify repository setup
-verify_repository() {
- echo "=== Repository Setup Verification ==="
- echo "Checking test repository:"
- ls -la "$TEST_BASE_DIR/"
- echo ""
- echo "Repository contents:"
- ls -la "$TEST_BASE_DIR/test-repo.git/"
- echo ""
- echo "Git log in bare repository:"
- cd "$TEST_BASE_DIR/test-repo.git" && git log --oneline
- echo ""
- echo "Git branches in bare repository:"
- cd "$TEST_BASE_DIR/test-repo.git" && git branch -a
- echo ""
- echo "Git refs in bare repository:"
- cd "$TEST_BASE_DIR/test-repo.git" && git show-ref
- echo ""
-
- echo "Git information:"
- which git
- git --version
- echo "Git help (first 10 lines):"
- git help -a | head -10
- echo ""
+die() {
+ print_status "FAILURE" "$1"
+ show_log "setup log" "$SETUP_LOG"
+ show_log "sshd log" "$SSHD_LOG"
+ exit 1
}
-# Function to verify SSH setup and algorithm negotiation
-verify_ssh_setup() {
- echo "=== SSH Setup and Algorithm Verification ==="
- echo ""
-
- # Check for force fail mode and provide context
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- print_status "INFO" "Force fail mode enabled - testing SSH algorithm behavior"
- echo "Note: SSH defaults to ed25519 and chacha20-poly1305"
- echo "These algorithms use OpenSSH's inline crypto, not OpenSSL/wolfProvider"
- echo "Force fail will pass for default behavior since wolfProvider is not used"
- echo ""
- echo "SSH-specific forced key generation tests will fail successfully as expected."
- echo "Since openssl is used for trivial things surrounding the operation WPFF will"
- echo "make the test fail. However, this DOES NOT mean that wolfProvider/openssl is"
- echo "being used."
- echo ""
+# Run a setup step without force fail and stop the test if it fails
+setup_run() {
+ if ! env -u WOLFPROV_FORCE_FAIL timeout "$OP_TIMEOUT" "$@" \
+ >>"$SETUP_LOG" 2>&1; then
+ die "Setup step failed: $*"
fi
+}
- # Git SSH environment variables
- echo "=== Git SSH Environment ==="
- echo "GIT_SSH: ${GIT_SSH:-not set}"
- echo "GIT_SSH_COMMAND: ${GIT_SSH_COMMAND:-not set}"
- echo ""
+select_suite() {
+ case "$SUITE" in
+ "aes-ctr")
+ KEY_TYPE="rsa"
+ KEY_BITS=4096
+ KEY_ALGO="rsa-sha2-512"
+ HOST_KEY_NAME="ssh-rsa"
+ KEX_ALGO="diffie-hellman-group14-sha256"
+ CIPHER="aes128-ctr"
+ MAC="hmac-sha2-256"
+ NEGOTIATED_MAC="hmac-sha2-256"
+ ;;
+ "aes-gcm")
+ KEY_TYPE="ecdsa"
+ KEY_BITS=521
+ KEY_ALGO="ecdsa-sha2-nistp521"
+ HOST_KEY_NAME="ecdsa-sha2-nistp521"
+ KEX_ALGO="ecdh-sha2-nistp256"
+ CIPHER="aes256-gcm@openssh.com"
+ MAC="hmac-sha2-256"
+ NEGOTIATED_MAC=""
+ ;;
+ *)
+ echo "Unknown suite: $SUITE"
+ show_usage
+ exit 1
+ ;;
+ esac
+}
- # SSH binary information
- echo "=== SSH Binary Information ==="
- local ssh_binary=$(which ssh)
- echo "SSH binary: $ssh_binary"
- echo "SSH version: $(ssh -V 2>&1)"
- echo ""
+ssh_command() {
+ local key=$1
- # Detect git remote host
- local git_remote_url=$(git remote get-url origin 2>/dev/null || echo "")
- local git_host="github.com"
- if [[ -n "$git_remote_url" ]]; then
- if [[ "$git_remote_url" =~ ^git@([^:]+): ]]; then
- git_host="${BASH_REMATCH[1]}"
- elif [[ "$git_remote_url" =~ ^ssh://([^/]+)/ ]]; then
- git_host="${BASH_REMATCH[1]}"
- elif [[ "$git_remote_url" =~ ^https?://([^/]+)/ ]]; then
- git_host="${BASH_REMATCH[1]}"
- fi
- fi
+ echo "ssh -F /dev/null -i $key -o IdentitiesOnly=yes -o BatchMode=yes" \
+ "-o StrictHostKeyChecking=yes -o UserKnownHostsFile=$KNOWN_HOSTS" \
+ "-o GlobalKnownHostsFile=/dev/null -o ConnectTimeout=10" \
+ "-o ServerAliveInterval=10 -o ServerAliveCountMax=3" \
+ "-o HostKeyAlgorithms=$KEY_ALGO -o PubkeyAcceptedAlgorithms=$KEY_ALGO" \
+ "-o KexAlgorithms=$KEX_ALGO -o Ciphers=$CIPHER -o MACs=$MAC" \
+ "-v -E $SSH_LOG"
+}
- local ssh_host="git@$git_host"
- echo "Target SSH host: $ssh_host"
- echo ""
+sshd_listening() {
+ (exec 3<>"/dev/tcp/127.0.0.1/$SSH_PORT") 2>/dev/null
+}
- # SSH algorithm negotiation test
- echo "=== SSH Algorithm Negotiation Test ==="
- local ssh_log="/tmp/ssh-negotiation.log"
- local ssh_error_log="/tmp/ssh-negotiation-errors.log"
+# Create a new workspace (mode 0700) and derive every test path from it
+init_workspace() {
+ TEST_BASE_DIR=$(mktemp -d /tmp/git-wolfprovider-test.XXXXXX) || {
+ echo "Cannot create a workspace under /tmp"
+ exit 1
+ }
+ KEY_DIR="$TEST_BASE_DIR/keys"
+ HOST_KEY="$KEY_DIR/host_key"
+ SETUP_KEY="$KEY_DIR/setup_key"
+ AUTH_KEYS="$KEY_DIR/authorized_keys"
+ KNOWN_HOSTS="$KEY_DIR/known_hosts"
+ SSHD_CONFIG="$TEST_BASE_DIR/sshd_config"
+ SSHD_PID="$TEST_BASE_DIR/sshd.pid"
+ SSHD_LOG="$TEST_BASE_DIR/sshd.log"
+ SETUP_LOG="$TEST_BASE_DIR/setup.log"
+ OP_LOG="$TEST_BASE_DIR/op.log"
+ SSH_LOG="$TEST_BASE_DIR/ssh.log"
+ BARE_REPO="$TEST_BASE_DIR/test-repo.git"
+ SETUP_CLONE="$TEST_BASE_DIR/setup-clone"
+ UPSTREAM_CLONE="$TEST_BASE_DIR/upstream-clone"
+}
- print_status "INFO" "Testing SSH connection with verbose output..."
- if timeout 10 ssh -vvv -o ConnectTimeout=5 -o BatchMode=yes "$ssh_host" 2>"$ssh_error_log" >"$ssh_log" 2>&1; then
- print_status "SUCCESS" "SSH connection test completed"
- else
- print_status "INFO" "SSH connection test completed (connection may have failed as expected)"
+# Stop the sshd this run started and remove its workspace
+cleanup() {
+ if [ -z "$TEST_BASE_DIR" ]; then
+ return
fi
+ if [ -s "$SSHD_PID" ]; then
+ kill "$(cat "$SSHD_PID")" 2>/dev/null
+ fi
+ rm -rf "$TEST_BASE_DIR"
+}
- # Parse algorithm negotiation results
- echo "=== Algorithm Negotiation Results ==="
- if [ -f "$ssh_log" ] && [ -s "$ssh_log" ]; then
- # Extract key algorithms
- local kex_algo=$(grep "kex: algorithm:" "$ssh_log" | tail -1 | awk '{print $NF}' || echo "unknown")
- local hostkey_algo=$(grep "kex: host key algorithm:" "$ssh_log" | tail -1 | awk '{print $NF}' || echo "unknown")
- local cipher_sc=$(grep "server->client cipher:" "$ssh_log" | tail -1 | awk '{print $5}' || echo "unknown")
- local cipher_cs=$(grep "client->server cipher:" "$ssh_log" | tail -1 | awk '{print $5}' || echo "unknown")
-
- echo "Key Exchange Algorithm: $kex_algo"
- echo "Host Key Algorithm: $hostkey_algo"
- echo "Server->Client Cipher: $cipher_sc"
- echo "Client->Server Cipher: $cipher_cs"
- echo ""
-
- # Check for ed25519 and chacha20-poly1305 usage
- local uses_ed25519=false
- local uses_chacha20=false
-
- if [[ "$hostkey_algo" == *"ed25519"* ]]; then
- uses_ed25519=true
- fi
- if [[ "$cipher_sc" == *"chacha20"* ]] || [[ "$cipher_cs" == *"chacha20"* ]]; then
- uses_chacha20=true
- fi
+# Check that ssh and openssl load the replace-default libcrypto
+check_install() {
+ local version
+ local providers
- if [ "$uses_ed25519" = true ] || [ "$uses_chacha20" = true ]; then
- print_status "INFO" "Modern SSH algorithms detected"
- if [ "$uses_ed25519" = true ]; then
- echo " - ed25519 host key algorithm detected (OpenSSH inline crypto)"
- fi
- if [ "$uses_chacha20" = true ]; then
- echo " - chacha20-poly1305 cipher detected (OpenSSH inline crypto)"
- fi
- echo " - These algorithms bypass OpenSSL/wolfProvider"
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- print_status "SUCCESS" "Force fail will pass - wolfProvider not used by default SSH algorithms"
- fi
- else
- print_status "INFO" "Traditional SSH algorithms detected"
- echo " - These algorithms may use OpenSSL/wolfProvider"
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- print_status "WARNING" "Force fail may not pass - wolfProvider may be used"
- fi
- fi
- else
- print_status "WARNING" "Could not parse SSH negotiation results"
- echo "SSH log file: $ssh_log"
- echo "SSH error log: $ssh_error_log"
+ echo "=== Installation Check ==="
+ version=$(env -u WOLFPROV_FORCE_FAIL ssh -V 2>&1)
+ echo "ssh -V: $version"
+ case "$version" in
+ *"+wolfProvider-replace-default"*)
+ ;;
+ *)
+ die "ssh is not linked with the wolfProvider replace-default libcrypto"
+ ;;
+ esac
+
+ providers=$(env -u WOLFPROV_FORCE_FAIL openssl list -providers 2>&1)
+ echo "$providers"
+ case "$providers" in
+ *"wolfSSL Provider"*)
+ ;;
+ *)
+ die "wolfProvider is not the active provider"
+ ;;
+ esac
+
+ if [ ! -x /usr/sbin/sshd ]; then
+ die "/usr/sbin/sshd not found"
fi
echo ""
+}
- # Library linkage analysis
- echo "=== SSH Binary Library Analysis ==="
- if command -v ldd >/dev/null 2>&1; then
- echo "Library dependencies:"
- ldd "$ssh_binary" | grep -E -i 'ssl|crypto|wolf|gnutls' || echo " No SSL/Crypto/Wolf/GnuTLS libraries linked"
- else
- echo "ldd not available for library analysis"
+setup_sshd() {
+ echo "=== Starting sshd on 127.0.0.1:$SSH_PORT ($SUITE) ==="
+
+ setup_run ssh-keygen -q -t "$KEY_TYPE" -b "$KEY_BITS" -N "" \
+ -C "git-ssh-dr-host" -f "$HOST_KEY"
+ setup_run ssh-keygen -q -t "$KEY_TYPE" -b "$KEY_BITS" -N "" \
+ -C "git-ssh-dr-setup" -f "$SETUP_KEY"
+ cp "$SETUP_KEY.pub" "$AUTH_KEYS"
+ echo "[127.0.0.1]:$SSH_PORT $(cut -d' ' -f1,2 "$HOST_KEY.pub")" \
+ > "$KNOWN_HOSTS"
+
+ cat > "$SSHD_CONFIG" < "$GIT_CONFIG_GLOBAL" < "$seed/README.md"
+ setup_run git -C "$seed" add README.md
+ setup_run git -C "$seed" commit -q -m "Initial commit"
+ setup_run git -C "$seed" push -q "$BARE_REPO" main
+
+ # Clone over SSH: the server works, and force fail has a clone to use
+ setup_run env GIT_SSH_COMMAND="$(ssh_command "$SETUP_KEY")" \
+ git clone -q "$REPO_URL" "$SETUP_CLONE"
+ print_status "SUCCESS" "Created $BARE_REPO and cloned it over SSH"
+
+ # Local clone that adds commits for pull and fetch to download
+ setup_run git clone -q "$BARE_REPO" "$UPSTREAM_CLONE"
echo ""
+}
- # Clean up temporary files
- rm -f "$ssh_log" "$ssh_error_log"
+# Require the suite's algorithms in the ssh client log of the last operation
+check_negotiation() {
+ local want
+
+ for want in "kex: algorithm: $KEX_ALGO" \
+ "kex: host key algorithm: $KEY_ALGO" \
+ "kex: server->client cipher: $CIPHER MAC: $NEGOTIATED_MAC" \
+ "kex: client->server cipher: $CIPHER MAC: $NEGOTIATED_MAC" \
+ "Server host key: $HOST_KEY_NAME" \
+ "Authenticated to 127.0.0.1"; do
+ if ! grep -qF "$want" "$SSH_LOG"; then
+ echo "Not found in ssh log: $want"
+ return 1
+ fi
+ done
}
-# Function to test GitHub SSH connectivity
-test_github_ssh_connectivity() {
- echo "=== Testing GitHub SSH Connectivity ==="
- echo "Testing lightweight git operation to GitHub via SSH"
- echo ""
+# Require that ref in dir is the commit advance_remote() pushed last
+check_ref() {
+ local dir=$1
+ local ref=$2
+ local id
- local github_repo="git@github.com:wolfSSL/wolfProvider.git"
- local test_iterations=${1:-1} # Default to 1 iteration for GitHub test
- local success_count=0
- local failure_count=0
- local timing_log="/tmp/github-ssh-timing.log"
- local error_log="/tmp/github-ssh-errors.log"
+ if [ -z "$REMOTE_HEAD" ]; then
+ return 0
+ fi
+ id=$(git -C "$dir" rev-parse "$ref") || return 1
+ if [ "$id" != "$REMOTE_HEAD" ]; then
+ echo "$ref is $id, expected $REMOTE_HEAD"
+ return 1
+ fi
+}
- # Clear previous logs
- > "$timing_log"
- > "$error_log"
+op_keygen() {
+ local key=$1
- echo "Testing git ls-remote to $github_repo"
- echo "This tests SSH connectivity and crypto without heavy operations"
- echo ""
+ timeout "$OP_TIMEOUT" ssh-keygen -q -t "$KEY_TYPE" -b "$KEY_BITS" -N "" \
+ -C "git-ssh-dr-test" -f "$key"
+}
- # Ensure we're in a valid directory for git operations
- local original_dir=$(pwd)
- cd /tmp || cd / || cd "$HOME" || true
- echo "Current directory: $(pwd)"
- echo ""
+op_clone() {
+ local key=$1
+ local dir=$2
- for ((attempt=1; attempt<=test_iterations; attempt++)); do
- echo "--- GitHub SSH Test $attempt ---"
-
- local start_time=$(date +%s.%N)
- local status="UNKNOWN"
-
- echo "Attempting git ls-remote to GitHub..."
-
- # Test the lightweight git operation
- if timeout 30 git ls-remote "$github_repo" HEAD 2>>"$error_log" | head -1 >/dev/null; then
- local end_time=$(date +%s.%N)
- local duration=$(echo "$end_time - $start_time" | bc -l)
-
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "GitHub SSH operation successful (with WPFF=1"
- check_force_fail
- else
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "GitHub SSH operation successful"
- fi
-
- echo " GitHub SSH test: $status ($(printf "%.6f" "$duration")s)"
- echo "$attempt,$status,$duration" >> "$timing_log"
- else
- local end_time=$(date +%s.%N)
- local duration=$(echo "$end_time - $start_time" | bc -l)
-
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="EXPECTED_FAIL"
- print_status "SUCCESS" "GitHub SSH operation failed as expected (WPFF=1)"
- else
- status="FAILURE"
- ((failure_count++))
- print_status "FAILURE" "GitHub SSH operation failed on attempt $attempt"
- fi
-
- echo " GitHub SSH test: $status ($(printf "%.6f" "$duration")s)"
- echo "$attempt,$status,$duration" >> "$timing_log"
- fi
-
- echo ""
- done
+ GIT_SSH_COMMAND="$(ssh_command "$key")" \
+ timeout "$OP_TIMEOUT" git clone "$REPO_URL" "$dir" &&
+ check_negotiation
+}
- # Summary
- echo "=== GITHUB SSH TEST SUMMARY ==="
- echo "Total operations: $((success_count + failure_count))"
- echo "Successful operations: $success_count"
- echo "Failed operations: $failure_count"
- if [ $((success_count + failure_count)) -gt 0 ]; then
- local failure_rate=$((failure_count * 100 / (success_count + failure_count)))
- echo "Failure rate: ${failure_rate}%"
- else
- echo "Failure rate: 0%"
+op_push() {
+ local key=$1
+ local dir=$2
+ local head
+ local remote
+
+ GIT_SSH_COMMAND="$(ssh_command "$key")" \
+ timeout "$OP_TIMEOUT" git -C "$dir" push origin main || return
+ check_negotiation || return 1
+
+ head=$(git -C "$dir" rev-parse HEAD) || return 1
+ remote=$(GIT_SSH_COMMAND="$(ssh_command "$key")" \
+ timeout "$OP_TIMEOUT" git -C "$dir" ls-remote origin refs/heads/main) ||
+ return
+ if [ "${remote%%[[:space:]]*}" != "$head" ]; then
+ echo "Remote main is '$remote', expected $head"
+ return 1
fi
- echo ""
- echo "GitHub SSH timing data saved to: $timing_log"
- echo "GitHub SSH error log saved to: $error_log"
- echo ""
+}
- # Show error log summary if there were errors
- if [ -s "$error_log" ]; then
- echo "=== GITHUB SSH ERROR LOG SUMMARY ==="
- head -20 "$error_log"
- if [ $(wc -l < "$error_log") -gt 20 ]; then
- echo "... (showing first 20 lines, see $error_log for full log)"
- fi
- echo ""
- fi
+op_pull() {
+ local key=$1
+ local dir=$2
- # Return to original directory
- cd "$original_dir" 2>/dev/null || true
+ GIT_SSH_COMMAND="$(ssh_command "$key")" \
+ timeout "$OP_TIMEOUT" git -C "$dir" pull origin main &&
+ check_negotiation && check_ref "$dir" HEAD
}
-# Function to test git operations
-test_git_operations() {
- local key_type=$1
- local iterations=$2
-
- echo "=== Testing Git Operations for $key_type ==="
-
- local success_count=0
- local failure_count=0
- local timing_log="/tmp/git-timing-$key_type.log"
- local error_log="/tmp/git-errors-$key_type.log"
-
- echo "Iteration,Operation,Status,Duration,Error" > "$timing_log"
-
- for attempt in $(seq 1 "$iterations"); do
- echo "--- Attempt $attempt for $key_type ---"
- local test_dir="$TEST_BASE_DIR/git-test-$attempt"
- mkdir -p "$test_dir"
- cd "$test_dir"
-
- for operation in "clone" "push" "pull" "fetch"; do
- echo "Testing $operation operation..."
- local start_time=$(date +%s.%N)
- local status="UNKNOWN"
-
- case "$operation" in
- "clone")
- echo "Attempting to clone from $TEST_BASE_DIR/test-repo.git"
- echo "Current directory: $(pwd)"
- echo "Repository exists: $(test -d "$TEST_BASE_DIR/test-repo.git" && echo 'YES' || echo 'NO')"
-
- if git clone --verbose "$TEST_BASE_DIR/test-repo.git" cloned-repo 2>&1 | tee -a "$error_log"; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Clone successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Clone successful"
- fi
-
- # Verify the clone worked
- if [ -d "cloned-repo" ]; then
- echo "Cloned repository exists and contains:"
- ls -la cloned-repo/
- echo "Git status in cloned repo:"
- cd cloned-repo
- if ! git status 2>/dev/null; then
- echo "WARNING: Git status failed - potential wolfProvider interference"
- print_status "WARNING" "Git status failed in cloned repo"
- fi
- echo "Git log in cloned repo:"
- if ! git log --oneline | head -${MAX_LOG_LINES} 2>/dev/null; then
- echo "WARNING: Git log failed - potential wolfProvider interference"
- print_status "WARNING" "Git log failed in cloned repo"
- fi
- cd ..
- else
- print_status "FAILURE" "cloned-repo directory not found after successful clone"
- status="FAILURE"
- ((failure_count++))
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="EXPECTED_FAIL"
- print_status "SUCCESS" "Clone failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "Clone failed on attempt $attempt"
- fi
- fi
- ;;
-
- "push")
- if [ -d "cloned-repo" ]; then
- echo "Entering cloned-repo directory..."
- cd cloned-repo
- echo "Test change $attempt" >> test-file.txt
- git add test-file.txt
- git commit -m "Test commit $attempt" || true
- echo "Attempting git push..."
- if timeout 30 git push origin main 2>>"$error_log"; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Push successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Push successful"
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="EXPECTED_FAIL"
- print_status "SUCCESS" "Push failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "Push failed on attempt $attempt"
- fi
- fi
- cd ..
- else
- status="SKIPPED"
- echo "Skipping push - clone failed"
- fi
- ;;
-
- "pull")
- if [ -d "cloned-repo" ]; then
- echo "Entering cloned-repo directory for pull..."
- cd cloned-repo
- echo "Attempting git pull..."
- if timeout 30 git pull origin main 2>>"$error_log"; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Pull successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Pull successful"
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="EXPECTED_FAIL"
- print_status "SUCCESS" "Pull failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "Pull failed on attempt $attempt"
- fi
- fi
- cd ..
- else
- status="SKIPPED"
- echo "Skipping pull - clone failed"
- fi
- ;;
-
- "fetch")
- if [ -d "cloned-repo" ]; then
- echo "Entering cloned-repo directory for fetch..."
- cd cloned-repo
- echo "Attempting git fetch..."
- if timeout 30 git fetch origin 2>>"$error_log"; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Fetch successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Fetch successful"
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="EXPECTED_FAIL"
- print_status "SUCCESS" "Fetch failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "Fetch failed on attempt $attempt"
- fi
- fi
- cd ..
- else
- status="SKIPPED"
- echo "Skipping fetch - clone failed"
- fi
- ;;
- esac
-
- local end_time=$(date +%s.%N)
- local duration=$(echo "$end_time - $start_time" | bc -l 2>/dev/null || echo "0")
- echo "$attempt,$operation,$status,$duration," >> "$timing_log"
- echo " $operation: $status (${duration}s)"
- done
-
- rm -rf "$test_dir"
- done
-
- # Print summary
- echo ""
- echo "=== SUMMARY FOR $key_type ==="
- echo "Total operations: $((success_count + failure_count))"
- echo "Successful operations: $success_count"
- echo "Failed operations: $failure_count"
-
- if [ $failure_count -gt 0 ]; then
- local failure_rate=$(echo "scale=2; $failure_count * 100 / ($success_count + failure_count)" | bc -l)
- echo "Failure rate: ${failure_rate}%"
- else
- echo "Failure rate: 0%"
- fi
+op_fetch() {
+ local key=$1
+ local dir=$2
- echo ""
- echo "Timing data saved to: $timing_log"
- echo "Error log saved to: $error_log"
+ GIT_SSH_COMMAND="$(ssh_command "$key")" \
+ timeout "$OP_TIMEOUT" git -C "$dir" fetch origin &&
+ check_negotiation && check_ref "$dir" origin/main
+}
- if [ -f "$error_log" ] && [ -s "$error_log" ]; then
- echo ""
- echo "=== ERROR LOG SUMMARY ==="
- tail -20 "$error_log"
+# Run one client operation, count its result and return its exit status
+run_op() {
+ local op=$1
+ local rc
+ local outcome
+ local expected
+ shift
+
+ : > "$OP_LOG"
+ : > "$SSH_LOG"
+ "$@" >"$OP_LOG" 2>&1
+ rc=$?
+ if [ $rc -eq 124 ]; then
+ echo "Timed out after ${OP_TIMEOUT}s" >> "$OP_LOG"
fi
- echo ""
-}
-# Function to test git operations with different SSH key types
-test_ssh_key_operations() {
- local key_type=$1
- local iterations=$2
+ if [ "$VERBOSE_OUTPUT" = "true" ]; then
+ sed 's/^/ /' "$OP_LOG"
+ fi
- echo "=== Testing Git Operations with $key_type SSH Keys ==="
- echo "Investigating intermittent failures with wolfProvider + git + SSH keys"
- echo ""
+ if [ $rc -eq 0 ]; then
+ ((OK_COUNT[$op]++))
+ outcome="succeeded"
+ elif grep -qF "$FORCE_FAIL_REASON" "$OP_LOG" "$SSH_LOG"; then
+ ((RNG_COUNT[$op]++))
+ outcome="failed on the RNG"
+ else
+ ((FAIL_COUNT[$op]++))
+ outcome="failed"
+ fi
- # Verify wolfProvider is still active (if available)
- echo "Pre-SSH wolfProvider Verification:"
- if openssl list -providers | grep -q "wolfSSL Provider"; then
- print_status "SUCCESS" "wolfProvider is active before SSH key operations"
+ if is_force_fail; then
+ expected="failed on the RNG"
else
- print_status "INFO" "wolfProvider not detected - testing SSH keys without wolfProvider"
+ expected="succeeded"
+ fi
+ if [ "$outcome" = "$expected" ]; then
+ print_status "SUCCESS" "$op $outcome"
+ else
+ print_status "FAILURE" "$op $outcome"
+ show_log "$op output" "$OP_LOG"
+ show_log "ssh log" "$SSH_LOG"
+ show_log "sshd log" "$SSHD_LOG"
fi
- echo ""
- local success_count=0
- local failure_count=0
- local timing_log="/tmp/ssh-key-timing-$key_type.log"
- local error_log="/tmp/ssh-key-errors-$key_type.log"
-
- echo "Iteration,Operation,Status,Duration,Error" > "$timing_log"
-
- # Test SSH key generation and git operations
- for attempt in $(seq 1 "$iterations"); do
- echo "--- SSH Key Test $attempt for $key_type ---"
- local test_dir="$TEST_BASE_DIR/ssh-key-test-$attempt"
- mkdir -p "$test_dir"
- cd "$test_dir"
-
- # Generate SSH key for this attempt
- local ssh_key="/tmp/test_${key_type}_key_$attempt"
- local ssh_pub_key="${ssh_key}.pub"
-
- echo "Generating $key_type SSH key (attempt $attempt)..."
- local key_gen_start=$(date +%s.%N)
- local key_gen_status="UNKNOWN"
-
- case "$key_type" in
- "rsa")
- if ssh-keygen -t rsa -b 4096 -f "$ssh_key" -N "" -C "test-rsa-key-$attempt" 2>/dev/null; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- key_gen_status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "RSA key generation successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- key_gen_status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "RSA key generation successful"
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- key_gen_status="EXPECTED_FAIL"
- print_status "SUCCESS" "RSA key generation failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- key_gen_status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "RSA key generation failed"
- fi
- fi
- ;;
- "ecdsa")
- if ssh-keygen -t ecdsa -b 521 -f "$ssh_key" -N "" -C "test-ecdsa-key-$attempt" 2>/dev/null; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- key_gen_status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "ECDSA key generation successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- key_gen_status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "ECDSA key generation successful"
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- key_gen_status="EXPECTED_FAIL"
- print_status "SUCCESS" "ECDSA key generation failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- key_gen_status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "ECDSA key generation failed"
- fi
- fi
- ;;
- "ed25519")
- if ssh-keygen -t ed25519 -f "$ssh_key" -N "" -C "test-ed25519-key-$attempt" 2>/dev/null; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- key_gen_status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "ED25519 key generation successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- key_gen_status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "ED25519 key generation successful"
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- key_gen_status="EXPECTED_FAIL"
- print_status "SUCCESS" "ED25519 key generation failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- key_gen_status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "ED25519 key generation failed"
- fi
- fi
- ;;
- "chacha20-poly1305")
- # Use chacha20-poly1305 cipher for SSH key encryption (default cipher in SSH)
- if ssh-keygen -t ed25519 -Z chacha20-poly1305@openssh.com -f "$ssh_key" -N "" -C "test-chacha20-poly1305-key-$attempt" 2>/dev/null; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- key_gen_status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "chacha20-poly1305 SSH key generation successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- key_gen_status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "chacha20-poly1305 SSH key generation successful"
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- key_gen_status="EXPECTED_FAIL"
- print_status "SUCCESS" "chacha20-poly1305 SSH key generation failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- key_gen_status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "chacha20-poly1305 SSH key generation failed"
- fi
- fi
- ;;
- esac
+ return $rc
+}
- local key_gen_end=$(date +%s.%N)
- local key_gen_duration=$(echo "$key_gen_end - $key_gen_start" | bc -l 2>/dev/null || echo "0")
- echo "$attempt,key_generation,$key_gen_status,$key_gen_duration," >> "$timing_log"
- echo " Key generation: $key_gen_status (${key_gen_duration}s)"
-
- if [ "$key_gen_status" = "SUCCESS" ] && [ -f "$ssh_key" ]; then
- echo "Key fingerprint: $(ssh-keygen -lf "$ssh_pub_key" 2>/dev/null | awk '{print $2}')"
- echo "Key size: $(stat -c%s "$ssh_key") bytes"
-
- # Test git operations with this SSH key
- for operation in "clone" "push" "pull" "fetch"; do
- echo "Testing git $operation with $key_type SSH key..."
- local start_time=$(date +%s.%N)
- local status="UNKNOWN"
-
- case "$operation" in
- "clone")
- echo "Setting up SSH key for git operations..."
- mkdir -p ~/.ssh
- cp "$ssh_key" ~/.ssh/id_${key_type}_test
- cp "$ssh_pub_key" ~/.ssh/id_${key_type}_test.pub
- chmod 600 ~/.ssh/id_${key_type}_test
- chmod 644 ~/.ssh/id_${key_type}_test.pub
-
- # Test git clone with SSH key (using local path but with SSH key setup)
- if git clone --verbose "$TEST_BASE_DIR/test-repo.git" cloned-repo 2>&1 | tee -a "$error_log"; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Git clone with $key_type key successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Git clone with $key_type key successful"
- fi
-
- if [ -d "cloned-repo" ]; then
- echo "Cloned repository exists and contains:"
- ls -la cloned-repo/
- echo "Git status in cloned repo:"
- cd cloned-repo
- git status || echo "Git status failed (this may be normal)"
- echo "Git log in cloned repo:"
- git log --oneline | head -${MAX_LOG_LINES} || echo "Git log failed"
- cd ..
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="EXPECTED_FAIL"
- print_status "SUCCESS" "Git clone with $key_type key failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "Git clone with $key_type key failed"
- fi
- fi
- ;;
-
- "push")
- if [ -d "cloned-repo" ]; then
- echo "Entering cloned-repo directory for git push..."
- cd cloned-repo
- echo "Test change $attempt with $key_type key" >> test-file.txt
- git add test-file.txt
- git commit -m "$key_type Test commit $attempt" || true
- echo "Attempting git push..."
- if timeout 30 git push origin main 2>>"$error_log"; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Git push with $key_type key successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Git push with $key_type key successful"
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="EXPECTED_FAIL"
- print_status "SUCCESS" "Git push with $key_type key failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "Git push with $key_type key failed"
- fi
- fi
- cd ..
- else
- status="SKIPPED"
- echo "Skipping push - clone failed"
- fi
- ;;
-
- "pull")
- if [ -d "cloned-repo" ]; then
- echo "Entering cloned-repo directory for git pull..."
- cd cloned-repo
- echo "Attempting git pull..."
- if timeout 30 git pull origin main 2>>"$error_log"; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Git pull with $key_type key successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Git pull with $key_type key successful"
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="EXPECTED_FAIL"
- print_status "SUCCESS" "Git pull with $key_type key failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "Git pull with $key_type key failed"
- fi
- fi
- cd ..
- else
- status="SKIPPED"
- echo "Skipping pull - clone failed"
- fi
- ;;
-
- "fetch")
- if [ -d "cloned-repo" ]; then
- echo "Entering cloned-repo directory for git fetch..."
- cd cloned-repo
- echo "Attempting git fetch..."
- if timeout 30 git fetch origin 2>>"$error_log"; then
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Git fetch with $key_type key successful (with WPFF=1 - using OpenSSH inline crypto as expected)"
- check_force_fail
- else
- status="SUCCESS"
- ((success_count++))
- print_status "SUCCESS" "Git fetch with $key_type key successful"
- fi
- else
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- status="EXPECTED_FAIL"
- print_status "SUCCESS" "Git fetch with $key_type key failed as expected (WPFF=1 - wolfProvider IS being used!)"
- else
- status="FAILURE"
- ((failure_count++))
- FAIL=1
- print_status "FAILURE" "Git fetch with $key_type key failed"
- fi
- fi
- cd ..
- else
- status="SKIPPED"
- echo "Skipping fetch - clone failed"
- fi
- ;;
- esac
-
- local end_time=$(date +%s.%N)
- local duration=$(echo "$end_time - $start_time" | bc -l 2>/dev/null || echo "0")
- echo "$attempt,git_${operation},$status,$duration," >> "$timing_log"
- echo " Git $operation with $key_type: $status (${duration}s)"
- done
-
- # Clean up SSH key for this attempt
- rm -f ~/.ssh/id_${key_type}_test ~/.ssh/id_${key_type}_test.pub
- fi
+skip_op() {
+ local op=$1
- # Clean up test files
- rm -f "$ssh_key" "$ssh_pub_key"
- rm -rf "$test_dir"
- done
+ ((SKIP_COUNT[$op]++))
+ print_status "WARNING" "$op skipped"
+}
- # Print summary
- echo ""
- echo "=== SSH KEY TEST SUMMARY FOR $key_type ==="
- echo "Total operations: $((success_count + failure_count))"
- echo "Successful operations: $success_count"
- echo "Failed operations: $failure_count"
-
- if [ $failure_count -gt 0 ]; then
- local failure_rate=$(echo "scale=2; $failure_count * 100 / ($success_count + failure_count)" | bc -l)
- echo "Failure rate: ${failure_rate}%"
- else
- echo "Failure rate: 0%"
- fi
+# Commit a change to push, without force fail
+make_commit() {
+ local dir=$1
+ local attempt=$2
- echo ""
- echo "SSH Key timing data saved to: $timing_log"
- echo "SSH Key error log saved to: $error_log"
+ echo "Test change $attempt" >> "$dir/test-file.txt"
+ setup_run git -C "$dir" add test-file.txt
+ setup_run git -C "$dir" commit -q -m "Test commit $attempt"
+}
- if [ -f "$error_log" ] && [ -s "$error_log" ]; then
- echo ""
- echo "=== SSH KEY ERROR LOG SUMMARY ==="
- tail -20 "$error_log"
- fi
- echo ""
+# Push a new commit from UPSTREAM_CLONE, without force fail
+advance_remote() {
+ local label=$1
+
+ setup_run git -C "$UPSTREAM_CLONE" pull -q origin main
+ echo "Upstream change $label" >> "$UPSTREAM_CLONE/upstream-file.txt"
+ setup_run git -C "$UPSTREAM_CLONE" add upstream-file.txt
+ setup_run git -C "$UPSTREAM_CLONE" commit -q -m "Upstream commit $label"
+ setup_run git -C "$UPSTREAM_CLONE" push -q origin main
+ REMOTE_HEAD=$(git -C "$UPSTREAM_CLONE" rev-parse HEAD) ||
+ die "Cannot read the upstream clone's HEAD"
}
-# Function to cleanup
-cleanup() {
- echo "=== Cleanup ==="
+# Run keygen, clone, push, pull and fetch once. Under force fail, a step
+# that fails uses the setup key or setup clone so the next step still runs.
+run_iteration() {
+ local attempt=$1
+ local iter_dir="$TEST_BASE_DIR/iter-$attempt"
+ local key="$iter_dir/id_$KEY_TYPE"
+ local clone_key=""
+ local work_dir=""
+ local op
+
+ echo "--- Iteration $attempt of $ITERATIONS ($SUITE) ---"
+ mkdir -p "$iter_dir"
+
+ if run_op "keygen" op_keygen "$key"; then
+ cat "$key.pub" >> "$AUTH_KEYS"
+ clone_key=$key
+ elif is_force_fail; then
+ clone_key=$SETUP_KEY
+ fi
- # Stop SSH server if running
- if pgrep -f "sshd.*2222" > /dev/null; then
- echo "Stopping SSH test server..."
- pkill -f "sshd.*2222" || true
+ if [ -z "$clone_key" ]; then
+ skip_op "clone"
+ elif run_op "clone" op_clone "$clone_key" "$iter_dir/clone"; then
+ work_dir="$iter_dir/clone"
+ elif is_force_fail; then
+ work_dir=$SETUP_CLONE
fi
- # Clean up test directory
- rm -rf "$TEST_BASE_DIR"
- print_status "SUCCESS" "Cleaned up test directory: $TEST_BASE_DIR"
+ for op in "push" "pull" "fetch"; do
+ if [ -z "$work_dir" ]; then
+ skip_op "$op"
+ continue
+ fi
+ if [ "$op" = "push" ]; then
+ make_commit "$work_dir" "$attempt"
+ elif ! is_force_fail; then
+ advance_remote "$attempt-$op"
+ fi
+ if ! run_op "$op" "op_$op" "$clone_key" "$work_dir" &&
+ [ "$op" = "push" ] && ! is_force_fail; then
+ # Drop the unpushed commit so pull can still fast-forward
+ setup_run git -C "$work_dir" reset -q --hard origin/main
+ fi
+ done
+
+ rm -rf "$iter_dir"
echo ""
}
-# Function to show usage
show_usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -h, --help Show this help message"
- echo " -v, --verbose Enable verbose debug output"
- echo " -q, --quiet Enable quiet mode (minimal output)"
- echo " -s, --ssh Enable SSH key testing (default: enabled)"
- echo " -n, --no-ssh Disable SSH key testing"
- echo " -i, --iterations N Number of iterations per test (default: 10)"
- echo " -g, --github-iterations N Number of GitHub SSH test iterations (default: 5)"
- echo " -k, --key-types TYPES Comma-separated key types (default: rsa,ecdsa,ed25519)"
- echo " -l, --log-lines N Maximum git log lines to show (default: 5)"
- echo ""
- echo "Environment Variables:"
- echo " VERBOSE_OUTPUT=true Enable verbose output"
- echo " QUIET_MODE=true Enable quiet mode"
- echo " SSH_TEST_ENABLED=false Disable SSH testing"
- echo " MAX_LOG_LINES=10 Set maximum log lines"
- echo " WOLFPROV_FORCE_FAIL=1 Test if wolfProvider is being used (operations should fail)"
- echo ""
- echo "Examples:"
- echo " $0 # Run all tests with default settings"
- echo " $0 --verbose # Run with verbose debug output"
- echo " $0 --no-ssh # Skip SSH key testing"
- echo " $0 --iterations 20 # Run 20 iterations per test"
- echo " $0 --github-iterations 10 # Run 10 GitHub SSH tests"
- echo " $0 --key-types rsa,ed25519 # Test only RSA and ED25519 keys"
- echo " WOLFPROV_FORCE_FAIL=1 $0 # Test with force fail to verify wolfProvider usage"
+ echo " -v, --verbose Print the output of every operation"
+ echo " -i, --iterations N Number of iterations (default: 10)"
+ echo " -s, --suite SUITE aes-ctr or aes-gcm (default: aes-ctr)"
echo ""
}
-# Function to parse command line arguments
+# Exit unless the option in $1 is followed by a value
+need_value() {
+ if [ $# -lt 2 ]; then
+ echo "Missing value for $1"
+ show_usage
+ exit 1
+ fi
+}
+
parse_args() {
while [[ $# -gt 0 ]]; do
case $1 in
@@ -1004,32 +557,14 @@ parse_args() {
VERBOSE_OUTPUT=true
shift
;;
- -q|--quiet)
- QUIET_MODE=true
- shift
- ;;
- -s|--ssh)
- SSH_TEST_ENABLED=true
- shift
- ;;
- -n|--no-ssh)
- SSH_TEST_ENABLED=false
- shift
- ;;
-i|--iterations)
+ need_value "$@"
ITERATIONS="$2"
shift 2
;;
- -g|--github-iterations)
- GITHUB_ITERATIONS="$2"
- shift 2
- ;;
- -k|--key-types)
- IFS=',' read -ra KEY_TYPES <<< "$2"
- shift 2
- ;;
- -l|--log-lines)
- MAX_LOG_LINES="$2"
+ -s|--suite)
+ need_value "$@"
+ SUITE="$2"
shift 2
;;
*)
@@ -1039,94 +574,85 @@ parse_args() {
;;
esac
done
+
+ if ! [[ "$ITERATIONS" =~ ^[1-9][0-9]*$ ]]; then
+ echo "Invalid iteration count: $ITERATIONS"
+ exit 1
+ fi
}
-# Main execution
main() {
- # Parse command line arguments
- parse_args "$@"
+ local op
+ local ok=0
+ local rng=0
+ local failed=0
+ local skipped=0
- echo "Starting wolfProvider Git Operations Test"
- echo "=========================================="
+ parse_args "$@"
+ select_suite
+
+ echo "=== wolfProvider Git over SSH Test ==="
+ echo "Suite: $SUITE ($KEY_ALGO, $KEX_ALGO, $CIPHER, $MAC)"
+ echo "Iterations: $ITERATIONS"
+ if is_force_fail; then
+ echo "WOLFPROV_FORCE_FAIL=1: client operations are expected to fail" \
+ "with '$FORCE_FAIL_REASON'"
+ fi
echo ""
- # Check if running as root
- if [ "$EUID" -ne 0 ]; then
- print_status "WARNING" "Not running as root. Some operations may fail due to permissions."
- echo "Consider running with: sudo $0"
- echo ""
+ if [ "$(id -u)" -ne 0 ]; then
+ echo "This test starts sshd and must run as root"
+ exit 1
fi
- # Verify wolfProvider is properly installed
- ./scripts/verify-debian.sh
-
- # Verify SSH setup and algorithm negotiation
- verify_ssh_setup
+ trap cleanup EXIT
+ init_workspace
+ mkdir -m 700 "$KEY_DIR"
- # Setup git environment
- setup_git_environment
+ export GIT_CONFIG_GLOBAL="$TEST_BASE_DIR/gitconfig"
+ REPO_URL="ssh://$(id -un)@127.0.0.1:$SSH_PORT$BARE_REPO"
- # Verify repository setup
- verify_repository
+ check_install
+ setup_sshd
+ setup_repository
- # Test git operations for each key type
- for key_type in "${KEY_TYPES[@]}"; do
- test_git_operations "$key_type" "$ITERATIONS"
+ for op in "${OPS[@]}"; do
+ OK_COUNT[$op]=0
+ RNG_COUNT[$op]=0
+ FAIL_COUNT[$op]=0
+ SKIP_COUNT[$op]=0
done
- # Test SSH key operations if enabled
- if [ "$SSH_TEST_ENABLED" = "true" ]; then
- echo "=== SSH Key Testing Enabled ==="
- echo "Testing SSH key generation and validation with different key types"
- echo ""
-
- for key_type in "${KEY_TYPES[@]}"; do
- test_ssh_key_operations "$key_type" "$ITERATIONS"
- done
- else
- echo "=== SSH Key Testing Disabled ==="
- echo "Set SSH_TEST_ENABLED=true to enable SSH key testing"
- echo ""
- fi
-
- # Test GitHub SSH connectivity
- test_github_ssh_connectivity "$GITHUB_ITERATIONS"
+ for attempt in $(seq 1 "$ITERATIONS"); do
+ run_iteration "$attempt"
+ done
- # Final verification
- echo "=== Final wolfProvider Verification ==="
- if openssl list -providers | grep -q "wolfSSL Provider"; then
- print_status "SUCCESS" "wolfProvider is still active after git operations"
- else
- print_status "WARNING" "wolfProvider may have been affected by git operations"
- fi
+ echo "=== Summary ($SUITE, $ITERATIONS iterations) ==="
+ printf " %-7s %9s %12s %14s %8s\n" "" "succeeded" "RNG failure" \
+ "other failure" "skipped"
+ for op in "${OPS[@]}"; do
+ printf " %-7s %9d %12d %14d %8d\n" "$op" "${OK_COUNT[$op]}" \
+ "${RNG_COUNT[$op]}" "${FAIL_COUNT[$op]}" "${SKIP_COUNT[$op]}"
+ ok=$((ok + OK_COUNT[$op]))
+ rng=$((rng + RNG_COUNT[$op]))
+ failed=$((failed + FAIL_COUNT[$op]))
+ skipped=$((skipped + SKIP_COUNT[$op]))
+ done
echo ""
+ # check-workflow-result.sh matches this line in force fail runs
+ echo "Result: $ok succeeded, $rng failed on the RNG, $failed failed" \
+ "otherwise, $skipped skipped"
- # Cleanup
- cleanup
-
- # Handle force fail results like cmd tests
- if [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
- if [ $FORCE_FAIL_PASSED -eq 1 ]; then
- echo ""
- print_status "FAILURE" "Git Tests Failed With Force Fail Enabled"
- echo "ERROR: Some tests passed when they should have failed"
- exit 1
- else
- echo ""
- print_status "SUCCESS" "Git Tests Passed With Force Fail Enabled"
- echo "SUCCESS: All tests failed as expected"
- exit 0
- fi
- else
- if [ $FAIL -eq 0 ]; then
- print_status "SUCCESS" "wolfProvider Git Operations Test completed successfully!"
- exit 0
- else
- print_status "FAILURE" "wolfProvider Git Operations Test completed with failures!"
- exit 1
- fi
+ if [ $rng -eq 0 ] && [ $failed -eq 0 ] && [ $skipped -eq 0 ] &&
+ [ $ok -gt 0 ]; then
+ print_status "SUCCESS" "All $ok operations succeeded"
+ exit 0
+ fi
+ if ! is_force_fail; then
+ show_log "sshd log" "$SSHD_LOG"
+ print_status "FAILURE" "Not every operation succeeded"
fi
+ exit 1
}
-# Run main function
main "$@"