From 107cc82a06c19946da1520c1e5f4d6f0bcb6efb3 Mon Sep 17 00:00:00 2001 From: jordan Date: Thu, 27 Jun 2024 10:45:02 -0500 Subject: [PATCH 1/3] Fixes ZD 18204: check hashsigalgo matches ssl suites. --- src/internal.c | 50 ++++++++++++++++++++++++++++++++++++++++++++-- wolfssl/internal.h | 2 ++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/internal.c b/src/internal.c index c798b8c02e..ba491bce5f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -27368,7 +27368,45 @@ static byte MinHashAlgo(WOLFSSL* ssl) return sha_mac; } +/* Check if a given peer hashSigAlgo is supported in our ssl->suites or + * ssl->ctx->suites. + * + * Returns 1 on match. + * Returns 0 otherwise. + * */ +static int SupportedHashSigAlgo(WOLFSSL* ssl, const byte * hashSigAlgo) +{ + const Suites * suites = NULL; + word32 i = 0; + + if (ssl == NULL || hashSigAlgo == NULL) { + return 0; + } + + suites = WOLFSSL_SUITES(ssl); + + if (suites == NULL || suites->hashSigAlgoSz == 0) { + return 0; + } + + for (i = 0; (i+1) < suites->hashSigAlgoSz; i += HELLO_EXT_SIGALGO_SZ) { + if (XMEMCMP(&suites->hashSigAlgo[i], hashSigAlgo, + HELLO_EXT_SIGALGO_SZ) == 0) { + /* Match found. */ + return 1; + } + } + + return 0; +} + int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) +{ + return PickHashSigAlgo_ex(ssl, hashSigAlgo, hashSigAlgoSz, 0); +} + +int PickHashSigAlgo_ex(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz, + int matchSuites) { word32 i; int ret = WC_NO_ERR_TRACE(MATCH_SUITE_ERROR); @@ -27409,6 +27447,14 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) if (!MatchSigAlgo(ssl, sigAlgo)) continue; + if (matchSuites) { + /* Keep looking if peer algorithm isn't supported in our ssl->suites + * or ssl->ctx->suites. */ + if (!SupportedHashSigAlgo(ssl, &hashSigAlgo[i])) { + continue; + } + } + #ifdef HAVE_ED25519 if (ssl->pkCurveOID == ECC_ED25519_OID) { /* Matched Ed25519 - set chosen and finished. */ @@ -35913,8 +35959,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ret = SetCipherSpecs(ssl); if (ret != 0) return ret; - ret = PickHashSigAlgo(ssl, peerSuites->hashSigAlgo, - peerSuites->hashSigAlgoSz); + ret = PickHashSigAlgo_ex(ssl, peerSuites->hashSigAlgo, + peerSuites->hashSigAlgoSz, 1); if (ret != 0) return ret; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 7bac1f6cf8..fa7e32352d 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2181,6 +2181,8 @@ WOLFSSL_LOCAL int CompleteServerHello(WOLFSSL *ssl); WOLFSSL_LOCAL int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv); WOLFSSL_LOCAL int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz); +WOLFSSL_LOCAL int PickHashSigAlgo_ex(WOLFSSL* ssl, const byte* hashSigAlgo, + word32 hashSigAlgoSz, int matchSuites); #if defined(WOLF_PRIVATE_KEY_ID) && !defined(NO_CHECK_PRIVATE_KEY) WOLFSSL_LOCAL int CreateDevPrivateKey(void** pkey, byte* data, word32 length, int hsType, int label, int id, From 7dfef18cf491ab6d371fc20c471d7cdeee6d1a04 Mon Sep 17 00:00:00 2001 From: jordan Date: Fri, 28 Jun 2024 18:32:13 -0500 Subject: [PATCH 2/3] Refactor unneeded PickHashSigAlgo_ex function. --- src/internal.c | 17 ++++++----------- src/tls13.c | 2 +- wolfssl/internal.h | 4 +--- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/internal.c b/src/internal.c index ba491bce5f..0423e86e85 100644 --- a/src/internal.c +++ b/src/internal.c @@ -27400,13 +27400,8 @@ static int SupportedHashSigAlgo(WOLFSSL* ssl, const byte * hashSigAlgo) return 0; } -int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) -{ - return PickHashSigAlgo_ex(ssl, hashSigAlgo, hashSigAlgoSz, 0); -} - -int PickHashSigAlgo_ex(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz, - int matchSuites) +int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz, + int matchSuites) { word32 i; int ret = WC_NO_ERR_TRACE(MATCH_SUITE_ERROR); @@ -30074,7 +30069,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, if ((len > size) || ((*inOutIdx - begin) + len > size)) return BUFFER_ERROR; - if (PickHashSigAlgo(ssl, input + *inOutIdx, len) != 0 && + if (PickHashSigAlgo(ssl, input + *inOutIdx, len, 0) != 0 && ssl->buffers.certificate && ssl->buffers.certificate->buffer) { #ifdef HAVE_PK_CALLBACKS @@ -35959,8 +35954,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ret = SetCipherSpecs(ssl); if (ret != 0) return ret; - ret = PickHashSigAlgo_ex(ssl, peerSuites->hashSigAlgo, - peerSuites->hashSigAlgoSz, 1); + ret = PickHashSigAlgo(ssl, peerSuites->hashSigAlgo, + peerSuites->hashSigAlgoSz, 1); if (ret != 0) return ret; @@ -36323,7 +36318,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ret = SetCipherSpecs(ssl); if (ret == 0) { ret = PickHashSigAlgo(ssl, clSuites->hashSigAlgo, - clSuites->hashSigAlgoSz); + clSuites->hashSigAlgoSz, 0); } } else if (ret == 0) { diff --git a/src/tls13.c b/src/tls13.c index 585b02958a..ac09be3c64 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -5740,7 +5740,7 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, #endif ) { if (PickHashSigAlgo(ssl, peerSuites.hashSigAlgo, - peerSuites.hashSigAlgoSz) != 0) { + peerSuites.hashSigAlgoSz, 0) != 0) { WOLFSSL_ERROR_VERBOSE(INVALID_PARAMETER); return INVALID_PARAMETER; } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index fa7e32352d..f017abaae7 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2180,9 +2180,7 @@ WOLFSSL_LOCAL int DoServerHello(WOLFSSL* ssl, const byte* input, word32* inOutI WOLFSSL_LOCAL int CompleteServerHello(WOLFSSL *ssl); WOLFSSL_LOCAL int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv); WOLFSSL_LOCAL int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, - word32 hashSigAlgoSz); -WOLFSSL_LOCAL int PickHashSigAlgo_ex(WOLFSSL* ssl, const byte* hashSigAlgo, - word32 hashSigAlgoSz, int matchSuites); + word32 hashSigAlgoSz, int matchSuites); #if defined(WOLF_PRIVATE_KEY_ID) && !defined(NO_CHECK_PRIVATE_KEY) WOLFSSL_LOCAL int CreateDevPrivateKey(void** pkey, byte* data, word32 length, int hsType, int label, int id, From f7f3ba9c768300e871ce6a4ef86e94bfc69c888c Mon Sep 17 00:00:00 2001 From: jordan Date: Wed, 3 Jul 2024 11:59:18 -0500 Subject: [PATCH 3/3] check hashsigalgo matches ssl suites on client side. --- src/internal.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/internal.c b/src/internal.c index 0423e86e85..982502be2c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -31104,6 +31104,15 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, ERROR_OUT(BUFFER_ERROR, exit_dske); } + /* Check if hashSigAlgo in Server Key Exchange is supported + * in our ssl->suites or ssl->ctx->suites. */ + if (!SupportedHashSigAlgo(ssl, &input[args->idx])) { + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, handshake_failure); + #endif + ERROR_OUT(MATCH_SUITE_ERROR, exit_dske); + } + DecodeSigAlg(&input[args->idx], &ssl->options.peerHashAlgo, &sigAlgo); #ifndef NO_RSA