diff --git a/Cargo.toml b/Cargo.toml index d5c1679..c513386 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,46 +12,53 @@ repository = "https://github.com/webrtc-rs/dtls" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -util = { package = "webrtc-util", version = "0.4.3", default-features = false, features = ["conn"] } -byteorder = "1.3.2" -lazy_static = "1.3.0" -rand_core = "0.5" -elliptic-curve = {version = "0.8.4", features=["default", "ecdh", "zeroize"]} -p256 = { version = "0.7.1", features=["default", "ecdh", "zeroize", "ecdsa"] } +util = { package = "webrtc-util", version = "0.4.3", default-features = false, features = [ + "conn", +] } +byteorder = "1.4.3" +lazy_static = "1.4.0" +rand_core = "0.6.3" +elliptic-curve = { version = "0.10.6", features = [ + "default", + "ecdh", + "zeroize", +] } +p256 = { version = "0.9.0", features = ["default", "ecdh", "zeroize", "ecdsa"] } #p384 = "0.4.1" -rand = "0.8.0" -hmac = "0.10.1" -sha-1 = "0.9.1" -sha2 = "0.9.1" -aes = "0.6.0" -block-modes = "0.7.0" -aes-gcm = "0.8.0" -ccm = "0.3.0" +rand = "0.8.4" +hmac = "0.11.0" +sha-1 = "0.9.8" +sha2 = "0.9.8" +aes = "0.7.5" +block-modes = "0.8.1" +aes-gcm = "0.9.4" +ccm = "0.4.4" tokio = { version = "1.12.0", features = ["full"] } -async-trait = "0.1" -x25519-dalek = "1.1.0" -signature = "1.2.2" -oid-registry = "0.1.1" -x509-parser = "0.9" -der-parser = "5.0" +async-trait = "0.1.51" +x25519-dalek = { version = "1.1.1", package = "x25519-dalek-ng" } +signature = "1.3.1" +oid-registry = "0.2.0" +x509-parser = "0.12.0" +der-parser = "6.0.0" rcgen = "0.8.13" -ring = "0.16.19" -webpki = "0.21.4" -rustls = { version = "0.19.0", features = ["dangerous_configuration"]} -bincode = "1.3.1" -serde = "1.0" -serde_derive = "1.0" +ring = "0.16.20" +webpki = "0.22.0" +rustls = { version = "0.20.0", features = ["dangerous_configuration"] } +bincode = "1.3.3" +serde = "1.0.130" +serde_derive = "1.0.130" subtle = "2.4.1" -log = "0.4" -thiserror = "1.0.25" -anyhow = "1.0.41" +log = "0.4.14" +thiserror = "1.0.29" +anyhow = "1.0.44" [dev-dependencies] -tokio-test = "0.4" +tokio-test = "0.4.2" env_logger = "0.9.0" chrono = "0.4.19" -clap = "2" -hub = {path = "examples/hub"} +clap = "2.33.3" +hub = { path = "examples/hub" } +rustls-pemfile = "0.2.1" [[example]] name = "dial_psk" @@ -82,5 +89,3 @@ bench = false name = "listen_verify" path = "examples/listen/verify/listen_verify.rs" bench = false - - diff --git a/examples/dial/verify/dial_verify.rs b/examples/dial/verify/dial_verify.rs index f0bc8ef..cf44edc 100644 --- a/examples/dial/verify/dial_verify.rs +++ b/examples/dial/verify/dial_verify.rs @@ -68,10 +68,13 @@ async fn main() -> Result<()> { let mut cert_pool = rustls::RootCertStore::empty(); let f = File::open("examples/certificates/server.pub.pem")?; let mut reader = BufReader::new(f); - if let Err(_) = cert_pool.add_pem_file(&mut reader) { + if let Ok(Some(rustls_pemfile::Item::X509Certificate(cert))) = + rustls_pemfile::read_one(&mut reader) + { + cert_pool.add(&rustls::Certificate(cert))?; + } else { return Err(Error::new("cert_pool add_pem_file failed".to_owned()).into()); } - let config = Config { certificates: vec![certificate], extended_master_secret: ExtendedMasterSecretType::Require, diff --git a/examples/hub/Cargo.toml b/examples/hub/Cargo.toml index e1138f6..25c5427 100644 --- a/examples/hub/Cargo.toml +++ b/examples/hub/Cargo.toml @@ -4,13 +4,16 @@ version = "0.1.0" edition = "2018" [dependencies] -util = { package = "webrtc-util", version = "0.4.3", default-features = false, features = ["conn"] } +util = { package = "webrtc-util", version = "0.4.3", default-features = false, features = [ + "conn", +] } dtls = { package = "webrtc-dtls", path = "../../" } tokio = { version = "1.12.0", features = ["full"] } x509-parser = "0.12.0" -rcgen = { version = "0.8.13", features = ["pem", "x509-parser"]} +rcgen = { version = "0.8.13", features = ["pem", "x509-parser"] } ring = "0.16.19" -rustls = "0.19.0" +rustls = "0.20.0" log = "0.4" thiserror = "1.0.25" anyhow = "1.0.41" +rustls-pemfile = "0.2.1" diff --git a/examples/hub/src/utilities.rs b/examples/hub/src/utilities.rs index e84e820..cc09f5d 100644 --- a/examples/hub/src/utilities.rs +++ b/examples/hub/src/utilities.rs @@ -3,7 +3,7 @@ use super::*; use anyhow::Result; use dtls::crypto::{Certificate, CryptoPrivateKey}; use rcgen::KeyPair; -use rustls::internal::pemfile::certs; +use rustls_pemfile; use std::fs::File; use std::io::Read; use std::path::PathBuf; @@ -98,11 +98,11 @@ pub fn load_key(path: PathBuf) -> Result { /// load_certificate Load/read certificate(s) from file pub fn load_certificate(path: PathBuf) -> Result> { - let f = File::open(&path)?; + let certs: Vec<_> = rustls_pemfile::certs(&mut BufReader::new(File::open(&path)?)) + .unwrap() + .iter() + .map(|v| rustls::Certificate(v.clone())) + .collect(); - let mut reader = BufReader::new(f); - match certs(&mut reader) { - Ok(ders) => Ok(ders), - Err(_) => Err(Error::ErrNoCertificateFound.into()), - } + Ok(certs) } diff --git a/examples/listen/verify/listen_verify.rs b/examples/listen/verify/listen_verify.rs index 0231276..2238913 100644 --- a/examples/listen/verify/listen_verify.rs +++ b/examples/listen/verify/listen_verify.rs @@ -64,7 +64,11 @@ async fn main() -> Result<()> { let mut cert_pool = rustls::RootCertStore::empty(); let f = File::open("examples/certificates/server.pub.pem")?; let mut reader = BufReader::new(f); - if let Err(_) = cert_pool.add_pem_file(&mut reader) { + if let Ok(Some(rustls_pemfile::Item::X509Certificate(cert))) = + rustls_pemfile::read_one(&mut reader) + { + cert_pool.add(&rustls::Certificate(cert))?; + } else { return Err(Error::new("cert_pool add_pem_file failed".to_owned()).into()); } diff --git a/src/conn/mod.rs b/src/conn/mod.rs index f8c44ec..4b224bd 100644 --- a/src/conn/mod.rs +++ b/src/conn/mod.rs @@ -213,11 +213,12 @@ impl DTLSConn { local_certificates: config.certificates.clone(), insecure_skip_verify: config.insecure_skip_verify, verify_peer_certificate: config.verify_peer_certificate.take(), - roots_cas: config.roots_cas, client_cert_verifier: if config.client_auth as u8 >= ClientAuthType::VerifyClientCertIfGiven as u8 { - Some(rustls::AllowAnyAuthenticatedClient::new(config.client_cas)) + Some(rustls::server::AllowAnyAuthenticatedClient::new( + config.roots_cas, + )) } else { None }, diff --git a/src/crypto/crypto_cbc.rs b/src/crypto/crypto_cbc.rs index fa71189..ad3ae3b 100644 --- a/src/crypto/crypto_cbc.rs +++ b/src/crypto/crypto_cbc.rs @@ -73,7 +73,7 @@ impl CryptoCbc { let mut iv: Vec = vec![0; Self::BLOCK_SIZE]; rand::thread_rng().fill(iv.as_mut_slice()); - let write_cbc = Aes256Cbc::new_var(&self.local_key, &iv)?; + let write_cbc = Aes256Cbc::new_from_slices(&self.local_key, &iv)?; let encrypted = write_cbc.encrypt_vec(&payload); // Prepend unencrypte header with encrypted payload @@ -102,7 +102,7 @@ impl CryptoCbc { let body = &body[Self::BLOCK_SIZE..]; //TODO: add body.len() check - let read_cbc = Aes256Cbc::new_var(&self.remote_key, iv)?; + let read_cbc = Aes256Cbc::new_from_slices(&self.remote_key, iv)?; let decrypted = read_cbc.decrypt_vec(body)?; diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs index 3beb890..2ae1be8 100644 --- a/src/crypto/mod.rs +++ b/src/crypto/mod.rs @@ -15,7 +15,10 @@ use der_parser::{oid, oid::Oid}; use rcgen::KeyPair; use ring::rand::SystemRandom; use ring::signature::{EcdsaKeyPair, Ed25519KeyPair, RsaKeyPair}; +use rustls::ServerName; +use std::convert::TryFrom; use std::sync::Arc; +use std::time::SystemTime; #[derive(Clone, PartialEq)] pub struct Certificate { @@ -406,13 +409,21 @@ pub(crate) fn load_certs(raw_certificates: &[Vec]) -> Result], - cert_verifier: &Arc, + cert_verifier: &Arc, ) -> Result> { let chains = load_certs(raw_certificates)?; - match cert_verifier.verify_client_cert(&chains, None) { + if chains.is_empty() { + return Err(rustls::Error::NoCertificatesPresented.into()); + } + + let (end_entity, intermediates) = chains + .split_first() + .ok_or(rustls::Error::NoCertificatesPresented)?; + + match cert_verifier.verify_client_cert(end_entity, intermediates, SystemTime::now()) { Ok(_) => {} - Err(err) => return Err(Error::new(err.to_string()).into()), + Err(err) => return Err(err.into()), }; Ok(chains) @@ -420,17 +431,32 @@ pub(crate) fn verify_client_cert( pub(crate) fn verify_server_cert( raw_certificates: &[Vec], - cert_verifier: &Arc, - roots: &rustls::RootCertStore, + cert_verifier: &Arc, server_name: &str, ) -> Result> { - let chains = load_certs(raw_certificates)?; - let dns_name = match webpki::DNSNameRef::try_from_ascii_str(server_name) { - Ok(dns_name) => dns_name, - Err(err) => return Err(Error::new(err.to_string()).into()), + let server_name = match ServerName::try_from(server_name) { + Ok(server_name) => server_name, + Err(_) => return Err(Error::new("Invalid Dns Name".to_string()).into()), }; - match cert_verifier.verify_server_cert(roots, &chains, dns_name, &[]) { + let chains = load_certs(raw_certificates)?; + if chains.is_empty() { + return Err(rustls::Error::NoCertificatesPresented.into()); + } + + let (end_entity, intermediates) = chains + .split_first() + .ok_or(rustls::Error::NoCertificatesPresented)?; + + const SCTS: &[&[u8]] = &[]; + match cert_verifier.verify_server_cert( + end_entity, + intermediates, + &server_name, + &mut SCTS.iter().copied(), + &[], + SystemTime::now(), + ) { Ok(_) => {} Err(err) => return Err(Error::new(err.to_string()).into()), }; diff --git a/src/flight/flight5.rs b/src/flight/flight5.rs index 7c627e5..3352183 100644 --- a/src/flight/flight5.rs +++ b/src/flight/flight5.rs @@ -722,7 +722,6 @@ async fn initalize_cipher_suite( chains = match verify_server_cert( &state.peer_certificates, &cfg.server_cert_verifier, - &cfg.roots_cas, &cfg.server_name, ) { Ok(chains) => chains, diff --git a/src/handshaker.rs b/src/handshaker.rs index 8a6bb24..cb29d70 100644 --- a/src/handshaker.rs +++ b/src/handshaker.rs @@ -87,9 +87,8 @@ pub(crate) struct HandshakeConfig { pub(crate) name_to_certificate: HashMap, pub(crate) insecure_skip_verify: bool, pub(crate) verify_peer_certificate: Option, - pub(crate) roots_cas: rustls::RootCertStore, - pub(crate) server_cert_verifier: Arc, - pub(crate) client_cert_verifier: Option>, + pub(crate) server_cert_verifier: Arc, + pub(crate) client_cert_verifier: Option>, pub(crate) retransmit_interval: tokio::time::Duration, pub(crate) initial_epoch: u16, //log logging.LeveledLogger @@ -111,8 +110,10 @@ impl Default for HandshakeConfig { name_to_certificate: HashMap::new(), insecure_skip_verify: false, verify_peer_certificate: None, - roots_cas: rustls::RootCertStore::empty(), - server_cert_verifier: Arc::new(rustls::WebPKIVerifier::new()), + server_cert_verifier: Arc::new(rustls::client::WebPkiVerifier::new( + rustls::RootCertStore::empty(), + None, + )), client_cert_verifier: None, retransmit_interval: tokio::time::Duration::from_secs(0), initial_epoch: 0, diff --git a/src/prf/mod.rs b/src/prf/mod.rs index 35b8c0d..d6bdf1b 100644 --- a/src/prf/mod.rs +++ b/src/prf/mod.rs @@ -133,7 +133,7 @@ fn elliptic_curve_pre_master_secret( fn hmac_sha(h: CipherSuiteHash, key: &[u8], data: &[u8]) -> Result> { let mut mac = match h { CipherSuiteHash::Sha256 => { - HmacSha256::new_varkey(key).map_err(|e| Error::new(e.to_string()))? + HmacSha256::new_from_slice(key).map_err(|e| Error::new(e.to_string()))? } }; mac.update(data); @@ -288,7 +288,7 @@ pub(crate) fn prf_mac( payload: &[u8], key: &[u8], ) -> Result> { - let mut hmac = HmacSha1::new_varkey(key).map_err(|e| Error::new(e.to_string()))?; + let mut hmac = HmacSha1::new_from_slice(key).map_err(|e| Error::new(e.to_string()))?; let mut msg = vec![0u8; 13]; msg[..2].copy_from_slice(&epoch.to_be_bytes());