A menagerie of changes to bssl-tls

This is an accumulation of changes I made while reading over the code.

Change-Id: I44883a476f77a4d7f3d07e8fec1ee232d86282d9
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/88787
Commit-Queue: Xiangfei Ding <xfding@google.com>
Reviewed-by: Xiangfei Ding <xfding@google.com>
diff --git a/rust/bssl-tls/Cargo.toml b/rust/bssl-tls/Cargo.toml
index c86145f..f319111 100644
--- a/rust/bssl-tls/Cargo.toml
+++ b/rust/bssl-tls/Cargo.toml
@@ -32,5 +32,5 @@
 std = ["bssl-crypto/std"]
 # `mlalgs` enables ML-KEM and ML-DSA support. This requires Rust 1.82.
 mlalgs = ["bssl-crypto/mlalgs"]
-# `rustls` enables the adapters to key traits for inter-op with `rustls` crate
+# `rustls-adapters` enables the adapters to key traits for inter-op with `rustls` crate
 rustls-adapters = ["rustls/tls12", "rustls/std"]
diff --git a/rust/bssl-tls/src/lib.rs b/rust/bssl-tls/src/lib.rs
index 99111e4..1c4b666 100644
--- a/rust/bssl-tls/src/lib.rs
+++ b/rust/bssl-tls/src/lib.rs
@@ -23,7 +23,11 @@
 #![allow(private_bounds)]
 #![cfg_attr(not(any(feature = "std", test)), no_std)]
 
-//! Rust BoringSSL bindings
+//! BoringSSL-backed [`rustls`] adapters.
+//!
+//! This crate provides a [`rustls::crypto::CryptoProvider`] backed by
+//! BoringSSL, for use with the [`rustls`] TLS stack. See
+//! [`rustls_provider`] for details and examples.
 
 extern crate alloc;
 extern crate core;
diff --git a/rust/bssl-tls/src/rustls_provider.rs b/rust/bssl-tls/src/rustls_provider.rs
index 389a948..622339c 100644
--- a/rust/bssl-tls/src/rustls_provider.rs
+++ b/rust/bssl-tls/src/rustls_provider.rs
@@ -12,27 +12,46 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//! `rustls` Adapters
+//! BoringSSL-backed [`rustls::crypto::CryptoProvider`].
 //!
-//! This module provides a provider builder `CryptoProviderBuilder`,
-//! which constructs a [`rustls::crypto::CryptoProvider`] for interop with `rustls` TLS stack.
+//! This module provides [`CryptoProviderBuilder`], which constructs a
+//! [`rustls::crypto::CryptoProvider`] backed by BoringSSL. The resulting
+//! provider can be used with [`rustls`] to establish TLS 1.2 and TLS 1.3
+//! connections.
 //!
-//! # Supported signature schemes
+//! ```
+//! use std::sync::Arc;
+//! use bssl_tls::rustls_provider::CryptoProviderBuilder;
+//! use rustls::client::ClientConfig;
 //!
-//! ## [RFC 8446] IANA assignments for TLS supported signature scheme
+//! let provider = CryptoProviderBuilder::full();
+//! let _config = ClientConfig::builder_with_provider(Arc::new(provider))
+//!     .with_safe_default_protocol_versions()
+//!     .unwrap()
+//!     .with_root_certificates(rustls::RootCertStore::empty())
+//!     .with_no_client_auth();
+//! ```
 //!
-//! - `TLS_AES_128_GCM_SHA256`
-//! - `TLS_AES_256_GCM_SHA384`
-//! - `TLS_CHACHA20_POLY1305_SHA256`
+//! For finer-grained control, individual cipher suites and key exchange
+//! groups can be selected:
 //!
-//! # Supported key exchange groups
+//! ```
+//! use std::sync::Arc;
+//! use bssl_tls::rustls_provider::{CryptoProviderBuilder, cipher_suites, key_exchange};
+//! use rustls::{SupportedCipherSuite, client::ClientConfig};
 //!
-//! - [`secp256r1`] backed by [`key_exchange::ECDH_P256`]
-//! - [`secp384r1`] backed by [`key_exchange::ECDH_P384`]
-//! - [`X25519`] backed by [`key_exchange::X25519`]
-//!
-//! [RFC 8446]: https://datatracker.ietf.org/doc/html/rfc8446
-//! [`X25519`]: https://datatracker.ietf.org/doc/html/rfc7748
+//! let provider = CryptoProviderBuilder::new()
+//!     .with_key_exchange_group(key_exchange::X25519)
+//!     .with_cipher_suite(SupportedCipherSuite::Tls13(
+//!         cipher_suites::TLS13_AES_256_GCM_SHA384,
+//!     ))
+//!     .build();
+//! let _config = ClientConfig::builder_with_provider(Arc::new(provider))
+//!     .with_safe_default_protocol_versions()
+//!     .unwrap()
+//!     .with_root_certificates(rustls::RootCertStore::empty())
+//!     .with_no_client_auth();
+//! ```
 
 use alloc::{boxed::Box, sync::Arc, vec, vec::Vec};
 use bssl_sys::RAND_bytes;
@@ -275,9 +294,9 @@
     /// groups.
     pub fn with_default_key_exchange_groups(mut self) -> Self {
         self.kx_groups.extend_from_slice(&[
+            key_exchange::X25519,
             key_exchange::ECDH_P256,
             key_exchange::ECDH_P384,
-            key_exchange::X25519,
         ]);
         self
     }
diff --git a/rust/bssl-tls/src/rustls_provider/cipher_suites.rs b/rust/bssl-tls/src/rustls_provider/cipher_suites.rs
index f8417cb..7e8e63a 100644
--- a/rust/bssl-tls/src/rustls_provider/cipher_suites.rs
+++ b/rust/bssl-tls/src/rustls_provider/cipher_suites.rs
@@ -54,7 +54,7 @@
 tls12_suites! {
     TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 {
         Sha256,
-        1 << 24,
+        u64::MAX,
         ECDHE,
         TLS12_ECDSA_SCHEMES,
         TLS12_CHACHA20_POLY1305_AEAD
diff --git a/rust/bssl-tls/src/rustls_provider/pki.rs b/rust/bssl-tls/src/rustls_provider/pki.rs
index bb16e2d..b28ba30 100644
--- a/rust/bssl-tls/src/rustls_provider/pki.rs
+++ b/rust/bssl-tls/src/rustls_provider/pki.rs
@@ -281,7 +281,7 @@
         message: &[u8],
         signature: &[u8],
     ) -> bool {
-        // Safety: we would only allow SHA-256 hashing onto P-256 and SHA-386 hashing onto P-384
+        // Safety: we would only allow SHA-256 hashing onto P-256 and SHA-384 hashing onto P-384
         public_key.verify(message, signature).is_ok()
     }
 }
diff --git a/rust/bssl-tls/src/rustls_provider/tests.rs b/rust/bssl-tls/src/rustls_provider/tests.rs
index 88d523f..631e810 100644
--- a/rust/bssl-tls/src/rustls_provider/tests.rs
+++ b/rust/bssl-tls/src/rustls_provider/tests.rs
@@ -43,6 +43,18 @@
 const ECDSA_P256_SVC_KEY: &'static [u8] =
     include_bytes!("./tests/BoringSSLServerTest-ECDSA-P256.key");
 
+const ECDSA_P384_SVC_CERT: &'static [u8] =
+    include_bytes!("./tests/BoringSSLServerTest-ECDSA-P384.crt");
+
+const ECDSA_P384_SVC_KEY: &'static [u8] =
+    include_bytes!("./tests/BoringSSLServerTest-ECDSA-P384.key");
+
+const ED25519_SVC_CERT: &'static [u8] =
+    include_bytes!("./tests/BoringSSLServerTest-Ed25519.crt");
+
+const ED25519_SVC_KEY: &'static [u8] =
+    include_bytes!("./tests/BoringSSLServerTest-Ed25519.key");
+
 const RSA_PSS_SVC_CERT: &'static [u8] =
     include_bytes!("./tests/BoringSSLServerTest-RSA-PSS-SHA256.crt");
 
@@ -440,3 +452,141 @@
         },
     );
 }
+
+#[test]
+fn tls12_ecdhe_rsa_with_chacha20_poly1305_sha256() {
+    let providers = [CryptoProviderBuilder::full, ring::default_provider];
+    let test_provider = || {
+        CryptoProviderBuilder::new()
+            .with_default_key_exchange_groups()
+            .with_cipher_suite(SupportedCipherSuite::Tls12(
+                cipher_suites::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+            ))
+            .build()
+    };
+    test_half_connection(
+        &providers,
+        test_provider,
+        |client_provider, server_provider| {
+            test_cipher_suite(
+                CA_CERT,
+                RSA_SVC_CERT,
+                RSA_SVC_KEY,
+                &[&TLS12],
+                server_provider,
+                client_provider,
+            )
+        },
+    );
+}
+
+#[test]
+fn tls13_rsa_server_cert() {
+    test_cipher_suite(
+        CA_CERT,
+        RSA_SVC_CERT,
+        RSA_SVC_KEY,
+        &[&TLS13],
+        CryptoProviderBuilder::full(),
+        CryptoProviderBuilder::full(),
+    );
+}
+
+#[test]
+fn tls13_rsa_pss_server_cert() {
+    test_cipher_suite(
+        CA_CERT,
+        RSA_PSS_SVC_CERT,
+        RSA_SVC_KEY,
+        &[&TLS13],
+        CryptoProviderBuilder::full(),
+        CryptoProviderBuilder::full(),
+    );
+}
+
+#[test]
+fn tls13_ecdsa_p384_server_cert() {
+    let providers = [CryptoProviderBuilder::full, ring::default_provider];
+    let test_provider = || {
+        CryptoProviderBuilder::new()
+            .with_default_key_exchange_groups()
+            .with_full_cipher_suites()
+            .build()
+    };
+    test_half_connection(
+        &providers,
+        test_provider,
+        |client_provider, server_provider| {
+            test_cipher_suite(
+                CA_CERT,
+                ECDSA_P384_SVC_CERT,
+                ECDSA_P384_SVC_KEY,
+                &[&TLS13],
+                server_provider,
+                client_provider,
+            )
+        },
+    );
+}
+
+#[test]
+fn tls12_ecdsa_p384_server_cert() {
+    let providers = [CryptoProviderBuilder::full, ring::default_provider];
+    let test_provider = || {
+        CryptoProviderBuilder::new()
+            .with_default_key_exchange_groups()
+            .with_full_cipher_suites()
+            .build()
+    };
+    test_half_connection(
+        &providers,
+        test_provider,
+        |client_provider, server_provider| {
+            test_cipher_suite(
+                CA_CERT,
+                ECDSA_P384_SVC_CERT,
+                ECDSA_P384_SVC_KEY,
+                &[&TLS12],
+                server_provider,
+                client_provider,
+            )
+        },
+    );
+}
+
+#[test]
+fn tls13_ed25519_server_cert() {
+    // Ed25519 is not supported by ring, so test BoringSSL on both sides.
+    test_cipher_suite(
+        CA_CERT,
+        ED25519_SVC_CERT,
+        ED25519_SVC_KEY,
+        &[&TLS13],
+        CryptoProviderBuilder::full(),
+        CryptoProviderBuilder::full(),
+    );
+}
+
+#[test]
+fn full_provider_both_sides_tls13() {
+    test_cipher_suite(
+        CA_CERT,
+        ECDSA_P256_SVC_CERT,
+        ECDSA_P256_SVC_KEY,
+        &[&TLS13],
+        CryptoProviderBuilder::full(),
+        CryptoProviderBuilder::full(),
+    );
+}
+
+#[test]
+fn full_provider_both_sides_tls12() {
+    test_cipher_suite(
+        CA_CERT,
+        ECDSA_P256_SVC_CERT,
+        ECDSA_P256_SVC_KEY,
+        &[&TLS12],
+        CryptoProviderBuilder::full(),
+        CryptoProviderBuilder::full(),
+    );
+}
diff --git a/rust/bssl-tls/src/rustls_provider/tests/BoringSSLCATest.crt b/rust/bssl-tls/src/rustls_provider/tests/BoringSSLCATest.crt
index e5d28ce..a6d3912 100644
--- a/rust/bssl-tls/src/rustls_provider/tests/BoringSSLCATest.crt
+++ b/rust/bssl-tls/src/rustls_provider/tests/BoringSSLCATest.crt
@@ -1,3 +1,99 @@
+This is generated from
+    openssl req -new -x509 -key BoringSSLCATest.key -out BoringSSLCATest.crt \
+      -config caconfig -days 30
+
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            1e:51:13:9d:9c:81:90:38:25:32:72:51:f3:33:1b:70:d0:9b:6a:5c
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=DE, ST=Freistaat Bayern, L=Muenchen, O=Google Germany GmbH, OU=ISE Crypto, CN=BoringSSL Authors, emailAddress=boringssl@google.com
+        Validity
+            Not Before: Jan 22 09:53:41 2026 GMT
+            Not After : Feb 21 09:53:41 2026 GMT
+        Subject: C=DE, ST=Freistaat Bayern, L=Muenchen, O=Google Germany GmbH, OU=ISE Crypto, CN=BoringSSL Authors, emailAddress=boringssl@google.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (4096 bit)
+                Modulus:
+                    00:d9:6c:65:59:51:32:fa:a5:6e:ab:93:a3:f7:45:
+                    c9:75:97:54:0b:6e:5f:fb:6f:2f:d7:ed:5b:bc:57:
+                    1b:a8:8e:aa:be:03:5c:38:78:4c:92:2c:5f:1c:b2:
+                    39:a4:a4:53:9d:b9:d7:dd:7a:00:af:4d:4d:93:6a:
+                    5b:07:3c:10:bf:bc:02:3e:85:b9:a9:96:3f:52:ba:
+                    c5:06:15:ac:ac:66:54:26:55:77:dc:86:11:8f:a6:
+                    9c:7b:49:f1:16:f7:3a:62:26:d4:fe:a9:69:6c:22:
+                    79:c2:92:62:2d:6c:1e:63:5e:07:41:8a:39:27:41:
+                    34:c0:99:57:22:cc:30:8c:95:e7:5c:3d:f2:26:e9:
+                    4d:29:9e:c9:69:37:3d:47:f5:5e:69:3c:43:4e:b6:
+                    d3:52:e1:97:77:0e:1a:69:2e:ea:8a:fe:50:68:19:
+                    f2:38:eb:05:58:56:8a:39:22:83:3c:ae:e3:87:48:
+                    ad:fc:30:56:43:5d:6c:75:e4:e2:fd:cd:1f:d3:a7:
+                    81:52:1d:7f:dd:39:57:03:1f:d5:ed:be:e4:23:94:
+                    23:6d:70:b6:d7:84:ec:80:7d:ec:f4:ca:44:e2:a7:
+                    61:eb:16:5f:dd:a2:4e:6d:99:8f:30:9c:b7:75:74:
+                    da:83:41:42:ae:56:44:21:7b:71:cf:7d:a8:b5:32:
+                    8f:91:b3:30:a1:f4:ea:10:cf:3e:0d:37:3c:fe:a3:
+                    fa:f2:26:68:a5:16:40:be:b9:e7:ae:e0:e1:eb:6c:
+                    65:c2:08:bd:d7:32:7e:a7:5c:09:f3:d5:40:de:c8:
+                    9d:c4:fd:05:e0:6a:12:93:60:35:b6:a4:7a:6b:a7:
+                    35:a0:86:b2:80:f6:51:6c:49:a1:b4:26:1f:a2:7b:
+                    20:ff:14:fe:36:f1:1a:3e:2b:3c:cf:3e:9f:07:24:
+                    d3:fa:ad:b6:88:a6:3f:98:a1:19:01:eb:e4:7b:e9:
+                    ec:b3:58:56:39:bb:f3:70:58:d6:87:4e:83:1a:df:
+                    48:af:96:fb:70:3e:73:93:df:84:ab:6d:54:bb:0b:
+                    6d:dd:65:d2:9a:5f:a2:ed:b3:b4:7b:54:ee:49:fd:
+                    fd:44:54:3a:2d:d6:b0:c9:62:89:e2:ee:71:e1:60:
+                    73:3a:dd:1c:05:fb:f5:97:9d:8f:82:9b:ac:42:32:
+                    77:42:d9:60:77:59:2c:0a:4e:cd:b6:cd:c5:e1:5d:
+                    d2:00:31:c8:d2:a7:57:46:69:1a:6f:b6:ab:f3:92:
+                    e2:42:38:2f:c7:5f:b3:03:d0:04:70:05:7f:5f:6d:
+                    4c:18:69:90:95:a8:9c:02:44:ac:96:88:f5:fc:4d:
+                    81:4a:de:e3:5e:1e:57:c1:2d:ba:8e:f3:2b:39:ae:
+                    ab:8d:05
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier:
+                EA:1B:59:1E:5D:E3:33:29:41:7F:D7:58:88:63:D4:2A:28:06:78:10
+            X509v3 Authority Key Identifier:
+                EA:1B:59:1E:5D:E3:33:29:41:7F:D7:58:88:63:D4:2A:28:06:78:10
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Digital Signature, Certificate Sign, CRL Sign
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        d8:72:63:ba:c9:8d:26:18:12:d0:ab:51:e3:6a:ca:29:83:af:
+        d0:b1:42:ae:36:d6:23:92:d3:c7:e3:f4:1a:d9:16:14:da:3f:
+        97:9a:ff:36:5f:83:ed:f8:d8:f2:8f:7a:2a:73:7a:8d:7a:5b:
+        91:ce:b8:17:e8:42:29:f4:13:1e:e5:2e:3f:bf:0e:fb:de:20:
+        69:c3:46:9e:67:66:26:dc:52:8e:c8:59:d8:f5:1d:ad:d4:04:
+        ac:e0:26:71:2e:a6:86:b2:97:37:44:cc:b0:fb:e6:72:20:83:
+        12:7a:98:07:f3:a6:27:ba:a2:18:ff:40:ad:ca:33:be:a5:23:
+        d6:2f:0e:d1:75:d3:a1:6f:8b:bb:a9:7e:e0:fd:18:e1:44:35:
+        84:56:55:72:86:72:35:bc:e5:50:77:69:e8:f2:b6:cc:3e:b6:
+        bf:e4:5b:ac:17:c4:84:ff:e8:d5:be:f4:7a:00:de:59:8e:2a:
+        65:da:71:58:4e:d0:26:80:f0:4b:85:30:cd:c3:8c:02:2f:b4:
+        dc:82:c7:f7:f0:02:4b:67:5d:d8:a1:d7:4d:64:93:6b:a4:ec:
+        5c:d9:52:bd:28:b8:6a:02:a6:bc:29:74:f5:bd:4d:a2:36:a6:
+        57:95:42:2f:ee:1f:5d:63:6a:d2:0a:a2:f7:04:4a:6c:ca:0a:
+        17:3a:9e:9a:fe:72:05:58:59:84:77:61:a0:73:8d:2b:5a:c7:
+        d5:98:8f:a7:de:bd:5f:25:cf:f4:01:7c:74:0e:04:49:1e:0a:
+        2b:6f:2f:7f:e7:e3:c7:ce:77:43:73:10:3d:f0:a4:fc:0a:3b:
+        21:1d:e0:0e:3e:4d:3a:e0:23:0a:59:ea:5b:15:07:d1:2c:e4:
+        22:4d:da:01:5d:d2:94:89:0b:7a:3c:9f:35:bf:2c:36:b5:4d:
+        8e:7c:88:60:0d:74:5d:b4:f0:cc:25:c7:c7:93:a4:fa:26:fa:
+        6e:13:f6:03:58:6f:97:7e:cd:e3:c4:cd:aa:ae:64:5e:2a:cb:
+        70:4b:df:13:3e:2b:07:3b:d8:e8:a8:91:eb:fa:a8:09:60:5c:
+        b3:da:d3:10:6e:23:8e:d7:95:34:01:16:3c:08:fc:f1:a3:41:
+        1b:3a:45:a2:32:95:58:05:f5:b3:12:00:60:6e:49:a5:a3:ca:
+        24:5d:eb:a8:e8:73:55:64:1c:13:f5:ba:e2:ba:6c:0c:15:66:
+        55:40:6c:55:e6:4e:60:27:91:45:23:7c:e6:8e:ed:f5:ce:e4:
+        09:9e:32:45:d8:63:21:e8:3a:9f:91:a5:52:c2:27:de:ff:35:
+        31:3f:39:cc:d8:c6:0e:8c:be:58:2b:f4:77:06:ac:d7:fb:76:
+        58:15:30:28:df:9e:94:e2
+
 -----BEGIN CERTIFICATE-----
 MIIGUTCCBDmgAwIBAgIUHlETnZyBkDglMnJR8zMbcNCbalwwDQYJKoZIhvcNAQEL
 BQAwga8xCzAJBgNVBAYTAkRFMRkwFwYDVQQIDBBGcmVpc3RhYXQgQmF5ZXJuMREw
diff --git a/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-ECDSA-P256.crt b/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-ECDSA-P256.crt
index b0282a5..b72a0e3 100644
--- a/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-ECDSA-P256.crt
+++ b/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-ECDSA-P256.crt
@@ -2,6 +2,70 @@
     openssl x509 -req -in server.csr -CA BoringSSLCATest.crt \
       -CAkey BoringSSLCATest.key -CAcreateserial \
       -out BoringSSLServerTest-ECDSA-P256.crt -extfile svcconfig -days 730500
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            50:2d:32:51:7b:b9:51:f0:df:6e:4e:c3:05:1f:2c:4b:af:cd:52:74
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=DE, ST=Freistaat Bayern, L=Muenchen, O=Google Germany GmbH, OU=ISE Crypto, CN=BoringSSL Authors, emailAddress=boringssl@google.com
+        Validity
+            Not Before: Jan 23 13:40:52 2026 GMT
+            Not After : Feb  7 13:40:52 4026 GMT
+        Subject: CN=www.google.com
+        Subject Public Key Info:
+            Public Key Algorithm: id-ecPublicKey
+                Public-Key: (256 bit)
+                pub:
+                    04:eb:d1:ff:95:75:4a:0b:08:fd:00:ef:91:98:d4:
+                    6f:1e:f7:3e:38:03:ab:72:3b:a2:f3:04:71:9f:eb:
+                    a5:8d:18:16:4f:72:cb:39:1c:29:98:0e:71:72:23:
+                    3e:3c:69:ad:e8:84:8f:70:e3:80:e7:b6:4d:f2:23:
+                    b0:ec:5d:9f:7f
+                ASN1 OID: prime256v1
+                NIST CURVE: P-256
+        X509v3 extensions:
+            X509v3 Authority Key Identifier:
+                EA:1B:59:1E:5D:E3:33:29:41:7F:D7:58:88:63:D4:2A:28:06:78:10
+            X509v3 Basic Constraints:
+                CA:FALSE
+            X509v3 Key Usage:
+                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
+            X509v3 Subject Alternative Name:
+                DNS:www.google.com, DNS:localhost
+            X509v3 Subject Key Identifier:
+                F1:D8:5F:E8:36:6E:04:A3:E0:54:5D:8F:2C:44:EC:9E:B9:67:21:8C
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        ab:66:a7:3c:5d:8c:b8:70:09:38:ff:7a:6c:61:80:84:31:4c:
+        06:8a:b6:51:10:f9:19:8e:86:94:6c:e2:28:9b:5b:5b:b1:9b:
+        ae:63:6b:03:ab:63:5f:32:ec:ff:6b:82:68:e9:f1:bb:43:02:
+        de:c5:af:02:67:84:a2:78:68:68:03:46:05:4e:a6:35:09:23:
+        9b:34:b2:c6:2c:17:5a:d7:71:69:8f:df:41:84:17:3a:41:a6:
+        34:fa:2e:9b:2a:27:ac:49:6a:8b:ae:dd:77:2e:ec:87:6a:d1:
+        b1:69:1f:b3:85:96:91:68:44:2d:e8:fc:5c:68:29:4e:c6:f2:
+        f8:fb:6f:c9:04:d1:b6:3b:da:4e:71:0e:a6:98:24:c9:22:cd:
+        db:46:fd:e9:7d:2c:98:4e:84:35:47:ca:aa:ed:64:e5:fe:96:
+        42:62:1f:0b:74:cf:87:c7:56:94:06:e0:a5:a9:3b:74:6e:40:
+        29:81:b1:19:00:32:2b:ee:d1:5a:80:5f:d5:ec:7b:22:4c:a7:
+        b8:f2:c8:0e:af:57:c4:c1:c1:16:2a:bc:b5:cc:74:7e:7f:46:
+        19:72:72:0d:cc:54:80:06:2e:ef:98:92:39:4e:f5:7f:d8:19:
+        81:8d:65:91:88:4b:62:f8:ee:49:11:28:17:ac:a1:6d:5c:bd:
+        0c:f7:f3:5b:2d:f7:c6:a2:28:9e:a0:0e:57:6c:12:0d:51:69:
+        00:d1:12:e5:8f:68:8c:a1:76:78:d0:0d:e4:c5:4e:69:b0:be:
+        30:21:e8:bd:c4:a1:0f:7f:e5:ee:47:e8:0b:62:87:cc:98:d7:
+        b5:a1:20:a9:05:12:84:46:d1:b8:9f:e8:a0:fb:c1:4d:7d:df:
+        a6:3e:90:44:23:8b:d7:62:f2:90:89:4c:64:b9:56:d1:af:06:
+        55:05:77:3f:98:ac:e6:31:78:e1:38:02:c3:e9:93:22:cf:00:
+        ec:1e:f0:6f:b2:b6:ee:76:34:5f:33:db:83:bc:ed:28:cf:eb:
+        98:fa:25:32:e8:75:83:b3:9e:90:a0:63:7b:a9:e9:55:8d:66:
+        67:a9:70:54:a5:92:a4:ec:0a:a7:79:4c:7b:62:84:c0:01:27:
+        cb:e6:5d:97:da:00:bc:52:c5:ef:6f:2a:56:4d:2e:34:3f:e1:
+        dc:b0:04:46:76:f6:cc:a1:1e:a1:b7:68:31:82:6e:ac:12:cc:
+        58:da:ef:9f:2b:ef:0a:22:be:32:e0:40:9c:ca:30:65:2f:f0:
+        9c:2d:13:e3:c7:94:24:5f:9e:eb:47:5d:07:70:35:48:5d:47:
+        3f:56:d8:fd:50:1f:55:53:04:c1:65:c9:29:46:83:d0:77:86:
+        70:8a:bc:04:8a:19:d7:ad
 
 -----BEGIN CERTIFICATE-----
 MIIEDzCCAfegAwIBAgIUUC0yUXu5UfDfbk7DBR8sS6/NUnQwDQYJKoZIhvcNAQEL
diff --git a/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-RSA-PSS-SHA256.crt b/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-RSA-PSS-SHA256.crt
index ad53a9c..a368580 100644
--- a/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-RSA-PSS-SHA256.crt
+++ b/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-RSA-PSS-SHA256.crt
@@ -4,6 +4,107 @@
       -out BoringSSLServerTest-RSA-PSS-SHA256.crt -extfile svcconfig \
       -days 730500 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 \
       -sigopt rsa_mgf1_md:sha256
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            2a:7d:8e:d1:d8:49:df:fa:b6:31:9a:df:0b:04:9f:dc:cb:be:82:03
+        Signature Algorithm: rsassaPss
+        Hash Algorithm: sha256
+        Mask Algorithm: mgf1 with sha256
+         Salt Length: 0x20
+        Trailer Field: 0x01 (default)
+        Issuer: C=DE, ST=Freistaat Bayern, L=Muenchen, O=Google Germany GmbH, OU=ISE Crypto, CN=BoringSSL Authors, emailAddress=boringssl@google.com
+        Validity
+            Not Before: Feb  2 15:39:55 2026 GMT
+            Not After : Feb 17 15:39:55 4026 GMT
+        Subject: CN=www.google.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (4096 bit)
+                Modulus:
+                    00:f7:a2:3f:8e:9e:a5:9a:f7:eb:c5:cf:d5:31:3b:
+                    c0:ca:02:83:3a:81:90:9a:8d:47:d4:3c:c1:f2:61:
+                    3d:87:11:25:7f:bc:b9:a4:dc:7f:3e:7d:30:1e:32:
+                    8d:ec:d5:e0:b5:b2:47:b3:77:3d:2d:2e:61:dd:ad:
+                    03:62:2d:e0:19:c8:fb:1f:43:ef:ed:cd:a2:96:8c:
+                    61:27:fc:7d:9e:42:90:07:79:c8:87:f5:3a:ff:f9:
+                    0e:25:b3:b2:67:45:3e:6b:a6:bf:0c:8d:ac:78:00:
+                    8a:5d:6c:dd:97:8c:f6:1f:2f:73:c8:ed:af:39:73:
+                    81:a5:38:fc:ed:a6:0c:1c:46:45:49:98:19:cd:4c:
+                    3b:63:ac:67:9a:d8:95:36:46:b6:47:ec:cd:bd:84:
+                    ca:8b:34:6e:5e:67:f0:1f:4f:c7:7e:57:97:3f:e6:
+                    b9:7e:b1:f6:66:41:26:2b:3e:9f:1a:88:48:58:46:
+                    7e:6d:6a:74:f0:4a:6f:f4:51:2d:cb:22:45:33:c1:
+                    77:4d:c7:8a:0d:ad:0d:dc:6a:8e:5c:87:3a:a9:a7:
+                    dc:df:45:0b:d8:36:5a:c9:3f:5c:2a:dc:9d:81:1d:
+                    30:bd:0d:03:5d:cb:8d:f8:5d:31:81:76:97:c1:1f:
+                    14:0c:54:3d:30:41:c4:7b:96:6f:8c:2a:2f:2a:fb:
+                    fc:96:59:5f:7a:f6:48:4a:eb:8f:a6:c6:59:e1:e1:
+                    05:27:cc:7d:c0:60:77:dd:8f:a2:7c:86:c1:d7:3e:
+                    05:18:ad:54:c4:68:8f:10:d6:c7:f2:63:d8:17:bd:
+                    8f:c3:29:08:9b:15:af:19:eb:a2:16:23:67:b8:b8:
+                    b1:ee:ee:32:d3:8f:31:4b:19:c2:4e:f9:3e:9a:bf:
+                    77:ec:b9:e9:d9:c7:9f:82:21:b8:2d:4d:ed:9c:30:
+                    b1:b2:86:c1:38:22:3a:fe:08:21:fe:2e:94:d0:b9:
+                    5a:ef:8f:b0:15:74:b2:df:37:28:59:fd:48:92:eb:
+                    a2:6a:17:4f:90:0f:78:b9:d3:59:22:f6:10:b9:35:
+                    a5:ea:21:c9:0b:55:3e:56:00:f4:6a:37:17:d9:94:
+                    5a:d7:ec:76:6d:5d:22:9b:d0:bf:f1:03:b0:66:91:
+                    8d:ae:ae:ee:6c:00:e8:03:ad:1a:c5:18:80:15:b0:
+                    cb:af:2d:3e:b4:25:fc:01:db:70:09:fe:44:d0:2d:
+                    f3:be:25:55:82:c9:a0:36:f6:be:0d:d7:39:a7:51:
+                    9f:a7:ee:67:8a:a8:34:e6:f5:6d:82:54:bf:bc:07:
+                    a6:26:da:0f:d6:58:f8:93:53:f9:f3:23:73:b5:69:
+                    22:cf:ef:af:0a:77:07:53:a2:59:59:96:36:8a:11:
+                    d0:ac:2d
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Authority Key Identifier:
+                EA:1B:59:1E:5D:E3:33:29:41:7F:D7:58:88:63:D4:2A:28:06:78:10
+            X509v3 Basic Constraints:
+                CA:FALSE
+            X509v3 Key Usage:
+                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
+            X509v3 Subject Alternative Name:
+                DNS:www.google.com, DNS:localhost
+            X509v3 Subject Key Identifier:
+                3B:BF:82:CA:BD:B0:B7:0D:60:E4:DD:A5:3B:FC:AF:6A:F6:8A:A2:28
+    Signature Algorithm: rsassaPss
+    Signature Value:
+        Hash Algorithm: sha256
+        Mask Algorithm: mgf1 with sha256
+         Salt Length: 0x20
+        Trailer Field: 0x01 (default)
+        96:84:18:0d:a9:40:54:39:26:80:58:7c:27:9a:28:06:b2:f2:
+        59:f4:2c:3b:ab:a8:6e:77:33:27:6f:23:db:01:f3:11:22:ef:
+        6a:ce:a4:fe:77:d1:18:fc:4c:85:13:e7:d9:ef:00:fc:b5:5d:
+        b7:a7:e3:74:3d:4a:fb:a4:66:7e:d6:91:94:10:1a:3d:d5:f0:
+        5a:68:25:71:23:b9:31:8d:ba:ef:2a:e6:dd:3e:85:2d:6b:f6:
+        a6:7f:86:d9:a2:b5:8f:83:a6:56:b9:61:11:a5:e7:0c:19:20:
+        9b:8c:e9:cc:b9:6b:69:fa:db:93:a8:bd:60:e2:0a:59:1d:58:
+        51:3d:bd:44:df:f5:85:7c:19:04:47:8b:ca:18:09:3d:2a:ff:
+        c4:fe:48:09:5b:b2:d8:66:55:60:95:3b:34:72:71:cb:af:dd:
+        17:1a:bd:68:17:5f:50:38:39:4e:c3:95:61:35:63:27:f2:d0:
+        da:20:7d:e2:d6:59:ec:c2:46:26:25:bc:a5:dd:7e:64:9a:44:
+        33:31:84:75:05:3a:e2:a2:9a:8e:b2:cc:5e:95:1c:8d:2d:b4:
+        9e:e0:f4:29:10:9e:16:0d:be:e7:1f:a9:ee:61:c0:48:4c:19:
+        fb:b0:d5:83:ef:eb:ee:50:a9:5c:94:41:fc:40:23:ff:63:38:
+        18:3a:ab:50:f5:7b:b7:eb:8d:2d:f4:62:bb:20:33:57:22:97:
+        7f:6d:32:9b:bf:7a:01:73:de:a4:04:96:47:19:0f:6d:99:a9:
+        51:b0:63:2e:ff:56:36:b9:2f:d4:6c:a7:9c:f5:bc:2f:23:d1:
+        4a:85:a8:63:ea:6a:62:3e:ef:10:14:f7:b6:97:42:a4:7c:6c:
+        ba:b1:53:ea:fc:4e:eb:db:20:60:41:32:26:dd:19:e0:a3:f4:
+        06:f8:19:c3:48:9a:7e:7f:c7:c2:f4:88:55:5b:bc:41:69:be:
+        ab:7f:36:fe:ea:df:32:25:ab:cc:fe:9b:37:a6:92:6d:f0:9f:
+        4c:45:3f:e7:1a:7f:06:86:4b:95:bc:78:03:4f:42:fc:4b:ac:
+        f6:3a:15:89:ed:40:25:34:b5:85:9d:16:1d:4c:1f:97:30:f1:
+        68:58:09:fb:c2:83:76:b3:4a:cf:d1:fe:dc:33:a5:83:f8:0c:
+        43:7b:f6:9c:36:17:ff:f7:a2:33:1e:db:83:9a:22:e3:76:2e:
+        ca:f2:e6:cc:2e:59:20:be:6c:06:57:8a:43:9b:17:e1:46:10:
+        c6:f7:bc:64:c7:18:ed:7a:88:9f:59:51:da:3d:2f:1c:a2:0a:
+        92:1f:9a:e4:27:58:68:7f:71:d4:c2:b4:03:bb:e1:8b:92:2a:
+        3d:75:1d:eb:54:3e:13:e7
 
 -----BEGIN CERTIFICATE-----
 MIIGQjCCA/agAwIBAgIUKn2O0dhJ3/q2MZrfCwSf3Mu+ggMwQQYJKoZIhvcNAQEK
diff --git a/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-RSA.crt b/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-RSA.crt
index ca24a8f..4b376c1 100644
--- a/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-RSA.crt
+++ b/rust/bssl-tls/src/rustls_provider/tests/BoringSSLServerTest-RSA.crt
@@ -2,6 +2,99 @@
     openssl x509 -req -in server.csr -CA BoringSSLCATest.crt \
       -CAkey BoringSSLCATest.key -CAcreateserial \
       -out BoringSSLServerTest-RSA.crt -extfile svcconfig -days 730500
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            50:2d:32:51:7b:b9:51:f0:df:6e:4e:c3:05:1f:2c:4b:af:cd:52:73
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=DE, ST=Freistaat Bayern, L=Muenchen, O=Google Germany GmbH, OU=ISE Crypto, CN=BoringSSL Authors, emailAddress=boringssl@google.com
+        Validity
+            Not Before: Jan 22 10:40:09 2026 GMT
+            Not After : Feb  6 10:40:09 4026 GMT
+        Subject: CN=www.google.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (4096 bit)
+                Modulus:
+                    00:f7:a2:3f:8e:9e:a5:9a:f7:eb:c5:cf:d5:31:3b:
+                    c0:ca:02:83:3a:81:90:9a:8d:47:d4:3c:c1:f2:61:
+                    3d:87:11:25:7f:bc:b9:a4:dc:7f:3e:7d:30:1e:32:
+                    8d:ec:d5:e0:b5:b2:47:b3:77:3d:2d:2e:61:dd:ad:
+                    03:62:2d:e0:19:c8:fb:1f:43:ef:ed:cd:a2:96:8c:
+                    61:27:fc:7d:9e:42:90:07:79:c8:87:f5:3a:ff:f9:
+                    0e:25:b3:b2:67:45:3e:6b:a6:bf:0c:8d:ac:78:00:
+                    8a:5d:6c:dd:97:8c:f6:1f:2f:73:c8:ed:af:39:73:
+                    81:a5:38:fc:ed:a6:0c:1c:46:45:49:98:19:cd:4c:
+                    3b:63:ac:67:9a:d8:95:36:46:b6:47:ec:cd:bd:84:
+                    ca:8b:34:6e:5e:67:f0:1f:4f:c7:7e:57:97:3f:e6:
+                    b9:7e:b1:f6:66:41:26:2b:3e:9f:1a:88:48:58:46:
+                    7e:6d:6a:74:f0:4a:6f:f4:51:2d:cb:22:45:33:c1:
+                    77:4d:c7:8a:0d:ad:0d:dc:6a:8e:5c:87:3a:a9:a7:
+                    dc:df:45:0b:d8:36:5a:c9:3f:5c:2a:dc:9d:81:1d:
+                    30:bd:0d:03:5d:cb:8d:f8:5d:31:81:76:97:c1:1f:
+                    14:0c:54:3d:30:41:c4:7b:96:6f:8c:2a:2f:2a:fb:
+                    fc:96:59:5f:7a:f6:48:4a:eb:8f:a6:c6:59:e1:e1:
+                    05:27:cc:7d:c0:60:77:dd:8f:a2:7c:86:c1:d7:3e:
+                    05:18:ad:54:c4:68:8f:10:d6:c7:f2:63:d8:17:bd:
+                    8f:c3:29:08:9b:15:af:19:eb:a2:16:23:67:b8:b8:
+                    b1:ee:ee:32:d3:8f:31:4b:19:c2:4e:f9:3e:9a:bf:
+                    77:ec:b9:e9:d9:c7:9f:82:21:b8:2d:4d:ed:9c:30:
+                    b1:b2:86:c1:38:22:3a:fe:08:21:fe:2e:94:d0:b9:
+                    5a:ef:8f:b0:15:74:b2:df:37:28:59:fd:48:92:eb:
+                    a2:6a:17:4f:90:0f:78:b9:d3:59:22:f6:10:b9:35:
+                    a5:ea:21:c9:0b:55:3e:56:00:f4:6a:37:17:d9:94:
+                    5a:d7:ec:76:6d:5d:22:9b:d0:bf:f1:03:b0:66:91:
+                    8d:ae:ae:ee:6c:00:e8:03:ad:1a:c5:18:80:15:b0:
+                    cb:af:2d:3e:b4:25:fc:01:db:70:09:fe:44:d0:2d:
+                    f3:be:25:55:82:c9:a0:36:f6:be:0d:d7:39:a7:51:
+                    9f:a7:ee:67:8a:a8:34:e6:f5:6d:82:54:bf:bc:07:
+                    a6:26:da:0f:d6:58:f8:93:53:f9:f3:23:73:b5:69:
+                    22:cf:ef:af:0a:77:07:53:a2:59:59:96:36:8a:11:
+                    d0:ac:2d
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Authority Key Identifier:
+                EA:1B:59:1E:5D:E3:33:29:41:7F:D7:58:88:63:D4:2A:28:06:78:10
+            X509v3 Basic Constraints:
+                CA:FALSE
+            X509v3 Key Usage:
+                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
+            X509v3 Subject Alternative Name:
+                DNS:www.google.com, DNS:localhost
+            X509v3 Subject Key Identifier:
+                3B:BF:82:CA:BD:B0:B7:0D:60:E4:DD:A5:3B:FC:AF:6A:F6:8A:A2:28
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        c7:85:d7:41:f9:b1:67:7a:72:39:46:01:05:25:5f:9e:45:a1:
+        06:3f:19:dd:31:30:ed:2f:9e:37:e6:fc:b7:55:e9:38:8d:77:
+        5f:aa:ba:26:8f:4e:bf:d6:ff:d2:0e:46:41:d6:3c:5f:65:83:
+        67:b6:46:a6:31:58:70:61:13:5e:6d:6c:2f:49:68:e8:eb:94:
+        78:f5:a1:5a:0f:c6:d0:29:c2:86:bc:13:fc:9a:08:d5:d4:58:
+        76:e6:85:2b:76:1b:d2:24:56:3d:0f:d0:f6:14:23:ed:48:3e:
+        56:57:f9:c2:45:d0:ba:b7:01:df:50:97:bc:3d:74:dd:ac:c3:
+        18:72:a7:66:9a:14:eb:22:33:89:bd:ad:f5:36:44:9a:71:6a:
+        78:b9:bd:e4:9a:a8:bf:de:c7:18:d8:6b:09:81:d9:d6:3f:a4:
+        11:df:18:68:58:e4:8a:8a:d3:31:28:eb:cc:59:a6:5f:89:62:
+        23:b2:ee:09:86:fd:33:b6:ba:84:5a:fe:10:57:c7:ab:16:eb:
+        69:44:84:67:bd:8a:89:22:d5:f7:91:d5:4c:99:00:45:dc:c7:
+        90:e8:7e:60:5e:e8:f7:e4:90:22:8c:bd:a2:0b:58:67:6a:ca:
+        7a:89:f9:fa:73:24:ac:39:29:0e:eb:cf:bc:82:72:b7:8d:52:
+        59:a3:7c:bb:72:0d:05:79:c3:90:1f:31:05:fc:7b:54:f1:7e:
+        fd:78:99:6c:21:74:cc:83:95:3f:09:e6:77:7f:16:6c:0f:3e:
+        71:24:31:ef:b8:95:3a:7a:2d:31:de:fa:33:7c:45:d7:ce:50:
+        9f:9d:82:95:27:b1:78:5c:ba:8f:49:02:37:a4:3f:ac:bc:1d:
+        51:c2:73:ac:75:9d:fe:8d:ee:94:81:60:95:45:3c:c4:ba:34:
+        25:3e:01:04:da:a0:0f:ed:b9:96:3a:81:ae:2f:d2:aa:0c:73:
+        05:f9:ec:79:90:6e:69:a7:aa:3d:ce:76:31:95:db:55:ef:64:
+        69:d1:e2:e7:e8:71:04:3c:14:d5:97:ad:b9:6e:20:bd:33:3d:
+        f2:d5:22:f0:c3:be:63:35:e1:7d:f8:81:6d:ac:60:ff:52:f1:
+        64:cc:b7:9c:bd:f4:bb:61:10:d7:a9:ba:6d:1a:e5:54:cc:4c:
+        7d:1a:8d:8a:85:0d:3a:91:8a:f3:7b:fd:6a:a5:66:3e:3a:34:
+        f6:df:f2:6e:26:b6:e0:b2:1b:28:f3:b7:bc:0c:6f:c7:7f:0c:
+        a5:0a:51:07:be:be:bb:7b:48:50:ae:f8:5e:2c:01:7b:8a:7a:
+        33:e2:30:39:53:a2:55:eb:4d:86:cf:eb:d4:21:63:9c:58:d6:
+        6e:1d:42:79:d3:3c:40:f4
 
 -----BEGIN CERTIFICATE-----
 MIIF2jCCA8KgAwIBAgIUUC0yUXu5UfDfbk7DBR8sS6/NUnMwDQYJKoZIhvcNAQEL