Skip to content

Commit 37704d1

Browse files
dkosticclaude
andcommitted
test(ssl): address PR review feedback for ML-DSA TLS 1.3 support
Functional fix: - Reject ML-DSA sigalgs arriving in TLS 1.2 SKE/CertVerify with illegal_parameter (draft-ietf-tls-mldsa §3.3) instead of failing later with WRONG_SIGNATURE_TYPE. Test coverage: - Add MLDSA-65 to kCertificateKeyTests and skip TLS<1.3 / non-MLDSA configurations across MultipleCertificateSlotTest cases. - New MLDSAHandshakeTest cases: ClientAuth (mTLS), FilteredFromTLS12, ParamNidFilterSelectsMatchingVariant, RejectedByPeerSigalgCheckInTLS12. Test infrastructure: - Pin sigalgs and curves in ssl_encoding_test's GetClientHelloLen so the baseline ClientHello stays predictable regardless of default-list changes; remove the version-skip workaround. Nits: - Make EVP_PKEY_PQDSA rejection in ssl_cipher_auth_mask_for_key explicit. - Clarify ML-DSA sigalg comments in extensions.cc and ssl_test.cc. Cleanup: - Drop unused ssl/test/runner/mldsa/ certificate and seed files; the Go runner has no ML-DSA wiring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 03699c7 commit 37704d1

10 files changed

Lines changed: 227 additions & 393 deletions

ssl/extensions.cc

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,10 @@ static const uint16_t kVerifySignatureAlgorithms[] = {
299299
SSL_SIGN_RSA_PSS_RSAE_SHA512,
300300
SSL_SIGN_RSA_PKCS1_SHA512,
301301

302-
// ML-DSA (TLS 1.3 only; ignored in earlier versions by
303-
// pkey_supports_algorithm).
302+
// ML-DSA. The codepoints are advertised in all TLS versions, but the
303+
// sigalgs are only selectable in TLS 1.3 (filtered by
304+
// |pkey_supports_algorithm|, and rejected at peer-sigalg-check time by
305+
// |tls12_check_peer_sigalg| to satisfy draft-ietf-tls-mldsa §3.3).
304306
SSL_SIGN_MLDSA44,
305307
SSL_SIGN_MLDSA65,
306308
SSL_SIGN_MLDSA87,
@@ -329,8 +331,8 @@ static const uint16_t kSignSignatureAlgorithms[] = {
329331
SSL_SIGN_RSA_PSS_RSAE_SHA512,
330332
SSL_SIGN_RSA_PKCS1_SHA512,
331333

332-
// ML-DSA (TLS 1.3 only; ignored in earlier versions by
333-
// pkey_supports_algorithm).
334+
// ML-DSA. Selectable for signing only in TLS 1.3; the version gate lives
335+
// in |pkey_supports_algorithm|.
334336
SSL_SIGN_MLDSA44,
335337
SSL_SIGN_MLDSA65,
336338
SSL_SIGN_MLDSA87,
@@ -356,8 +358,32 @@ bool tls12_add_verify_sigalgs(const SSL_HANDSHAKE *hs, CBB *out) {
356358
return true;
357359
}
358360

361+
// sigalg_valid_for_protocol_version returns whether |sigalg| is permitted at
362+
// the negotiated TLS protocol version. ML-DSA (draft-ietf-tls-mldsa §3.3) is
363+
// defined only for TLS 1.3; a peer that receives ML-DSA in a TLS 1.2
364+
// ServerKeyExchange or CertificateVerify MUST abort with illegal_parameter.
365+
static bool sigalg_valid_for_protocol_version(const SSL *ssl, uint16_t sigalg) {
366+
switch (sigalg) {
367+
case SSL_SIGN_MLDSA44:
368+
case SSL_SIGN_MLDSA65:
369+
case SSL_SIGN_MLDSA87:
370+
return ssl_protocol_version(ssl) >= TLS1_3_VERSION;
371+
default:
372+
return true;
373+
}
374+
}
375+
359376
bool tls12_check_peer_sigalg(const SSL_HANDSHAKE *hs, uint8_t *out_alert,
360377
uint16_t sigalg) {
378+
// Reject sigalgs that are not defined for the negotiated protocol version,
379+
// even if they appear in the local verify list (we still advertise them so
380+
// a higher version can negotiate them).
381+
if (!sigalg_valid_for_protocol_version(hs->ssl, sigalg)) {
382+
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
383+
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
384+
return false;
385+
}
386+
361387
for (uint16_t verify_sigalg : tls12_get_verify_sigalgs(hs)) {
362388
if (verify_sigalg == sigalg) {
363389
return true;

ssl/ssl_cipher.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,11 @@ uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key) {
13431343
case EVP_PKEY_ED25519:
13441344
// Ed25519 keys in TLS 1.2 repurpose the ECDSA ciphers.
13451345
return SSL_aECDSA;
1346+
case EVP_PKEY_PQDSA:
1347+
// ML-DSA is TLS 1.3 only and is not used for TLS <= 1.2 cipher-auth
1348+
// selection. TLS 1.3 paths gate on |SSL_aGENERIC| in
1349+
// |tls12_pkey_supports_cipher_auth| instead.
1350+
return 0;
13461351
default:
13471352
return 0;
13481353
}

ssl/ssl_encoding_test.cc

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,20 @@ static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
338338
return 0;
339339
}
340340

341-
// Set a one-element cipher list so the baseline ClientHello is unpadded.
341+
// Pin the sigalg list and the supported_groups list so this helper produces
342+
// a small, predictable baseline ClientHello regardless of the library's
343+
// current default sigalgs / curves. Without this, future changes to those
344+
// defaults silently push the baseline past the 0xff padding threshold and
345+
// skip this test for some |PaddingVersions| entries.
346+
static const uint16_t kBaselineSigalgs[] = {SSL_SIGN_ECDSA_SECP256R1_SHA256};
342347
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
343348
if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
344349
!SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
345-
!SSL_set1_curves_list(ssl.get(), "x25519:P-256:P-384") ||
350+
!SSL_set1_curves_list(ssl.get(), "x25519") ||
351+
!SSL_set_signing_algorithm_prefs(ssl.get(), kBaselineSigalgs,
352+
OPENSSL_ARRAY_SIZE(kBaselineSigalgs)) ||
353+
!SSL_set_verify_algorithm_prefs(ssl.get(), kBaselineSigalgs,
354+
OPENSSL_ARRAY_SIZE(kBaselineSigalgs)) ||
346355
!SSL_set_max_proto_version(ssl.get(), max_version)) {
347356
return 0;
348357
}
@@ -406,14 +415,6 @@ TEST(SSLTest, Padding) {
406415
GetClientHelloLen(versions.max_version, versions.session_version, 1);
407416
ASSERT_NE(base_len, 0u) << "Baseline length could not be sampled";
408417

409-
// If the baseline ClientHello is already in or past the padding range,
410-
// we cannot exercise the padding thresholds below. This happens when
411-
// the default extensions (e.g. sigalgs including ML-DSA) push the
412-
// unpadded ClientHello above 0xff bytes.
413-
if (base_len > kPaddingTests[0].input_len) {
414-
continue;
415-
}
416-
417418
for (const PaddingTest &test : kPaddingTests) {
418419
SCOPED_TRACE(test.input_len);
419420
ASSERT_LE(base_len, test.input_len) << "Baseline ClientHello too long";

ssl/ssl_test.cc

Lines changed: 181 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,6 +1689,8 @@ const CertificateKeyTestParams kCertificateKeyTests[] = {
16891689
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:", SSL_SIGN_ECDSA_SECP256R1_SHA256},
16901690
{GetED25519TestCertificate, GetED25519TestKey, SSL_PKEY_ED25519,
16911691
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:", SSL_SIGN_ED25519},
1692+
{GetMLDSA65TestCertificate, GetMLDSA65TestKey, SSL_PKEY_PQDSA, "",
1693+
SSL_SIGN_MLDSA65},
16921694
};
16931695

16941696
class MultipleCertificateSlotTest
@@ -1760,6 +1762,10 @@ TEST_P(MultipleCertificateSlotTest, CertificateSlotIndex) {
17601762
// ED25519 is not supported in versions prior to TLS1.2.
17611763
GTEST_SKIP();
17621764
}
1765+
if (version < TLS1_3_VERSION && slot_index == SSL_PKEY_PQDSA) {
1766+
// ML-DSA is only defined for TLS 1.3.
1767+
GTEST_SKIP();
1768+
}
17631769
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
17641770
bssl::UniquePtr<SSL_CTX> server_ctx(CreateContextWithCertificate(
17651771
TLS_method(), certificate_key_param().certificate(),
@@ -1768,7 +1774,7 @@ TEST_P(MultipleCertificateSlotTest, CertificateSlotIndex) {
17681774
StandardCertificateSlotIndexTests(
17691775
client_ctx.get(), server_ctx.get(),
17701776
{SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP256R1_SHA256,
1771-
SSL_SIGN_RSA_PSS_RSAE_SHA256},
1777+
SSL_SIGN_RSA_PSS_RSAE_SHA256, SSL_SIGN_MLDSA65},
17721778
slot_index, true);
17731779
}
17741780

@@ -1778,6 +1784,10 @@ TEST_P(MultipleCertificateSlotTest, SetChainAndKeyIndex) {
17781784
// ED25519 is not supported in versions prior to TLS1.2.
17791785
GTEST_SKIP();
17801786
}
1787+
if (version < TLS1_3_VERSION && slot_index == SSL_PKEY_PQDSA) {
1788+
// ML-DSA is only defined for TLS 1.3.
1789+
GTEST_SKIP();
1790+
}
17811791
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
17821792
bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
17831793

@@ -1797,7 +1807,7 @@ TEST_P(MultipleCertificateSlotTest, SetChainAndKeyIndex) {
17971807
StandardCertificateSlotIndexTests(
17981808
client_ctx.get(), server_ctx.get(),
17991809
{SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP256R1_SHA256,
1800-
SSL_SIGN_RSA_PSS_RSAE_SHA256},
1810+
SSL_SIGN_RSA_PSS_RSAE_SHA256, SSL_SIGN_MLDSA65},
18011811
slot_index, true);
18021812
}
18031813

@@ -1806,6 +1816,11 @@ TEST_P(MultipleCertificateSlotTest, AutomaticSelectionSigAlgs) {
18061816
// ED25519 is not supported in versions prior to TLS1.2.
18071817
GTEST_SKIP();
18081818
}
1819+
if (slot_index == SSL_PKEY_PQDSA) {
1820+
// The server in this test only configures RSA, ECDSA and ED25519
1821+
// credentials, so ML-DSA cannot be selected here.
1822+
GTEST_SKIP();
1823+
}
18091824

18101825
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
18111826
bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
@@ -1837,9 +1852,10 @@ TEST_P(MultipleCertificateSlotTest, AutomaticSelectionSigAlgs) {
18371852

18381853
TEST_P(MultipleCertificateSlotTest, AutomaticSelectionCipherAuth) {
18391854
if ((version < TLS1_2_VERSION && slot_index == SSL_PKEY_ED25519) ||
1840-
version >= TLS1_3_VERSION) {
1855+
version >= TLS1_3_VERSION || slot_index == SSL_PKEY_PQDSA) {
18411856
// ED25519 is not supported in versions prior to TLS1.2.
18421857
// TLS 1.3 not have cipher-based authentication configuration.
1858+
// ML-DSA is TLS 1.3 only and is not selectable via cipher-auth.
18431859
GTEST_SKIP();
18441860
}
18451861

@@ -1884,6 +1900,10 @@ TEST_P(MultipleCertificateSlotTest, MissingCertificate) {
18841900
// ED25519 is not supported in versions prior to TLS1.2.
18851901
GTEST_SKIP();
18861902
}
1903+
if (slot_index == SSL_PKEY_PQDSA) {
1904+
// The server in this test only configures RSA, ECDSA and ED25519 keys.
1905+
GTEST_SKIP();
1906+
}
18871907

18881908
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
18891909
bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
@@ -1911,6 +1931,10 @@ TEST_P(MultipleCertificateSlotTest, MissingPrivateKey) {
19111931
// ED25519 is not supported in versions prior to TLS1.2.
19121932
GTEST_SKIP();
19131933
}
1934+
if (slot_index == SSL_PKEY_PQDSA) {
1935+
// The server in this test only configures RSA, ECDSA and ED25519 certs.
1936+
GTEST_SKIP();
1937+
}
19141938

19151939
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
19161940
bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
@@ -1988,8 +2012,9 @@ TEST_P(MLDSAHandshakeTest, HandshakeSucceeds) {
19882012
}
19892013

19902014
TEST_P(MLDSAHandshakeTest, RejectedInTLS12) {
1991-
// ML-DSA is only defined for TLS 1.3. Forcing a TLS 1.2 handshake with an
1992-
// ML-DSA sigalg preference must not succeed.
2015+
// When both sides are pinned to TLS 1.2 and ML-DSA is the only sigalg in
2016+
// play, the handshake must not succeed: the server has nothing to sign
2017+
// with after the version filter excludes ML-DSA.
19932018
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
19942019
bssl::UniquePtr<SSL_CTX> server_ctx(
19952020
CreateContextWithCertificate(TLS_method(), GetParam().certificate(),
@@ -2039,6 +2064,157 @@ TEST(MLDSAHandshakeTest, CrossVariantMismatchFails) {
20392064
server_ctx.get()));
20402065
}
20412066

2067+
TEST_P(MLDSAHandshakeTest, ClientAuth) {
2068+
// Test ML-DSA for client certificate authentication (mutual TLS).
2069+
bssl::UniquePtr<SSL_CTX> client_ctx(CreateContextWithCertificate(
2070+
TLS_method(), GetParam().certificate(), GetParam().key()));
2071+
bssl::UniquePtr<SSL_CTX> server_ctx(CreateContextWithCertificate(
2072+
TLS_method(), GetParam().certificate(), GetParam().key()));
2073+
ASSERT_TRUE(client_ctx);
2074+
ASSERT_TRUE(server_ctx);
2075+
ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
2076+
ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2077+
ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
2078+
ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
2079+
2080+
const uint16_t sigalgs[] = {GetParam().sigalg};
2081+
ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx.get(), sigalgs,
2082+
OPENSSL_ARRAY_SIZE(sigalgs)));
2083+
ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(client_ctx.get(), sigalgs,
2084+
OPENSSL_ARRAY_SIZE(sigalgs)));
2085+
ASSERT_TRUE(SSL_CTX_set_verify_algorithm_prefs(client_ctx.get(), sigalgs,
2086+
OPENSSL_ARRAY_SIZE(sigalgs)));
2087+
ASSERT_TRUE(SSL_CTX_set_verify_algorithm_prefs(server_ctx.get(), sigalgs,
2088+
OPENSSL_ARRAY_SIZE(sigalgs)));
2089+
2090+
// Server requests client certificate.
2091+
SSL_CTX_set_custom_verify(
2092+
server_ctx.get(), SSL_VERIFY_PEER,
2093+
[](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
2094+
return ssl_verify_ok;
2095+
});
2096+
2097+
bssl::UniquePtr<SSL> client, server;
2098+
ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
2099+
server_ctx.get()));
2100+
EXPECT_EQ(SSL_get_peer_signature_algorithm(server.get()), GetParam().sigalg);
2101+
}
2102+
2103+
TEST_P(MLDSAHandshakeTest, FilteredFromTLS12) {
2104+
// ML-DSA is only defined for TLS 1.3 (draft-ietf-tls-mldsa §3.3). Confirm
2105+
// that even when the local sigalg prefs include ML-DSA, the negotiation
2106+
// does not pick it once the version is forced to TLS 1.2 -- the peer must
2107+
// fall back to a different sigalg, not fail.
2108+
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2109+
bssl::UniquePtr<SSL_CTX> server_ctx(CreateContextWithCertificate(
2110+
TLS_method(), GetParam().certificate(), GetParam().key()));
2111+
ASSERT_TRUE(client_ctx);
2112+
ASSERT_TRUE(server_ctx);
2113+
2114+
// Give the server an RSA cert/key as a fallback usable in TLS 1.2.
2115+
ASSERT_TRUE(
2116+
SSL_CTX_use_certificate(server_ctx.get(), GetTestCertificate().get()));
2117+
ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), GetTestKey().get()));
2118+
2119+
// Force TLS 1.2 from the client side; server allows 1.2..1.3.
2120+
ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_2_VERSION));
2121+
2122+
const uint16_t sigalgs[] = {GetParam().sigalg, SSL_SIGN_RSA_PSS_RSAE_SHA256};
2123+
ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx.get(), sigalgs,
2124+
OPENSSL_ARRAY_SIZE(sigalgs)));
2125+
ASSERT_TRUE(SSL_CTX_set_verify_algorithm_prefs(client_ctx.get(), sigalgs,
2126+
OPENSSL_ARRAY_SIZE(sigalgs)));
2127+
2128+
bssl::UniquePtr<SSL> client, server;
2129+
ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
2130+
server_ctx.get()));
2131+
EXPECT_EQ(SSL_version(client.get()), TLS1_2_VERSION);
2132+
EXPECT_NE(SSL_get_peer_signature_algorithm(client.get()), GetParam().sigalg);
2133+
}
2134+
2135+
TEST(MLDSAHandshakeTest, RejectedByPeerSigalgCheckInTLS12) {
2136+
// Even if a peer's local verify list contains ML-DSA (we advertise the
2137+
// codepoints in TLS 1.2 ClientHellos so a higher-version negotiation can
2138+
// pick them up), |tls12_check_peer_sigalg| must reject ML-DSA arriving in
2139+
// a TLS 1.2 ServerKeyExchange / CertificateVerify with illegal_parameter,
2140+
// per draft-ietf-tls-mldsa §3.3. Without this check, the handshake would
2141+
// only fail later with a non-spec WRONG_SIGNATURE_TYPE.
2142+
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2143+
bssl::UniquePtr<SSL_CTX> server_ctx(CreateContextWithCertificate(
2144+
TLS_method(), GetTestCertificate(), GetTestKey()));
2145+
ASSERT_TRUE(client_ctx);
2146+
ASSERT_TRUE(server_ctx);
2147+
ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_2_VERSION));
2148+
ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
2149+
2150+
bssl::UniquePtr<SSL> client, server;
2151+
ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
2152+
server_ctx.get(), ClientConfig(),
2153+
/*shed_handshake_config=*/false));
2154+
ASSERT_EQ(SSL_version(client.get()), TLS1_2_VERSION);
2155+
2156+
// Synthesize a fresh handshake state and seed its verify list with ML-DSA.
2157+
// |tls12_check_peer_sigalg| must still reject because the negotiated
2158+
// version is TLS 1.2.
2159+
bssl::UniquePtr<SSL_HANDSHAKE> hs = ssl_handshake_new(client.get());
2160+
ASSERT_TRUE(hs);
2161+
static const uint16_t kSeedSigalgs[] = {
2162+
SSL_SIGN_MLDSA44, SSL_SIGN_MLDSA65, SSL_SIGN_MLDSA87,
2163+
SSL_SIGN_RSA_PSS_RSAE_SHA256};
2164+
ASSERT_TRUE(hs->config->verify_sigalgs.CopyFrom(kSeedSigalgs));
2165+
2166+
for (uint16_t sigalg :
2167+
{SSL_SIGN_MLDSA44, SSL_SIGN_MLDSA65, SSL_SIGN_MLDSA87}) {
2168+
uint8_t alert = 0;
2169+
EXPECT_FALSE(tls12_check_peer_sigalg(hs.get(), &alert, sigalg));
2170+
EXPECT_EQ(alert, SSL_AD_ILLEGAL_PARAMETER);
2171+
ERR_clear_error();
2172+
}
2173+
2174+
// Sanity check: a valid TLS 1.2 sigalg from the same list still passes.
2175+
uint8_t alert = 0;
2176+
EXPECT_TRUE(
2177+
tls12_check_peer_sigalg(hs.get(), &alert, SSL_SIGN_RSA_PSS_RSAE_SHA256));
2178+
}
2179+
2180+
TEST(MLDSAHandshakeTest, ParamNidFilterSelectsMatchingVariant) {
2181+
// Server has an MLDSA-44 cert/key but advertises [MLDSA-65, MLDSA-87,
2182+
// MLDSA-44] in its signing prefs (so MLDSA-44 is *not* the first
2183+
// preference). |pkey_supports_algorithm| should reject MLDSA-65 and
2184+
// MLDSA-87 against the MLDSA-44 key (param_nid mismatch) and fall
2185+
// through to MLDSA-44, which both peers offer.
2186+
//
2187+
// This positively exercises the
2188+
// EVP_PKEY_pqdsa_get_type(pkey) != alg->param_nid
2189+
// filter that this PR adds.
2190+
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2191+
bssl::UniquePtr<SSL_CTX> server_ctx(CreateContextWithCertificate(
2192+
TLS_method(), GetMLDSA44TestCertificate(), GetMLDSA44TestKey()));
2193+
ASSERT_TRUE(client_ctx);
2194+
ASSERT_TRUE(server_ctx);
2195+
ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
2196+
ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2197+
ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
2198+
ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
2199+
2200+
const uint16_t server_sigalgs[] = {SSL_SIGN_MLDSA65, SSL_SIGN_MLDSA87,
2201+
SSL_SIGN_MLDSA44};
2202+
ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(
2203+
server_ctx.get(), server_sigalgs, OPENSSL_ARRAY_SIZE(server_sigalgs)));
2204+
2205+
const uint16_t client_sigalgs[] = {SSL_SIGN_MLDSA44, SSL_SIGN_MLDSA65,
2206+
SSL_SIGN_MLDSA87};
2207+
ASSERT_TRUE(SSL_CTX_set_verify_algorithm_prefs(
2208+
client_ctx.get(), client_sigalgs, OPENSSL_ARRAY_SIZE(client_sigalgs)));
2209+
2210+
bssl::UniquePtr<SSL> client, server;
2211+
ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
2212+
server_ctx.get()));
2213+
// Despite MLDSA-65 being the server's first signing preference, the param
2214+
// filter must have skipped it because the cert is MLDSA-44.
2215+
EXPECT_EQ(SSL_get_peer_signature_algorithm(client.get()), SSL_SIGN_MLDSA44);
2216+
}
2217+
20422218

20432219
struct MultiTransferReadWriteTestParams {
20442220
const char suite[50];

ssl/test/runner/mldsa/ML-DSA-44-seed.priv

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)