1#[cfg(test)]
17mod config_test;
18
19use crate::cipher_suite::*;
20use crate::conn::{DEFAULT_REPLAY_PROTECTION_WINDOW, INITIAL_TICKER_INTERVAL};
21use crate::crypto::*;
22use crate::extension::extension_use_srtp::SrtpProtectionProfile;
23use crate::signature_hash_algorithm::{
24 SignatureHashAlgorithm, SignatureScheme, parse_signature_schemes,
25};
26use log::warn;
27use shared::error::*;
28use std::collections::HashMap;
29use std::fmt;
30use std::net::SocketAddr;
31use std::sync::Arc;
32use std::time::Duration;
33
34use rustls::client::danger::ServerCertVerifier;
35use rustls::pki_types::CertificateDer;
36use rustls::server::danger::ClientCertVerifier;
37
38fn crypto_provider() -> Option<std::sync::Arc<rustls::crypto::CryptoProvider>> {
50 #[cfg(feature = "aws-lc-rs")]
51 {
52 Some(std::sync::Arc::new(
53 rustls::crypto::aws_lc_rs::default_provider(),
54 ))
55 }
56 #[cfg(all(feature = "ring", not(feature = "aws-lc-rs")))]
57 {
58 Some(std::sync::Arc::new(rustls::crypto::ring::default_provider()))
59 }
60 #[cfg(not(any(feature = "ring", feature = "aws-lc-rs")))]
61 {
62 None
63 }
64}
65
66fn server_cert_verifier(
72 roots: std::sync::Arc<rustls::RootCertStore>,
73) -> Result<std::sync::Arc<rustls::client::WebPkiServerVerifier>> {
74 let builder = match crypto_provider() {
75 Some(provider) => {
76 rustls::client::WebPkiServerVerifier::builder_with_provider(roots, provider)
77 }
78 None => rustls::client::WebPkiServerVerifier::builder(roots),
79 };
80 builder
81 .build()
82 .map_err(|err| Error::Other(format!("rustls server cert verifier: {err}")))
83}
84
85#[derive(Clone)]
88pub struct ConfigBuilder {
89 certificates: Vec<Certificate>,
90 cipher_suites: Vec<CipherSuiteId>,
91 signature_schemes: Vec<SignatureScheme>,
92 srtp_protection_profiles: Vec<SrtpProtectionProfile>,
93 client_auth: ClientAuthType,
94 extended_master_secret: ExtendedMasterSecretType,
95 flight_interval: Duration,
96 psk: Option<PskCallback>,
97 psk_identity_hint: Option<Vec<u8>>,
98 insecure_skip_verify: bool,
99 insecure_hashes: bool,
100 insecure_verification: bool,
101 verify_peer_certificate: Option<VerifyPeerCertificateFn>,
102 roots_cas: rustls::RootCertStore,
103 client_cas: rustls::RootCertStore,
104 server_name: String,
105 mtu: usize,
106 replay_protection_window: usize,
107}
108
109impl Default for ConfigBuilder {
110 fn default() -> Self {
111 Self {
112 certificates: vec![],
113 cipher_suites: vec![],
114 signature_schemes: vec![],
115 srtp_protection_profiles: vec![],
116 client_auth: ClientAuthType::default(),
117 extended_master_secret: ExtendedMasterSecretType::default(),
118 flight_interval: Duration::default(),
119 psk: None,
120 psk_identity_hint: None,
121 insecure_skip_verify: false,
122 insecure_hashes: false,
123 insecure_verification: false,
124 verify_peer_certificate: None,
125 roots_cas: rustls::RootCertStore::empty(),
126 client_cas: rustls::RootCertStore::empty(),
127 server_name: String::default(),
128 mtu: 0,
129 replay_protection_window: 0,
130 }
131 }
132}
133
134impl ConfigBuilder {
135 pub fn with_certificates(mut self, certificates: Vec<Certificate>) -> Self {
139 self.certificates = certificates;
140 self
141 }
142
143 pub fn with_cipher_suites(mut self, cipher_suites: Vec<CipherSuiteId>) -> Self {
146 self.cipher_suites = cipher_suites;
147 self
148 }
149
150 pub fn with_signature_schemes(mut self, signature_schemes: Vec<SignatureScheme>) -> Self {
152 self.signature_schemes = signature_schemes;
153 self
154 }
155
156 pub fn with_srtp_protection_profiles(
160 mut self,
161 srtp_protection_profiles: Vec<SrtpProtectionProfile>,
162 ) -> Self {
163 self.srtp_protection_profiles = srtp_protection_profiles;
164 self
165 }
166
167 pub fn with_client_auth(mut self, client_auth: ClientAuthType) -> Self {
170 self.client_auth = client_auth;
171 self
172 }
173
174 pub fn with_extended_master_secret(
177 mut self,
178 extended_master_secret: ExtendedMasterSecretType,
179 ) -> Self {
180 self.extended_master_secret = extended_master_secret;
181 self
182 }
183
184 pub fn with_flight_interval(mut self, flight_interval: Duration) -> Self {
187 self.flight_interval = flight_interval;
188 self
189 }
190
191 pub fn with_psk(mut self, psk: Option<PskCallback>) -> Self {
194 self.psk = psk;
195 self
196 }
197
198 pub fn with_psk_identity_hint(mut self, psk_identity_hint: Option<Vec<u8>>) -> Self {
200 self.psk_identity_hint = psk_identity_hint;
201 self
202 }
203
204 pub fn with_insecure_skip_verify(mut self, insecure_skip_verify: bool) -> Self {
211 self.insecure_skip_verify = insecure_skip_verify;
212 self
213 }
214
215 pub fn with_insecure_hashes(mut self, insecure_hashes: bool) -> Self {
218 self.insecure_hashes = insecure_hashes;
219 self
220 }
221
222 pub fn with_insecure_verification(mut self, insecure_verification: bool) -> Self {
225 self.insecure_verification = insecure_verification;
226 self
227 }
228
229 pub fn with_verify_peer_certificate(
241 mut self,
242 verify_peer_certificate: Option<VerifyPeerCertificateFn>,
243 ) -> Self {
244 self.verify_peer_certificate = verify_peer_certificate;
245 self
246 }
247
248 pub fn with_roots_cas(mut self, roots_cas: rustls::RootCertStore) -> Self {
253 self.roots_cas = roots_cas;
254 self
255 }
256
257 pub fn with_client_cas(mut self, client_cas: rustls::RootCertStore) -> Self {
262 self.client_cas = client_cas;
263 self
264 }
265
266 pub fn with_server_name(mut self, server_name: String) -> Self {
269 self.server_name = server_name;
270 self
271 }
272
273 pub fn with_mtu(mut self, mtu: usize) -> Self {
276 self.mtu = mtu;
277 self
278 }
279
280 pub fn with_replay_protection_window(mut self, replay_protection_window: usize) -> Self {
285 self.replay_protection_window = replay_protection_window;
286 self
287 }
288}
289
290pub(crate) const DEFAULT_MTU: usize = 1200; pub(crate) type PskCallback = Arc<dyn (Fn(&[u8]) -> Result<Vec<u8>>) + Send + Sync>;
295
296#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
299pub enum ClientAuthType {
300 #[default]
301 NoClientCert = 0,
303 RequestClientCert = 1,
305 RequireAnyClientCert = 2,
307 VerifyClientCertIfGiven = 3,
309 RequireAndVerifyClientCert = 4,
311}
312
313#[derive(Debug, Default, PartialEq, Eq, Copy, Clone)]
316pub enum ExtendedMasterSecretType {
318 #[default]
319 Request = 0,
321 Require = 1,
323 Disable = 2,
325}
326
327impl ConfigBuilder {
328 fn validate(&self, is_client: bool) -> Result<()> {
329 if is_client && self.psk.is_some() && self.psk_identity_hint.is_none() {
330 return Err(Error::ErrPskAndIdentityMustBeSetForClient);
331 }
332
333 if !is_client && self.psk.is_none() && self.certificates.is_empty() {
334 return Err(Error::ErrServerMustHaveCertificate);
335 }
336
337 if !self.certificates.is_empty() && self.psk.is_some() {
338 return Err(Error::ErrPskAndCertificate);
339 }
340
341 if self.psk_identity_hint.is_some() && self.psk.is_none() {
342 return Err(Error::ErrIdentityNoPsk);
343 }
344
345 for cert in &self.certificates {
346 match cert.private_key.kind {
347 CryptoPrivateKeyKind::Ed25519(_) => {}
348 CryptoPrivateKeyKind::Ecdsa256(_) => {}
349 CryptoPrivateKeyKind::Custom(_) => {}
350 _ => return Err(Error::ErrInvalidPrivateKey),
351 }
352 }
353
354 parse_cipher_suites(&self.cipher_suites, self.psk.is_none(), self.psk.is_some())?;
355
356 Ok(())
357 }
358
359 pub fn build(
361 mut self,
362 is_client: bool,
363 remote_addr: Option<SocketAddr>,
364 ) -> Result<HandshakeConfig> {
365 self.validate(is_client)?;
366
367 let local_cipher_suites: Vec<CipherSuiteId> =
368 parse_cipher_suites(&self.cipher_suites, self.psk.is_none(), self.psk.is_some())?
369 .iter()
370 .map(|cs| cs.id())
371 .collect();
372
373 let sigs: Vec<u16> = self.signature_schemes.iter().map(|x| *x as u16).collect();
374 let local_signature_schemes = parse_signature_schemes(&sigs, self.insecure_hashes)?;
375
376 let retransmit_interval = if self.flight_interval != Duration::from_secs(0) {
377 self.flight_interval
378 } else {
379 INITIAL_TICKER_INTERVAL
380 };
381
382 let maximum_transmission_unit = if self.mtu == 0 { DEFAULT_MTU } else { self.mtu };
383
384 let replay_protection_window = if self.replay_protection_window == 0 {
385 DEFAULT_REPLAY_PROTECTION_WINDOW
386 } else {
387 self.replay_protection_window
388 };
389
390 let mut server_name = self.server_name.clone();
391
392 if is_client && server_name.is_empty() {
394 if let Some(remote_addr) = remote_addr {
395 server_name = remote_addr.ip().to_string();
396 } else {
397 warn!(
398 "conn.remote_addr is empty, please set explicitly server_name in Config! Use default \"localhost\" as server_name now"
399 );
400 "localhost".clone_into(&mut server_name);
401 }
402 }
403
404 Ok(HandshakeConfig {
405 local_psk_callback: self.psk.take(),
406 local_psk_identity_hint: self.psk_identity_hint.take(),
407 local_cipher_suites,
408 local_signature_schemes,
409 extended_master_secret: self.extended_master_secret,
410 local_srtp_protection_profiles: self.srtp_protection_profiles,
411 server_name,
412 client_auth: self.client_auth,
413 local_certificates: self.certificates,
414 insecure_skip_verify: self.insecure_skip_verify,
415 insecure_verification: self.insecure_verification,
416 verify_peer_certificate: self.verify_peer_certificate.take(),
417 roots_cas: self.roots_cas,
418 server_cert_verifier: server_cert_verifier(Arc::new(gen_self_signed_root_cert()))?,
419 client_cert_verifier: None,
420 retransmit_interval,
421 initial_epoch: 0,
422 maximum_transmission_unit,
423 replay_protection_window,
424 ..Default::default()
425 })
426 }
427}
428
429pub type VerifyPeerCertificateFn =
434 Arc<dyn (Fn(&[Vec<u8>], &[CertificateDer<'static>]) -> Result<()>) + Send + Sync>;
435
436pub fn gen_self_signed_root_cert() -> rustls::RootCertStore {
438 let mut certs = rustls::RootCertStore::empty();
439 certs
440 .add(
441 rcgen::generate_simple_self_signed(vec![])
442 .unwrap()
443 .cert
444 .der()
445 .to_owned(),
446 )
447 .unwrap();
448 certs
449}
450
451#[derive(Clone)]
452pub struct HandshakeConfig {
454 pub(crate) local_psk_callback: Option<PskCallback>,
455 pub(crate) local_psk_identity_hint: Option<Vec<u8>>,
456 pub(crate) local_cipher_suites: Vec<CipherSuiteId>, pub(crate) local_signature_schemes: Vec<SignatureHashAlgorithm>, pub(crate) extended_master_secret: ExtendedMasterSecretType, pub(crate) local_srtp_protection_profiles: Vec<SrtpProtectionProfile>, pub(crate) server_name: String,
461 pub(crate) client_auth: ClientAuthType, pub(crate) local_certificates: Vec<Certificate>,
463 pub(crate) name_to_certificate: HashMap<String, Certificate>,
464 pub(crate) insecure_skip_verify: bool,
465 pub(crate) insecure_verification: bool,
466 pub(crate) verify_peer_certificate: Option<VerifyPeerCertificateFn>,
467 pub(crate) roots_cas: rustls::RootCertStore,
468 pub(crate) server_cert_verifier: Arc<dyn ServerCertVerifier>,
469 pub(crate) client_cert_verifier: Option<Arc<dyn ClientCertVerifier>>,
470 pub(crate) retransmit_interval: std::time::Duration,
471 pub(crate) initial_epoch: u16,
472 pub(crate) maximum_transmission_unit: usize,
473 pub(crate) maximum_retransmit_number: usize,
474 pub(crate) replay_protection_window: usize,
475}
476
477impl fmt::Debug for HandshakeConfig {
478 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
479 fmt.debug_struct("HandshakeConfig<T>")
480 .field("local_psk_identity_hint", &self.local_psk_identity_hint)
481 .field("local_cipher_suites", &self.local_cipher_suites)
482 .field("local_signature_schemes", &self.local_signature_schemes)
483 .field("extended_master_secret", &self.extended_master_secret)
484 .field(
485 "local_srtp_protection_profiles",
486 &self.local_srtp_protection_profiles,
487 )
488 .field("server_name", &self.server_name)
489 .field("client_auth", &self.client_auth)
490 .field("local_certificates", &self.local_certificates)
491 .field("name_to_certificate", &self.name_to_certificate)
492 .field("insecure_skip_verify", &self.insecure_skip_verify)
493 .field("insecure_verification", &self.insecure_verification)
494 .field("roots_cas", &self.roots_cas)
495 .field("retransmit_interval", &self.retransmit_interval)
496 .field("initial_epoch", &self.initial_epoch)
497 .field("maximum_transmission_unit", &self.maximum_transmission_unit)
498 .field("maximum_retransmit_number", &self.maximum_retransmit_number)
499 .field("replay_protection_window", &self.replay_protection_window)
500 .finish()
501 }
502}
503
504impl Default for HandshakeConfig {
505 fn default() -> Self {
506 HandshakeConfig {
507 local_psk_callback: None,
508 local_psk_identity_hint: None,
509 local_cipher_suites: vec![],
510 local_signature_schemes: vec![],
511 extended_master_secret: ExtendedMasterSecretType::Disable,
512 local_srtp_protection_profiles: vec![],
513 server_name: String::new(),
514 client_auth: ClientAuthType::NoClientCert,
515 local_certificates: vec![],
516 name_to_certificate: HashMap::new(),
517 insecure_skip_verify: false,
518 insecure_verification: false,
519 verify_peer_certificate: None,
520 roots_cas: rustls::RootCertStore::empty(),
521 server_cert_verifier: server_cert_verifier(Arc::new(gen_self_signed_root_cert()))
522 .expect("the built-in self-signed root is always a valid trust anchor"),
523 client_cert_verifier: None,
524 retransmit_interval: std::time::Duration::from_secs(0),
525 initial_epoch: 0,
526 maximum_transmission_unit: DEFAULT_MTU,
527 maximum_retransmit_number: 7,
528 replay_protection_window: DEFAULT_REPLAY_PROTECTION_WINDOW,
529 }
530 }
531}
532
533impl HandshakeConfig {
534 pub(crate) fn get_certificate(&self, server_name: &str) -> Result<Certificate> {
535 if self.local_certificates.is_empty() {
536 return Err(Error::ErrNoCertificates);
537 }
538
539 if self.local_certificates.len() == 1 {
540 return Ok(self.local_certificates[0].clone());
542 }
543
544 if server_name.is_empty() {
545 return Ok(self.local_certificates[0].clone());
546 }
547
548 let lower = server_name.to_lowercase();
549 let name = lower.trim_end_matches('.');
550
551 if let Some(cert) = self.name_to_certificate.get(name) {
552 return Ok(cert.clone());
553 }
554
555 let mut labels: Vec<&str> = name.split_terminator('.').collect();
558 for i in 0..labels.len() {
559 labels[i] = "*";
560 let candidate = labels.join(".");
561 if let Some(cert) = self.name_to_certificate.get(&candidate) {
562 return Ok(cert.clone());
563 }
564 }
565
566 Ok(self.local_certificates[0].clone())
568 }
569}