Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 47 additions & 3 deletions .github/workflows/x509-interop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
id: cache-wolfssl
with:
path: build-dir/
key: wolfssh-x509-interop-wolfssl-${{ env.WOLFSSL_REF }}-ubuntu-latest
key: wolfssh-x509-interop-wolfssl-${{ env.WOLFSSL_REF }}-all-ubuntu-latest
lookup-only: true

- name: Checkout, build, and install wolfSSL
Expand All @@ -35,7 +35,18 @@ jobs:
repository: wolfssl/wolfssl
ref: ${{ env.WOLFSSL_REF }}
path: wolfssl
configure: --enable-ssh --enable-keygen --enable-ed25519 --enable-curve25519
# --enable-all defines WOLFSSL_FPKI, which compiles the UPN-vs-username
# binding in wolfSSHd (apps/wolfsshd/auth.c). The client cert carries
# UPN:fred@example, so user "fred" is bound to the certificate. The
# wolfSSHd build still passes -DWOLFSSH_NO_FPKI below so the strict
# FPKI profile (FASCN) is not required of the fred test certificate.
#
# Coverage note: this FPKI build exercises only the WOLFSSL_FPKI
# success/binding path of RequestAuthentication. The non-FPKI
# fail-closed reject branch (apps/wolfsshd/auth.c) is intentionally
# not run here; it is verified at compile time and would need a
# separate non-FPKI build to exercise at runtime.
configure: --enable-all
check: false
install: true

Expand Down Expand Up @@ -86,7 +97,7 @@ jobs:
uses: actions/cache@v5
with:
path: build-dir/
key: wolfssh-x509-interop-wolfssl-${{ env.WOLFSSL_REF }}-ubuntu-latest
key: wolfssh-x509-interop-wolfssl-${{ env.WOLFSSL_REF }}-all-ubuntu-latest
fail-on-cache-miss: true

- name: Restore PKIX-SSH cache
Expand Down Expand Up @@ -199,6 +210,39 @@ jobs:
exit
EOF

- name: Negative test - fred cert must not authenticate as another user
working-directory: ./wolfssh/
run: |
# Regression guard for the cert principal-binding fix: a certificate
# issued for "fred" (UPN:fred@example) must not be accepted for a
# different SSH username. PreferredAuthentications=publickey plus
# BatchMode keep this to a single publickey attempt with no password
# fallback. The preceding positive tests already proved connectivity
# and that fred's cert works; here we additionally require the failure
# to be an authentication denial, so an unrelated ssh error (transport,
# host-key, option change) cannot masquerade as a passing negative test.
sudo useradd -m otheruser
set +e
../build-dir/bin/ssh -o StrictHostKeyChecking=accept-new \
-o PreferredAuthentications=publickey \
-o BatchMode=yes -o NumberOfPasswordPrompts=0 \
-p 22222 -F ssh-pkixssh-config \
-i ./keys/fred-key.pem otheruser@127.0.0.1 exit \
> ssh-neg.out 2> ssh-neg.err
rc=$?
set -e
cat ssh-neg.err || true
if [ "$rc" -eq 0 ]; then
echo "SECURITY FAILURE: fred certificate authenticated as otheruser"
exit 1
fi
if ! grep -qi "permission denied" ssh-neg.err; then
echo "Negative test inconclusive: ssh failed but not with an auth"
echo "denial (possible transport/config error, not a binding reject)"
exit 1
fi
echo "OK: fred certificate correctly rejected for otheruser (auth denied)"

- name: Show wolfSSHd log on failure
if: failure()
working-directory: ./wolfssh/
Expand Down
21 changes: 18 additions & 3 deletions apps/wolfsshd/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -1341,10 +1341,10 @@ static int RequestAuthentication(WS_UserAuthData* authData,
ret = WOLFSSH_USERAUTH_REJECTED;
}
else {
wolfSSH_Log(WS_LOG_INFO,
"[SSHD] Relying on CA for public key check");
#ifdef WIN32
/* Still need to get users token on Windows */
wolfSSH_Log(WS_LOG_INFO,
"[SSHD] Relying on CA for public key check");
rc = SetupUserTokenWin(usr, &authData->sf.publicKey,
wolfSSHD_ConfigGetUserCAKeysFile(usrConf), authCtx);
if (rc == WSSHD_AUTH_SUCCESS) {
Expand All @@ -1356,8 +1356,23 @@ static int RequestAuthentication(WS_UserAuthData* authData,
"[SSHD] Error getting users token.");
ret = WOLFSSH_USERAUTH_FAILURE;
}
#else
#elif defined(WOLFSSL_FPKI)
/* The UPN-vs-username check above already bound the certificate
* to the requested user, so the CA-verified chain is
* sufficient. */
wolfSSH_Log(WS_LOG_INFO,
"[SSHD] Relying on CA for public key check");
ret = WOLFSSH_USERAUTH_SUCCESS;
#else
/* Without FPKI the certificate UPN/principal cannot be read, so
* the requested user cannot be bound to the certificate. Fail
* closed: require AuthorizedKeysFile (per-user key/cert mapping)
* or a wolfSSL build with FPKI. */
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Certificate authentication cannot bind the requested "
"user without FPKI or AuthorizedKeysFile; rejecting "
"(user=%s)", usr);
ret = WOLFSSH_USERAUTH_REJECTED;
#endif
}
}
Expand Down
Loading