diff --git a/Cargo.lock b/Cargo.lock index 26d7a7fb..8ee96f80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,12 +65,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" - [[package]] name = "botan" version = "0.10.6" @@ -128,22 +122,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" - [[package]] name = "crossbeam-channel" version = "0.5.8" @@ -225,33 +203,6 @@ dependencies = [ "syn 2.0.29", ] -[[package]] -name = "errno" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "fastrand" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" - [[package]] name = "foreign-types" version = "0.3.2" @@ -324,12 +275,6 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" -[[package]] -name = "linux-raw-sys" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" - [[package]] name = "log" version = "0.4.20" @@ -348,24 +293,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "nom" version = "7.1.3" @@ -456,7 +383,7 @@ version = "0.10.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cfg-if", "foreign-types", "libc", @@ -476,12 +403,6 @@ dependencies = [ "syn 2.0.29", ] -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - [[package]] name = "openssl-sys" version = "0.9.91" @@ -609,13 +530,13 @@ name = "rcgen" version = "0.11.1" dependencies = [ "botan", - "native-tls", "openssl", "pem", "pipe", "rand", "ring", "rsa", + "rustls", "rustls-webpki", "time", "x509-parser", @@ -629,15 +550,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73891b98dabbe836d23a094941e6ec891bc4880e771faea98813f2ff27ede473" -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "ring" version = "0.16.20" @@ -685,16 +597,15 @@ dependencies = [ ] [[package]] -name = "rustix" -version = "0.38.8" +name = "rustls" +version = "0.21.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" +checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" dependencies = [ - "bitflags 2.4.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", + "log", + "ring", + "rustls-webpki", + "sct", ] [[package]] @@ -708,35 +619,13 @@ dependencies = [ ] [[package]] -name = "schannel" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "security-framework" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.1" +name = "sct" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "core-foundation-sys", - "libc", + "ring", + "untrusted", ] [[package]] @@ -831,19 +720,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "tempfile" -version = "3.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall", - "rustix", - "windows-sys", -] - [[package]] name = "thiserror" version = "1.0.47" @@ -1019,72 +895,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "x509-parser" version = "0.15.1" diff --git a/Cargo.toml b/Cargo.toml index 72231bb1..23f5e3cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,10 +33,10 @@ default = ["pem"] features = ["x509-parser"] [dev-dependencies] -native-tls = "0.2" openssl = "0.10" pipe = { version = "0.4", features = ["bidirectional"] } x509-parser = { version = "0.15", features = ["verify"] } +rustls = "0.21" rustls-webpki = { version = "0.101.0", features = ["std"] } rand = "0.8" rsa = "0.9" diff --git a/examples/auto-gen-ca-and-server-tls.rs b/examples/auto-gen-ca-and-server-tls.rs index 700f4235..10e67738 100644 --- a/examples/auto-gen-ca-and-server-tls.rs +++ b/examples/auto-gen-ca-and-server-tls.rs @@ -10,53 +10,66 @@ //! TLS client in two separate threads in the same process. use std::error::Error; -use std::io; +use std::io::Write; +use std::sync::Arc; use std::thread; +use rustls; +use rustls::{PrivateKey, RootCertStore, ServerName}; +use rustls::server::Acceptor; -use native_tls::{HandshakeError, Identity, TlsAcceptor, TlsConnector, TlsStream}; use rcgen::{BasicConstraints, CertificateSigningRequest, DnType, IsCa, SanType, KeyUsagePurpose, DistinguishedName, CertificateParams, Certificate, RcgenError}; const SAN: &str = "example-server"; fn main() -> Result<(), Box> { let ca = gen_cert_for_ca()?; + let rustls_ca = rustls::Certificate(ca.serialize_der().unwrap()); println!("CA private key:\n{}", ca.serialize_private_key_pem()); println!(); println!("CA certificate:\n{}", ca.serialize_pem()?); let host_cert = gen_cert_for_server(&ca)?; + let host_cert_rustls = rustls::Certificate(host_cert.signed_certificate_der); + let host_pk = PrivateKey(host_cert.private_key_der); println!("Preparing to verify with tls"); - let leaf_then_ca = format!("{}{}", host_cert.signed_certificate_pem, ca.serialize_pem()?); + let leaf_then_ca = vec![host_cert_rustls, rustls_ca.clone()]; println!(); - println!("Server private key:\n{}", host_cert.private_key_pem); - println!("Server chain:\n{}\n", leaf_then_ca); - // For use by server - let server_id = Identity::from_pkcs8( - leaf_then_ca.as_bytes(), - host_cert.private_key_pem.as_bytes() - )?; - - // For use by client - let native_ca_cert = native_tls::Certificate::from_pem(ca.serialize_pem()?.as_bytes())?; - - let (p_client, p_server) = pipe::bipipe(); + let (mut p_client, mut p_server) = pipe::bipipe(); let t_client = thread::spawn(move || -> Result<(), String> { println!("Client creating"); - let test_client = TlsConnector::builder() - .add_root_certificate(native_ca_cert) - .build() - .map_err(|e| e.to_string())?; + let mut root_store = RootCertStore::empty(); + + root_store.add(&rustls_ca) + .unwrap(); + + let client_config = Arc::new( + rustls::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(root_store) + .with_no_client_auth() + ); + + let server_name = ServerName::try_from(SAN) + .unwrap(); + + let mut conn = rustls::ClientConnection::new(client_config, server_name) + .unwrap(); println!("Client connecting"); - let _stream = map_tls_io_error(test_client.connect(SAN, p_client))?; + let mut stream = rustls::Stream::new(&mut conn, &mut p_client); + + println!("Client sending"); + + let message = "Hello, from client".as_bytes(); + stream.write_all(message).unwrap(); println!("Client connected"); Ok(()) @@ -65,14 +78,42 @@ fn main() -> Result<(), Box> { let t_server = thread::spawn(move || -> Result<(), String> { println!("Server creating"); - let test_server = TlsAcceptor::new(server_id) - .map_err(|e| e.to_string())?; + let server_config = Arc::new( + rustls::ServerConfig::builder() + .with_safe_defaults() + .with_no_client_auth() + .with_single_cert(leaf_then_ca, host_pk) + .unwrap() + ); + + let mut acceptor = Acceptor::default(); - println!("Server accepting"); + println!("Server accepting"); + let accepted = loop { + println!("Server reading tls"); + acceptor.read_tls(&mut p_server) + .unwrap(); - let _server_tls_stream = map_tls_io_error(test_server.accept(p_server))?; + if let Some(accepted) = acceptor.accept().unwrap() { + break accepted; + } + }; println!("Server accepted"); + + let mut conn = accepted.into_connection(server_config) + .unwrap(); + + println!("Server created"); + + let mut stream = rustls::Stream::new(&mut conn, &mut p_server); + + println!("Server sending"); + + let message = "Hello, from server".as_bytes(); + stream.write_all(message).unwrap(); + + println!("Server sent"); Ok(()) }); @@ -91,12 +132,13 @@ fn main() -> Result<(), Box> { } struct ServerCertificate { - private_key_pem: String, + private_key_der: Vec, // Server certificate only; does not include complete certificate chain. - signed_certificate_pem: String, + signed_certificate_der: Vec, } +// Create a certificate authority using rcgen and return and rcgen::Certificate. fn gen_cert_for_ca() -> Result { let mut dn = DistinguishedName::new(); dn.push(DnType::CountryName, "USA"); @@ -112,6 +154,7 @@ fn gen_cert_for_ca() -> Result { Certificate::from_params(params) } +// Create a server (host) certificate using rcgen and return it encoded into the DER format. fn gen_cert_for_server(ca: &Certificate) -> Result { let mut dn = DistinguishedName::new(); dn.push(DnType::CountryName, "USA"); @@ -130,26 +173,10 @@ fn gen_cert_for_server(ca: &Certificate) -> Result(tls_result: Result, HandshakeError>) -> Result, String> -where - S: io::Read + io::Write -{ - match tls_result { - Ok(stream) => Ok(stream), - Err(he) => { - match he { - HandshakeError::Failure(e) => Err(format!("{}", e)), - // Can't directly unwrap because TlsStream doesn't implement Debug trait - HandshakeError::WouldBlock(_) => Err("Would block".into()) - } - } - } -}