TLSv1.3 test: CertificateVerify signature algorithm test

F-2917
Added test for signature algorithms sent not matching available.
This commit is contained in:
Sean Parkinson
2026-06-30 15:51:51 +10:00
parent 18c9684c9d
commit 95e798e897
2 changed files with 88 additions and 0 deletions
+86
View File
@@ -5851,6 +5851,92 @@ int test_tls13_corrupted_finished(void)
}
/* Test that DoTls13CertificateVerify rejects a CertificateVerify whose
* signature algorithm is not one the receiver advertised.
*
* This drives the validSigAlgo == 0 path in src/tls13.c: the loop that scans
* the receiver's hashSigAlgo list for the algorithm carried in the
* CertificateVerify message. When no entry matches, validSigAlgo stays 0 and
* the message is rejected with INVALID_PARAMETER.
*
* The client sends its ClientHello (advertising its real signature
* algorithms), the server picks one of them to sign its CertificateVerify, and
* then - before the client processes the server flight - the client's accepted
* signature algorithm list is overwritten with a bogus entry. The server's
* (legitimately chosen) algorithm is therefore absent from the client's list
* at verification time, so the lookup fails.
*/
int test_tls13_certificate_verify_bad_sigalgo(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
!defined(NO_CERTS)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
int group = WOLFSSL_ECC_SECP256R1;
Suites* suites = NULL;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
/* Constrain both peers to a single, mutually-supported key share group so
* the server never sends a HelloRetryRequest. That keeps the message
* stepping below deterministic: one ClientHello, then the full server
* flight (which contains the CertificateVerify we want to corrupt). */
ExpectIntEQ(wolfSSL_set_groups(ssl_c, &group, 1), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, group), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set_groups(ssl_s, &group, 1), WOLFSSL_SUCCESS);
/* Step 1: Client sends ClientHello, advertising its real signature
* algorithms. */
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
/* Step 2: Server processes the ClientHello and emits SH + EE + Cert +
* CertVerify + Finished, signing the CertVerify with an algorithm taken
* from the list the client just advertised. */
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
/* The ClientHello has now been sent, so changing the client's accepted
* signature algorithms no longer affects what it advertised. Replace the
* list with a single bogus pair (not a valid SignatureScheme) that the
* server cannot have used. When the client verifies the server's
* CertificateVerify, the lookup loop finds no match -> validSigAlgo == 0. */
if (EXPECT_SUCCESS()) {
suites = (Suites*)WOLFSSL_SUITES(ssl_c);
ExpectNotNull(suites);
}
if (suites != NULL) {
suites->hashSigAlgo[0] = 0xFE;
suites->hashSigAlgo[1] = 0xFE;
suites->hashSigAlgoSz = 2;
}
/* Step 3: Client processes the server flight. DoTls13CertificateVerify
* must reject the CertificateVerify with INVALID_PARAMETER. */
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WC_NO_ERR_TRACE(INVALID_PARAMETER));
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
/* Test the TLS 1.3 peerAuthGood fail-safe checks on both sides.
* The client branch queues a real server flight before forcing
* FIRST_REPLY_SECOND on a live handshake object, and the server branch clears
+2
View File
@@ -58,6 +58,7 @@ int test_tls13_0rtt_stateless_replay(void);
int test_tls13_remove_session_return(void);
int test_tls13_0rtt_ext_cache_eviction(void);
int test_tls13_corrupted_finished(void);
int test_tls13_certificate_verify_bad_sigalgo(void);
int test_tls13_peerauth_failsafe(void);
int test_tls13_hrr_bad_cookie(void);
int test_tls13_zero_inner_content_type(void);
@@ -120,6 +121,7 @@ int test_tls13_AEAD_limit_KU_aes128_ccm_8_sha256(void);
TEST_DECL_GROUP("tls13", test_tls13_0rtt_ext_cache_eviction), \
TEST_DECL_GROUP("tls13", test_tls13_unknown_ext_rejected), \
TEST_DECL_GROUP("tls13", test_tls13_corrupted_finished), \
TEST_DECL_GROUP("tls13", test_tls13_certificate_verify_bad_sigalgo), \
TEST_DECL_GROUP("tls13", test_tls13_peerauth_failsafe), \
TEST_DECL_GROUP("tls13", test_tls13_hrr_bad_cookie), \
TEST_DECL_GROUP("tls13", test_tls13_zero_inner_content_type), \