diff --git a/.github/workflows/tpm-ssh.yml b/.github/workflows/tpm-ssh.yml index 1f31ee39..0da94347 100644 --- a/.github/workflows/tpm-ssh.yml +++ b/.github/workflows/tpm-ssh.yml @@ -51,12 +51,17 @@ jobs: run: | cd wolfssl ./autogen.sh - # certgen/certreq/certext: generate the X.509 host certificate from the - # TPM key. WC_SIG_MIN_HASH_TYPE=SHA: the RSA x509v3-ssh-rsa host cert is - # SHA-1; modern wolfSSL otherwise rejects SHA-1 RSA signatures. + # certgen/certreq/certext/cryptocb: generate the X.509 host certificate + # from the TPM key via the crypto callback. + EXTRA_CFLAGS="-DWC_RSA_NO_PADDING" + # The RSA x509v3-ssh-rsa host cert is SHA-1; modern wolfSSL otherwise + # rejects SHA-1 RSA signatures. Only needed for the RSA cells. + if [ "${{ matrix.keytype }}" = "rsa" ]; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -DWC_SIG_MIN_HASH_TYPE=WC_HASH_TYPE_SHA" + fi ./configure --enable-wolftpm --enable-wolfssh --enable-keygen \ - --enable-certgen --enable-certreq --enable-certext \ - CFLAGS="-DWC_RSA_NO_PADDING -DWC_SIG_MIN_HASH_TYPE=WC_HASH_TYPE_SHA" + --enable-certgen --enable-certreq --enable-certext --enable-cryptocb \ + CFLAGS="$EXTRA_CFLAGS" make sudo make install sudo ldconfig diff --git a/README.md b/README.md index 09080f0e..98fe0666 100644 --- a/README.md +++ b/README.md @@ -646,6 +646,7 @@ and wolfSSL/wolfTPM built with certificate generation: wolfSSL $ ./configure --enable-wolfssh --enable-wolftpm --enable-keygen \ --enable-certgen --enable-certreq --enable-certext \ + --enable-cryptocb \ CFLAGS="-DWC_RSA_NO_PADDING" wolfTPM $ ./configure --enable-fwtpm --enable-swtpm diff --git a/examples/tpmcertserver/tpmcertclient.c b/examples/tpmcertserver/tpmcertclient.c index a0ea12d7..4262017c 100644 --- a/examples/tpmcertserver/tpmcertclient.c +++ b/examples/tpmcertserver/tpmcertclient.c @@ -52,8 +52,12 @@ static int TpmCcUserAuth(byte authType, WS_UserAuthData* authData, void* ctx) } -/* The server host key is an X.509 certificate; it was already verified against - * the root CA loaded with wolfSSH_CTX_AddRootCert_buffer(). Accept it. */ +/* Host key acceptance callback. wolfSSH verifies the server's X.509 certificate + * chain against the root CA loaded with wolfSSH_CTX_AddRootCert_buffer() later, + * during the key exchange, when it extracts the public key from the certificate. + * Because the client only accepts x509v3 host key algorithms, that CA + * verification is always performed. This callback just accepts the presented + * host key blob. */ static int TpmCcHostKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx) { WOLFSSH_UNUSED(pubKey); diff --git a/examples/tpmcertserver/tpmcertserver.c b/examples/tpmcertserver/tpmcertserver.c index 2e5e4d95..70aaa0f3 100644 --- a/examples/tpmcertserver/tpmcertserver.c +++ b/examples/tpmcertserver/tpmcertserver.c @@ -146,13 +146,14 @@ static int TpmCsMakeKeyAndCert(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, rc = 0; } - /* The crypto callback is only needed to self-sign the certificate. Clear - * it before wolfSSH runs: host-key signing uses wolfTPM2_SignHashScheme() - * directly, and a registered callback would route wolfSSH's certificate - * parsing through the TPM. This reset is required, so treat a failure as - * fatal. */ - if (rc == 0 && devId != INVALID_DEVID) { - rc = wolfTPM2_ClearCryptoDevCb(dev, devId); + /* The crypto callback is only needed to self-sign the certificate. Always + * clear it (including on error paths) before wolfSSH runs: host-key signing + * uses wolfTPM2_SignHashScheme() directly, and a registered callback would + * route wolfSSH's certificate parsing through the TPM. */ + if (devId != INVALID_DEVID) { + int clearRc = wolfTPM2_ClearCryptoDevCb(dev, devId); + if (rc == 0) + rc = clearRc; } /* Restore a clean password session on the device. The certificate signing