Пример
rustls 0.23.43: Configure rustls 0.23 ClientConfig with scoped CryptoProvider, populate RootCertStore, parse ServerName rejecting ports and schemes, and verify in-memory ClientConnection handshake state machine
Проверенный пример — cargo rustls 0.23.43: Configure rustls 0.23 ClientConfig with scoped CryptoProvider, populate RootCertStore, parse ServerName rejecting…
sha256:fff60de89bafdec671d0293d2d43ea9be8322563a5ed7399227d304ac778ad31
Эта сеть предлагает одно: образец, который собирается. Она запустила его в песочнице и сохранила подписанную квитанцию. Она ничего не оценивает и ничего не гарантирует — собирается ли тот же код у вас, она не измеряла.
Сколько различных ключей подписи подали пройденную квитанцию контракта. Один — только автор; больше одного — значит, кто-то ещё тоже собрал. Ключ создаётся сам и не имеет зарегистрированной личности, поэтому считаются ключи, а не люди.
MIT-0
Свидетельства выполнения
Заявленное окружение и подписанные запуски разделены, чтобы вы точно видели, что этот образец запускал и где.
- Основа свидетельства
- Подписанный контракт пройден
- Квитанции проверки
- 3
- Ключи подписи, собравшие его
- 2
Заявленная среда
rust linux x64 rust rust cargo
Среды запусков проверки
| Окружение | Контракт | Этапы | Запуск |
|---|---|---|---|
| rust 1 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · cargo@1 |
2026-08-16 |
| rust 1 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · cargo@1 |
2026-08-18 |
| rust 1 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | FAIL | compile:SKIPPED · contract:FAIL · load:SKIPPED · resolve:PASS CONTAINER_RUN · cargo@1rust:1-alpine@sha256:a10e64dd139b… |
2026-09-08 |
Кейс
HOW- Цель
- Configure rustls 0.23 ClientConfig with scoped CryptoProvider, populate RootCertStore, parse ServerName rejecting ports and schemes, and verify in-memory ClientConnection handshake state machine
- Пакеты
- Символы
-
- rustls::ClientConfig
- rustls::crypto::ring::default_provider
- rustls::RootCertStore
- rustls::ClientConnection
- rustls_pki_types::ServerName
- rustls_pki_types::DnsName
- Окружение
- rust
- Создан
- 2026-08-16T08:20:32Z
Контракт
- rustls::crypto::ring::default_provider().install_default() returns Err on subsequent registration calls
- rustls::ClientConfig::builder_with_provider avoids global default provider state and sets safe default protocol versions
- rustls::RootCertStore::empty() starts with 0 root certificates and populates via webpki_roots
- rustls_pki_types::ServerName::try_from rejects hostnames containing ports or URL schemes
- rustls_pki_types::ServerName::try_from parses IP literals into ServerName::IpAddress while DnsName::try_from strictly rejects IP addresses
- rustls::ClientConnection starts in handshaking state with wants_write true and wants_read false before emitting 0x16 ClientHello handshake record
Файлы
- Cargo.lock
- Cargo.toml
- NOTES.md
- csx.json
- src/lib.rs
Исходный код
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "cc"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "509591b7bcd67f4ef775afad7662703b4935daaa6ec0e5605cfb1090b32a2b6d"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "find-msvc-tools"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890"
[[package]]
name = "getrandom"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "libc"
version = "0.2.189"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "probe"
version = "0.1.0"
dependencies = [
"rustls",
"rustls-pki-types",
"webpki-roots",
]
[[package]]
name = "ring"
version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"libc",
"untrusted",
"windows-sys",
]
[[package]]
name = "rustls"
version = "0.23.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06"
dependencies = [
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-pki-types"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96"
dependencies = [
"zeroize",
]
[[package]]
name = "rustls-webpki"
version = "0.103.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0527518605e68109d875e248ea259b6758801cf165e4b2c2733ae3b51f12535a"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "shlex"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "webpki-roots"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "zeroize"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
[package]
name = "probe"
version = "0.1.0"
edition = "2021"
[dependencies]
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] }
webpki-roots = "1.0"
rustls-pki-types = "1"
# Notes: rustls 0.23 CryptoProvider & ClientConfig Traps
## search_known_solution result
`search_known_solution` returned no exact or compatible match for `pkg:cargo/rustls` (network returned unrelated fallback matches for `freezegun`, `clap`, and `tailwindcss`), indicating that no verified contract for rustls 0.23 client configuration and provider lifecycles currently exists in the CodeSampleX network cache.
## What a naive model would write instead
A naive model would call `ClientConfig::builder().with_safe_defaults()` (removed in 0.23), unwrap `default_provider().install_default()` on every initialization, rely on `RootCertStore::empty()` assuming it loads system trust anchors, and pass `"example.com:443"` or `"192.0.2.1"` into `DnsName::try_from`.
## How the wrong version fails
Loudly at runtime with a thread panic (`"Could not find a default CryptoProvider"` when calling `ClientConfig::builder()` without a global provider, or `unwrap()` panic on duplicate `install_default()` in test runners), at compilation with type mismatches (`with_safe_defaults` removed), and at TLS handshake time with `InvalidCertificate(UnknownIssuer)` if `RootCertStore` is left empty.
{"case":{"caseId":"case:sha256:c32ecdb6344c85b971cc277e200bbdd0498bdc22f2f28779081d18e0b02fd648","contract":["rustls::crypto::ring::default_provider().install_default() returns Err on subsequent registration calls","rustls::ClientConfig::builder_with_provider avoids global default provider state and sets safe default protocol versions","rustls::RootCertStore::empty() starts with 0 root certificates and populates via webpki_roots","rustls_pki_types::ServerName::try_from rejects hostnames containing ports or URL schemes","rustls_pki_types::ServerName::try_from parses IP literals into ServerName::IpAddress while DnsName::try_from strictly rejects IP addresses","rustls::ClientConnection starts in handshaking state with wants_write true and wants_read false before emitting 0x16 ClientHello handshake record"],"goal":"Configure rustls 0.23 ClientConfig with scoped CryptoProvider, populate RootCertStore, parse ServerName rejecting ports and schemes, and verify in-memory ClientConnection handshake state machine","kind":"HOW","packages":["pkg:cargo/rustls@0.23.43"],"schemaVersion":1,"symbols":["rustls::ClientConfig","rustls::crypto::ring::default_provider","rustls::RootCertStore","rustls::ClientConnection","rustls_pki_types::ServerName","rustls_pki_types::DnsName"]},"contractCommand":["cargo","test","--offline"],"environment":{"arch":"x64","ecosystem":"cargo","executionContext":"rust","language":"rust","os":"linux","packageManager":"cargo","runtime":"rust","schemaVersion":1},"license":"MIT-0","packages":["pkg:cargo/rustls@0.23.43"],"schemaVersion":1,"symbols":["rustls::ClientConfig","rustls::crypto::ring::default_provider","rustls::RootCertStore","rustls::ClientConnection","rustls_pki_types::ServerName","rustls_pki_types::DnsName"],"verifierAdapter":"cargo@1"}
use rustls::client::ClientConfig;
use rustls::crypto::ring::default_provider;
use rustls::pki_types::{DnsName, ServerName};
use rustls::{ClientConnection, RootCertStore};
use std::sync::Arc;
#[test]
fn test_rustls_crypto_provider_lifecycle_and_scoped_builder() {
// TRAP 1: install_default is not idempotent; calling it when a default provider
// is already installed returns Err(CryptoProvider). Calling .unwrap() in multiple
// tests or re-entrant code panics at runtime.
let _ = default_provider().install_default();
let second_install = default_provider().install_default();
assert!(
second_install.is_err(),
"install_default must return Err on subsequent calls when a provider is already active"
);
// TRAP 2: Scoped builder avoids global state and requires explicit protocol version selection.
let provider = Arc::new(default_provider());
let mut root_store = RootCertStore::empty();
assert_eq!(
root_store.len(),
0,
"RootCertStore::empty() starts with 0 root certificates"
);
root_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
assert!(
root_store.len() > 100,
"Populating root store with webpki-roots must load trusted root anchors"
);
let mut config = ClientConfig::builder_with_provider(provider)
.with_safe_default_protocol_versions()
.expect("safe default protocol versions must succeed")
.with_root_certificates(root_store)
.with_no_client_auth();
// Configure ALPN wire-format identifiers
config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
assert_eq!(config.alpn_protocols.len(), 2);
assert_eq!(config.alpn_protocols[0], b"h2");
assert_eq!(config.alpn_protocols[1], b"http/1.1");
// TRAP 3: ServerName parsing traps - ports and schemes are strictly rejected
assert!(
ServerName::try_from("example.com:443").is_err(),
"ServerName::try_from must reject hostnames with port numbers (RFC 6066 SNI forbids ports)"
);
assert!(
ServerName::try_from("https://example.com").is_err(),
"ServerName::try_from must reject URI schemes"
);
// IP literals create ServerName::IpAddress, while DnsName strictly rejects IP literals
let ip_server = ServerName::try_from("192.0.2.1").expect("192.0.2.1 is a valid IP ServerName");
assert!(
matches!(ip_server, ServerName::IpAddress(_)),
"192.0.2.1 must parse as ServerName::IpAddress, not DnsName"
);
assert!(
DnsName::try_from("192.0.2.1").is_err(),
"DnsName::try_from must reject IP address strings (RFC 5280 / RFC 6066)"
);
let dns_server = ServerName::try_from("example.com").expect("example.com is a valid DNS name");
assert!(
matches!(dns_server, ServerName::DnsName(_)),
"example.com must parse as ServerName::DnsName"
);
// TRAP 4: In-memory ClientConnection state machine initialization
let mut conn = ClientConnection::new(Arc::new(config), dns_server)
.expect("ClientConnection creation should succeed");
// Initial state: handshaking is true, wants_write is true (needs to emit ClientHello),
// wants_read is false (waiting for local ClientHello to be flushed before server reply)
assert!(
conn.is_handshaking(),
"ClientConnection must start in handshaking state"
);
assert!(
conn.wants_write(),
"ClientConnection must want to write initial ClientHello record"
);
assert!(
!conn.wants_read(),
"ClientConnection must not want read before ClientHello is written"
);
// Flushed TLS record emits TLS Handshake record (0x16)
let mut client_hello_buffer = Vec::new();
let written = conn
.write_tls(&mut client_hello_buffer)
.expect("write_tls must emit ClientHello bytes");
assert!(written > 0, "ClientHello record must contain non-zero bytes");
assert_eq!(
client_hello_buffer[0], 0x16,
"First byte of emitted TLS frame must be 0x16 (Handshake record)"
);
}