tls.rs
Overview
This file provides comprehensive TLS (Transport Layer Security) configuration, certificate management, and verification utilities tailored for cryptographic operations with a focus on Ed25519 signatures. It facilitates generating self-signed TLS certificates embedded with Ed25519 signatures, creating client and server TLS configurations, verifying certificates against trusted hashes and Ed25519 public keys, and caching generated certificates for reuse. The file also includes serialization helpers for Ed25519 public keys and collections thereof.
The code integrates Rustls for TLS protocol handling, ed25519_dalek for Ed25519 signatures, rcgen for certificate generation, and x509_parser for X.509 certificate parsing.
Main Components
Structs and Types
NoCertVerification
Implements both ServerCertVerifier and ClientCertVerifier from Rustls.
Bypasses standard certificate verification by always approving certificates and signatures.
Used in debug mode to disable strict TLS validation.
TlsCertCache
Thread-safe cache for TLS certificates and private keys.
Caches certificates generated with given subjects and Ed25519 signing keys to avoid regeneration.
Internally uses a mutex-protected
TlsCertCacheInner.
TlsCertCacheInner
Holds the default private key and a map of cached certificates.
The cache key is a concatenation of the subject strings, TLS private key DER bytes, and Ed25519 public keys.
Functions
supported_schemes() -> Vec<SignatureScheme>
Returns a list of supported TLS signature schemes, including RSA, ECDSA, and EdDSA (Ed25519 and Ed448).
Certificate Verification Implementations - NoCertVerification
verify_server_cert, verify_tls12_signature, verify_tls13_signature: Always return success.
supported_verify_schemes: Returns the supported signature schemes.
Same methods implemented for client verification.
root_cert_store(credential: &NetCredential) -> RootCertStore
Returns an empty root certificate store.
Placeholder for future extension; currently disables root certificate validation.
client_tls_config
pub fn client_tls_config(
is_debug: bool,
credential: &NetCredential,
alpn_preferred: &[&str],
) -> Result<rustls::ClientConfig, anyhow::Error>
Creates a Rustls TLS client configuration.
In debug mode:
Uses
NoCertVerificationto skip certificate verification.Uses TLS 1.3 only.
Otherwise:
Uses root certificates from
root_cert_store.Uses client authentication with provided credentials.
Sets ALPN protocols from
alpn_preferred.Enables TLS key logging.
Returns configured
rustls::ClientConfig.
Usage example:
let client_config = client_tls_config(false, &credential, &["h3"]).unwrap();
server_tls_config
pub fn server_tls_config(
is_debug: bool,
credential: &NetCredential,
alpn_supported: &[&str],
) -> anyhow::Result<rustls::ServerConfig>
Creates a Rustls TLS server configuration.
In debug mode:
Uses
NoCertVerificationfor client cert verification.Uses TLS 1.3 only.
Otherwise:
Uses
WebPkiClientVerifierwith root certs.Uses TLS 1.3 only.
Sets ALPN protocols from
alpn_supported.Returns configured
rustls::ServerConfig.
generate_self_signed_cert
pub fn generate_self_signed_cert(
subjects: Option<Vec<String>>,
ed_signing_keys: &[ed25519_dalek::SigningKey],
) -> anyhow::Result<(PrivateKeyDer<'static>, CertificateDer<'static>)>
Generates a new random TLS private key.
Creates a self-signed certificate for given DNS subjects (default: "localhost").
Embeds Ed25519 signatures of the TLS public key as a custom X.509 extension.
Returns the private key and certificate DER.
create_self_signed_cert_with_ed_signatures
pub fn create_self_signed_cert_with_ed_signatures(
subjects: Option<Vec<String>>,
tls_key: &PrivateKeyDer<'static>,
ed_signing_keys: &[ed25519_dalek::SigningKey],
) -> anyhow::Result<(PrivateKeyDer<'static>, CertificateDer<'static>)>
Creates a self-signed certificate with a pre-existing TLS private key.
Embeds multiple Ed25519 signature-key pairs in a custom X.509 extension.
The extension OID is
1.2.3.4.5.6.The extension content concatenates each Ed25519 verifying key (32 bytes) and corresponding signature (64 bytes).
Returns the TLS key and generated certificate DER.
get_pubkeys_from_cert_der
pub fn get_pubkeys_from_cert_der(
cert: &CertificateDer<'static>,
) -> Result<Vec<VerifyingKey>, StartError>
Parses a DER-encoded certificate.
Extracts Ed25519 public keys embedded in the custom extension.
Validates signatures against the TLS public key.
Returns a vector of valid Ed25519 verifying keys.
get_pubkeys_from_cert
pub fn get_pubkeys_from_cert(
cert: &x509_parser::certificate::X509Certificate,
) -> Result<Vec<VerifyingKey>, StartError>
Similar to
get_pubkeys_from_cert_derbut operates on parsed X509Certificate.Returns Ed25519 verifying keys extracted from the custom extension.
verify_cert
pub fn verify_cert(
cert: &CertificateDer<'static>,
trusted_hashes: &HashSet<CertHash>,
trusted_pubkeys: &HashSet<VerifyingKey>,
) -> Result<(), StartError>
Parses and verifies the X.509 certificate signature.
Computes
CertHashfrom the certificate DER.Extracts embedded Ed25519 public keys.
Validates the certificate based on trusted hashes and trusted Ed25519 public keys.
Returns error if verification fails.
verify_cert_hash_and_pubkeys
pub fn verify_cert_hash_and_pubkeys(
hash: &CertHash,
pubkeys: &[VerifyingKey],
trusted_hashes: &HashSet<CertHash>,
trusted_pubkeys: &HashSet<VerifyingKey>,
) -> Result<(), StartError>
Implements logic for verifying certificate trust:
If no trusted hashes or pubkeys specified, approval is automatic.
If only trusted pubkeys specified, verifies that at least one pubkey matches.
If only trusted hashes specified, verifies that the hash matches.
If both specified, tries pubkeys first, then hashes.
Errors indicate untrusted certificate or invalid signatures.
build_pkcs12
pub fn build_pkcs12(credential: &NetCredential) -> anyhow::Result<Vec<u8>>
Builds a PKCS#12 (PFX) archive from the first certificate and private key in the credential.
Returns the DER-encoded PFX bytes.
Useful for interoperability with systems requiring PKCS#12 bundles.
resolve_signing_keys
pub fn resolve_signing_keys(
key_secrets: &[String],
key_paths: &[String],
) -> anyhow::Result<Vec<crate::SigningKey>>
Parses Ed25519 signing keys from:
Inline hex-encoded secret strings.
JSON files on disk containing a
secretfield.
Returns a vector of resolved signing keys.
TlsCertCache Methods
new() -> anyhow::Result<Self>: Creates a new cache with a randomly generated default TLS private key.get_key_cert(subjects: Option<Vec<String>>, tls_key: Option<&PrivateKeyDer<'static>>, ed_signing_keys: &[ed25519_dalek::SigningKey]) -> anyhow::Result<(PrivateKeyDer<'static>, CertificateDer<'static>)>:Returns a cached certificate matching the inputs or generates a new self-signed cert with Ed25519 signatures.
Uses a computed cache key based on subjects, TLS key, and Ed25519 keys.
Serialization Modules
hex_verifying_key
Provides Serde serializers and deserializers for a single Ed25519
VerifyingKey.Serializes as a 64-character hex string.
Deserializes from a hex string back to
VerifyingKey.
hex_verifying_keys
Provides Serde serializers and deserializers for a vector of Ed25519
VerifyingKeys.Serializes as a JSON array of hex strings.
Deserializes from a JSON array of hex strings.
Tests
test_cert_validation: Generates Ed25519 key pairs and self-signed certificates.Verifies that certificates signed by trusted keys pass verification.
Asserts that certificates signed by untrusted keys fail verification.
Important Implementation Details
Custom X.509 Extension for Ed25519 Signatures:
The file defines a custom OID1.2.3.4.5.6to embed multiple Ed25519 public keys and signatures over the TLS public key in the certificate. This enables strong binding of specific Ed25519 keys to the TLS certificate.Dual Verification Strategy:
The certificate verification accommodates both trusted certificate hashes and trusted Ed25519 public keys. This hybrid approach allows flexible trust models.NoCertVerification:
In debug mode, certificate verification is disabled to facilitate testing and development, while in production mode, proper root certificate stores and client cert verifiers are used.Certificate Caching:
TheTlsCertCacheavoids repeated certificate generation for identical inputs, improving performance in scenarios with multiple TLS connections.Rustls TLS 1.3 Only:
Both client and server configurations restrict to TLS 1.3 protocol version.
File Interactions and Dependencies
Uses
ed25519_dalekfor Ed25519 cryptographic primitives.Uses
rustlsfor TLS configuration and verification.Uses
rcgenfor certificate generation.Uses
x509_parserfor parsing and inspecting X.509 certificates.Uses
serdefor (de)serialization of keys.References
NetCredentialandCertHashtypes defined elsewhere in the project.Uses
StartErrorerror type from themsquic_asyncconnection module for error handling related to certificate validation.
Diagram: TLS Certificate Cache and Generation Workflow
flowchart TD
A[Request Key+Cert] --> B{Cache Hit?}
B -- Yes --> C[Return Cached Key+Cert]
B -- No --> D[Generate Self-Signed Cert]
D --> E[Embed Ed25519 Signatures Extension]
E --> F[Store in Cache]
F --> C
Request Key+Cert: Input includes subjects, optional TLS key, and Ed25519 signing keys.
Cache Hit?: Checks if a cert with these inputs already exists.
Generate Self-Signed Cert: Creates new cert with given inputs.
Embed Ed25519 Signatures Extension: Adds custom extension with Ed25519 keys and signatures.
Store in Cache: Saves newly generated cert for reuse.
Return Cached Key+Cert: Returns the key and certificate to caller.
Notes on Key Functions and Usage
Use
client_tls_configandserver_tls_configto create TLS configurations for clients and servers respectively, providing necessary certs and ALPN protocols.To generate a new key and self-signed certificate with Ed25519 signatures, use
generate_self_signed_cert.To verify certificates against trusted hashes or public keys, use
verify_cert.For efficient certificate reuse, instantiate and use a
TlsCertCache.For serialization of Ed25519 public keys in config files or network messages, use
hex_verifying_keyandhex_verifying_keysmodules.
Refer to TLS Configuration and Certificate Management for detailed background on TLS setup and certificate usage. For cryptographic primitives, see Ed25519 Cryptography.