diff --git a/src/tls13.c b/src/tls13.c index 101b31541ad..0bc741ad166 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -7791,7 +7791,6 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, int sendSz; word32 i; word32 reqSz; - word16 hashSigAlgoSz = 0; SignatureAlgorithms* sa; WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_SEND); @@ -7802,14 +7801,11 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, if (ssl->options.side != WOLFSSL_SERVER_END) return SIDE_ERROR; - /* Get the length of the hashSigAlgo buffer */ - InitSuitesHashSigAlgo(NULL, SIG_ALL, 1, 1, ssl->buffers.keySz, - &hashSigAlgoSz); - sa = TLSX_SignatureAlgorithms_New(ssl, hashSigAlgoSz, ssl->heap); + /* Use ssl->suites->hashSigAlgo so wolfSSL_set1_sigalgs_list() is honored. + * hashSigAlgoSz=0 makes GetSize/Write fall back to WOLFSSL_SUITES(ssl). */ + sa = TLSX_SignatureAlgorithms_New(ssl, 0, ssl->heap); if (sa == NULL) return MEMORY_ERROR; - InitSuitesHashSigAlgo(sa->hashSigAlgo, SIG_ALL, 1, 1, ssl->buffers.keySz, - &hashSigAlgoSz); ret = TLSX_Push(&ssl->extensions, TLSX_SIGNATURE_ALGORITHMS, sa, ssl->heap); if (ret != 0) { TLSX_SignatureAlgorithms_FreeAll(sa, ssl->heap); diff --git a/tests/api/test_tls13.c b/tests/api/test_tls13.c index 9c77126f460..a6f411544bc 100644 --- a/tests/api/test_tls13.c +++ b/tests/api/test_tls13.c @@ -3100,3 +3100,89 @@ int test_tls13_plaintext_alert(void) return EXPECT_RESULT(); } +/* Test that wolfSSL_set1_sigalgs_list() is honored in TLS 1.3 + */ +int test_tls13_cert_req_sigalgs(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_TLS13) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \ + !defined(NO_CERTS) && !defined(NO_RSA) && defined(WC_RSA_PSS) && \ + defined(HAVE_ECC) && !defined(NO_WOLFSSL_CLIENT) && \ + !defined(NO_WOLFSSL_SERVER) && defined(OPENSSL_EXTRA) && \ + !defined(NO_FILESYSTEM) + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + struct test_memio_ctx test_ctx; + + 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); + + /* Server: require client cert and load ECC client cert for verification */ + if (EXPECT_SUCCESS()) { + wolfSSL_set_verify(ssl_s, + WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); + ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_s, + cliEccCertFile, 0), WOLFSSL_SUCCESS); + } + + /* Server: restrict CertificateRequest to RSA-PSS+SHA256 only */ + if (EXPECT_SUCCESS()) { + ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl_s, "RSA-PSS+SHA256"), + WOLFSSL_SUCCESS); + } + + /* Client: load ECC cert/key */ + if (EXPECT_SUCCESS()) { + ExpectIntEQ(wolfSSL_use_certificate_file(ssl_c, cliEccCertFile, + CERT_FILETYPE), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_use_PrivateKey_file(ssl_c, cliEccKeyFile, + CERT_FILETYPE), WOLFSSL_SUCCESS); + } + + /* Handshake must fail: ECC client cannot match RSA-PSS+SHA256 */ + ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + + wolfSSL_free(ssl_c); ssl_c = NULL; + wolfSSL_free(ssl_s); ssl_s = NULL; + wolfSSL_CTX_free(ctx_c); ctx_c = NULL; + wolfSSL_CTX_free(ctx_s); ctx_s = 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); + + /* Server: require client cert and load RSA client cert for verification */ + if (EXPECT_SUCCESS()) { + wolfSSL_set_verify(ssl_s, + WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); + ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_s, + cliCertFile, 0), WOLFSSL_SUCCESS); + } + + /* Server: restrict CertificateRequest to RSA-PSS+SHA256 only */ + if (EXPECT_SUCCESS()) { + ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl_s, "RSA-PSS+SHA256"), + WOLFSSL_SUCCESS); + } + + /* Client: load RSA cert/key */ + if (EXPECT_SUCCESS()) { + ExpectIntEQ(wolfSSL_use_certificate_file(ssl_c, cliCertFile, + CERT_FILETYPE), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_use_PrivateKey_file(ssl_c, cliKeyFile, + CERT_FILETYPE), WOLFSSL_SUCCESS); + } + + /* Handshake must succeed: RSA client satisfies RSA-PSS+SHA256 */ + ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + + wolfSSL_free(ssl_c); ssl_c = NULL; + wolfSSL_free(ssl_s); ssl_s = NULL; + wolfSSL_CTX_free(ctx_c); ctx_c = NULL; + wolfSSL_CTX_free(ctx_s); ctx_s = NULL; +#endif + + return EXPECT_RESULT(); +} + diff --git a/tests/api/test_tls13.h b/tests/api/test_tls13.h index 8b5f48ef4d5..67b23d57fe7 100644 --- a/tests/api/test_tls13.h +++ b/tests/api/test_tls13.h @@ -38,6 +38,7 @@ int test_tls13_duplicate_extension(void); int test_key_share_mismatch(void); int test_tls13_middlebox_compat_empty_session_id(void); int test_tls13_plaintext_alert(void); +int test_tls13_cert_req_sigalgs(void); #define TEST_TLS13_DECLS \ TEST_DECL_GROUP("tls13", test_tls13_apis), \ @@ -53,6 +54,7 @@ int test_tls13_plaintext_alert(void); TEST_DECL_GROUP("tls13", test_tls13_duplicate_extension), \ TEST_DECL_GROUP("tls13", test_key_share_mismatch), \ TEST_DECL_GROUP("tls13", test_tls13_middlebox_compat_empty_session_id), \ - TEST_DECL_GROUP("tls13", test_tls13_plaintext_alert) + TEST_DECL_GROUP("tls13", test_tls13_plaintext_alert), \ + TEST_DECL_GROUP("tls13", test_tls13_cert_req_sigalgs) #endif /* WOLFCRYPT_TEST_TLS13_H */