Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ resolver = "2"

[workspace.package]
edition = "2021"
rust-version = "1.64.0"
rust-version = "1.70.0"
2 changes: 1 addition & 1 deletion rustls-symcrypt/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "rustls-symcrypt"
authors = ["Microsoft"]
version = "0.2.2"
version = "0.2.3"
license = "Apache-2.0 OR ISC OR MIT"
description = "Implementation of rustls crypto provider model for SymCrypt"
edition.workspace = true
Expand Down
48 changes: 48 additions & 0 deletions rustls-symcrypt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use rustls::crypto::{CryptoProvider, GetRandomFailed, SecureRandom, SupportedKxGroup};

use rustls::SupportedCipherSuite;
use std::sync::{Arc, OnceLock};
use symcrypt::symcrypt_random;

mod cipher_suites;
Expand Down Expand Up @@ -70,6 +71,41 @@ pub fn default_symcrypt_provider() -> CryptoProvider {
}
}

/// Returns a process-cached `Arc<CryptoProvider>` for callers that want
/// session-/connection-/test-scoped sharing without paying for repeated
/// `Vec<SupportedCipherSuite>` and `Vec<&dyn SupportedKxGroup>` allocations
/// on every call to [`default_symcrypt_provider`].
///
/// Initialized lazily on the first call; subsequent calls are an
/// `Arc::clone` (atomic refcount bump, no heap allocation).
///
/// Prefer this over `Arc::new(default_symcrypt_provider())` in any code
/// path that may run more than once per process — TLS integration tests,
/// per-connection setup, multi-config harnesses, etc.
///
/// ```rust
/// use rustls::{ClientConfig, RootCertStore};
/// use rustls_symcrypt::default_symcrypt_provider_arc;
/// use webpki_roots;
///
/// let mut root_store = RootCertStore {
/// roots: webpki_roots::TLS_SERVER_ROOTS.iter().cloned().collect(),
/// };
///
/// let provider = default_symcrypt_provider_arc();
/// let mut config = ClientConfig::builder_with_provider(provider)
/// .with_safe_default_protocol_versions()
/// .unwrap()
/// .with_root_certificates(root_store)
/// .with_no_client_auth();
/// ```
pub fn default_symcrypt_provider_arc() -> Arc<CryptoProvider> {
static PROVIDER: OnceLock<Arc<CryptoProvider>> = OnceLock::new();
PROVIDER
.get_or_init(|| Arc::new(default_symcrypt_provider()))
.clone()
}

/// `custom_symcrypt_provider` provides a way to set up an custom config using a `symcrypt` crypto backend.
///
/// `provided_cipher_suites` takes in an optional `Vec<>` of `SupportedCipherSuites`.
Expand Down Expand Up @@ -190,4 +226,16 @@ mod test {

assert_ne!(buff_1, buff_2);
}

#[test]
fn test_default_symcrypt_provider_arc_is_cached() {
let a = default_symcrypt_provider_arc();
let b = default_symcrypt_provider_arc();
assert!(
Arc::ptr_eq(&a, &b),
"default_symcrypt_provider_arc must return the same Arc on repeat calls",
);
assert_eq!(a.cipher_suites.len(), DEFAULT_CIPHER_SUITES.len());
assert!(!a.kx_groups.is_empty());
}
}
Loading