Merge pull request #4813 from dgarske/zd13571

Fix for mutual authentication to prevent mismatch of certificate and sigalgo
This commit is contained in:
Sean Parkinson
2022-02-07 11:00:04 +10:00
committed by GitHub

View File

@ -6538,6 +6538,8 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
case TLS_ASYNC_BUILD: case TLS_ASYNC_BUILD:
{ {
int validSigAlgo;
/* Signature algorithm. */ /* Signature algorithm. */
if ((args->idx - args->begin) + ENUM_LEN + ENUM_LEN > totalSz) { if ((args->idx - args->begin) + ENUM_LEN + ENUM_LEN > totalSz) {
ERROR_OUT(BUFFER_ERROR, exit_dcv); ERROR_OUT(BUFFER_ERROR, exit_dcv);
@ -6562,54 +6564,56 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
} }
/* Check for public key of required type. */ /* Check for public key of required type. */
/* Assume invalid unless signature algo matches the key provided */
validSigAlgo = 0;
#ifdef HAVE_ED25519 #ifdef HAVE_ED25519
if (args->sigAlgo == ed25519_sa_algo && if (args->sigAlgo == ed25519_sa_algo) {
!ssl->peerEd25519KeyPresent) { WOLFSSL_MSG("Peer sent ED25519 sig");
WOLFSSL_MSG("Peer sent ED25519 sig but not ED25519 cert"); validSigAlgo = (ssl->peerEd25519Key != NULL) &&
ret = SIG_VERIFY_E; ssl->peerEd25519KeyPresent;
goto exit_dcv;
} }
#endif #endif
#ifdef HAVE_ED448 #ifdef HAVE_ED448
if (args->sigAlgo == ed448_sa_algo && !ssl->peerEd448KeyPresent) { if (args->sigAlgo == ed448_sa_algo) {
WOLFSSL_MSG("Peer sent ED448 sig but not ED448 cert"); WOLFSSL_MSG("Peer sent ED448 sig");
ret = SIG_VERIFY_E; validSigAlgo = (ssl->peerEd448Key != NULL) &&
goto exit_dcv; ssl->peerEd448KeyPresent;
} }
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
if (args->sigAlgo == ecc_dsa_sa_algo && if (args->sigAlgo == ecc_dsa_sa_algo) {
!ssl->peerEccDsaKeyPresent) { WOLFSSL_MSG("Peer sent ECC sig");
WOLFSSL_MSG("Peer sent ECC sig but not ECC cert"); validSigAlgo = (ssl->peerEccDsaKey != NULL) &&
ret = SIG_VERIFY_E; ssl->peerEccDsaKeyPresent;
goto exit_dcv;
} }
#endif #endif
#ifdef HAVE_PQC #ifdef HAVE_PQC
if (args->sigAlgo == falcon_level1_sa_algo && !ssl->peerFalconKeyPresent) { if (args->sigAlgo == falcon_level1_sa_algo) {
WOLFSSL_MSG("Peer sent Falcon Level 1 sig but different cert"); WOLFSSL_MSG("Peer sent Falcon Level 1 sig");
ret = SIG_VERIFY_E; validSigAlgo = (ssl->peerFalconKey != NULL) &&
goto exit_dcv; ssl->peerFalconKeyPresent;
} }
if (args->sigAlgo == falcon_level5_sa_algo && !ssl->peerFalconKeyPresent) { if (args->sigAlgo == falcon_level5_sa_algo) {
WOLFSSL_MSG("Peer sent Falcon Level 5 sig but different cert"); WOLFSSL_MSG("Peer sent Falcon Level 5 sig");
ret = SIG_VERIFY_E; validSigAlgo = (ssl->peerFalconKey != NULL) &&
goto exit_dcv; ssl->peerFalconKeyPresent;
} }
#endif #endif
#ifndef NO_RSA #ifndef NO_RSA
if (args->sigAlgo == rsa_sa_algo) { if (args->sigAlgo == rsa_sa_algo) {
WOLFSSL_MSG("Peer sent PKCS#1.5 algo but not in certificate"); WOLFSSL_MSG("Peer sent PKCS#1.5 algo - not valid TLS 1.3");
ERROR_OUT(INVALID_PARAMETER, exit_dcv); ERROR_OUT(INVALID_PARAMETER, exit_dcv);
} }
if (args->sigAlgo == rsa_pss_sa_algo && if (args->sigAlgo == rsa_pss_sa_algo) {
(ssl->peerRsaKey == NULL || !ssl->peerRsaKeyPresent)) { WOLFSSL_MSG("Peer sent RSA sig");
WOLFSSL_MSG("Peer sent RSA sig but not RSA cert"); validSigAlgo = (ssl->peerRsaKey != NULL) &&
ret = SIG_VERIFY_E; ssl->peerRsaKeyPresent;
goto exit_dcv;
} }
#endif #endif
if (!validSigAlgo) {
WOLFSSL_MSG("Sig algo doesn't correspond to certficate");
ERROR_OUT(SIG_VERIFY_E, exit_dcv);
}
sig->buffer = (byte*)XMALLOC(args->sz, ssl->heap, sig->buffer = (byte*)XMALLOC(args->sz, ssl->heap,
DYNAMIC_TYPE_SIGNATURE); DYNAMIC_TYPE_SIGNATURE);