From 353604194ce284cdc08ff698f6758088281836c1 Mon Sep 17 00:00:00 2001 From: Michal Tarnacki Date: Tue, 16 Jun 2026 13:05:31 +0200 Subject: [PATCH] fix(crypto/rustls): pin RA-TLS CertificateVerify to ECDSA P-384/SHA-384 The RA-TLS Verifier accepted the full default list of signature schemes in supported_verify_schemes() and did not check the scheme used in the CertificateVerify message, leaving the handshake transcript signature algorithm unpinned. Restrict both the client- and server-side Verifier to ECDSA_NISTP384_SHA384: return only that scheme from supported_verify_schemes(), and reject any other scheme in verify_tls13_signature() with PeerIncompatible before verifying the transcript. This keeps the signature algorithm consistent with the cipher suite and key-exchange group already pinned in crypto_provider(). Signed-off-by: Michal Tarnacki Co-authored-by: GitHub Copilot --- src/crypto/src/rustls_impl/tls.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/crypto/src/rustls_impl/tls.rs b/src/crypto/src/rustls_impl/tls.rs index 862bb666a..6c13579a6 100644 --- a/src/crypto/src/rustls_impl/tls.rs +++ b/src/crypto/src/rustls_impl/tls.rs @@ -293,6 +293,15 @@ impl ServerCertVerifier for Verifier { cert: &CertificateDer<'_>, dss: &rustls::DigitallySignedStruct, ) -> core::result::Result { + // Pin the CertificateVerify signature scheme to ECDSA P-384/SHA-384, + // consistent with the cipher suite and key-exchange group pinned in + // `crypto_provider()`. Reject any other scheme so the handshake + // transcript can only be bound with the expected algorithm. + if dss.scheme != rustls::SignatureScheme::ECDSA_NISTP384_SHA384 { + return Err(rustls::Error::PeerIncompatible( + rustls::PeerIncompatible::NoSignatureSchemesInCommon, + )); + } verify_tls13_signature( message, cert, @@ -316,9 +325,7 @@ impl ServerCertVerifier for Verifier { } fn supported_verify_schemes(&self) -> Vec { - default_provider() - .signature_verification_algorithms - .supported_schemes() + vec![rustls::SignatureScheme::ECDSA_NISTP384_SHA384] } } @@ -347,6 +354,15 @@ impl ClientCertVerifier for Verifier { cert: &CertificateDer<'_>, dss: &rustls::DigitallySignedStruct, ) -> core::result::Result { + // Pin the CertificateVerify signature scheme to ECDSA P-384/SHA-384, + // consistent with the cipher suite and key-exchange group pinned in + // `crypto_provider()`. Reject any other scheme so the handshake + // transcript can only be bound with the expected algorithm. + if dss.scheme != rustls::SignatureScheme::ECDSA_NISTP384_SHA384 { + return Err(rustls::Error::PeerIncompatible( + rustls::PeerIncompatible::NoSignatureSchemesInCommon, + )); + } verify_tls13_signature( message, cert, @@ -370,9 +386,7 @@ impl ClientCertVerifier for Verifier { } fn supported_verify_schemes(&self) -> Vec { - default_provider() - .signature_verification_algorithms - .supported_schemes() + vec![rustls::SignatureScheme::ECDSA_NISTP384_SHA384] } fn root_hint_subjects(&self) -> &[rustls::DistinguishedName] {