wolfsshd: bind certificate auth to user, fail closed without FPKI

pull/1011/head
Yosuke Shimizu 2026-06-11 15:04:33 +09:00 committed by John Safranek
parent cb9bb7a2a7
commit eef8281609
2 changed files with 65 additions and 6 deletions

View File

@ -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
@ -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
@ -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
@ -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/

View File

@ -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) {
@ -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
}
}