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 {
347 match cert.private_key.kind {
348 CryptoPrivateKeyKind::Ed25519(_) => {}
349 CryptoPrivateKeyKind::Ecdsa256(_) => {}
350 CryptoPrivateKeyKind::Rsa256(_) => {}
351 CryptoPrivateKeyKind::Custom(_) => {}
352 }
353 }
354
355 parse_cipher_suites(&self.cipher_suites, self.psk.is_none(), self.psk.is_some())?;
356
357 Ok(())
358 }
359
360 pub fn build(
362 mut self,
363 is_client: bool,
364 remote_addr: Option<SocketAddr>,
365 ) -> Result<HandshakeConfig> {
366 self.validate(is_client)?;
367
368 let local_cipher_suites: Vec<CipherSuiteId> =
369 parse_cipher_suites(&self.cipher_suites, self.psk.is_none(), self.psk.is_some())?
370 .iter()
371 .map(|cs| cs.id())
372 .collect();
373
374 let sigs: Vec<u16> = self.signature_schemes.iter().map(|x| *x as u16).collect();
375 let local_signature_schemes = parse_signature_schemes(&sigs, self.insecure_hashes)?;
376
377 let retransmit_interval = if self.flight_interval != Duration::from_secs(0) {
378 self.flight_interval
379 } else {
380 INITIAL_TICKER_INTERVAL
381 };
382
383 let maximum_transmission_unit = if self.mtu == 0 { DEFAULT_MTU } else { self.mtu };
384
385 let replay_protection_window = if self.replay_protection_window == 0 {
386 DEFAULT_REPLAY_PROTECTION_WINDOW
387 } else {
388 self.replay_protection_window
389 };
390
391 let mut server_name = self.server_name.clone();
392
393 if is_client && server_name.is_empty() {
395 if let Some(remote_addr) = remote_addr {
396 server_name = remote_addr.ip().to_string();
397 } else {
398 warn!(
399 "conn.remote_addr is empty, please set explicitly server_name in Config! Use default \"localhost\" as server_name now"
400 );
401 "localhost".clone_into(&mut server_name);
402 }
403 }
404
405 Ok(HandshakeConfig {
406 local_psk_callback: self.psk.take(),
407 local_psk_identity_hint: self.psk_identity_hint.take(),
408 local_cipher_suites,
409 local_signature_schemes,
410 extended_master_secret: self.extended_master_secret,
411 local_srtp_protection_profiles: self.srtp_protection_profiles,
412 server_name,
413 client_auth: self.client_auth,
414 local_certificates: self.certificates,
415 insecure_skip_verify: self.insecure_skip_verify,
416 insecure_verification: self.insecure_verification,
417 verify_peer_certificate: self.verify_peer_certificate.take(),
418 roots_cas: self.roots_cas,
419 server_cert_verifier: server_cert_verifier(Arc::new(gen_self_signed_root_cert()))?,
420 client_cert_verifier: None,
421 retransmit_interval,
422 initial_epoch: 0,
423 maximum_transmission_unit,
424 replay_protection_window,
425 ..Default::default()
426 })
427 }
428}
429
430pub type VerifyPeerCertificateFn =
435 Arc<dyn (Fn(&[Vec<u8>], &[CertificateDer<'static>]) -> Result<()>) + Send + Sync>;
436
437pub fn gen_self_signed_root_cert() -> rustls::RootCertStore {
439 let mut certs = rustls::RootCertStore::empty();
440 certs
441 .add(
442 rcgen::generate_simple_self_signed(vec![])
443 .unwrap()
444 .cert
445 .der()
446 .to_owned(),
447 )
448 .unwrap();
449 certs
450}
451
452#[derive(Clone)]
453pub struct HandshakeConfig {
455 pub(crate) local_psk_callback: Option<PskCallback>,
456 pub(crate) local_psk_identity_hint: Option<Vec<u8>>,
457 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,
462 pub(crate) client_auth: ClientAuthType, pub(crate) local_certificates: Vec<Certificate>,
464 pub(crate) name_to_certificate: HashMap<String, Certificate>,
465 pub(crate) insecure_skip_verify: bool,
466 pub(crate) insecure_verification: bool,
467 pub(crate) verify_peer_certificate: Option<VerifyPeerCertificateFn>,
468 pub(crate) roots_cas: rustls::RootCertStore,
469 pub(crate) server_cert_verifier: Arc<dyn ServerCertVerifier>,
470 pub(crate) client_cert_verifier: Option<Arc<dyn ClientCertVerifier>>,
471 pub(crate) retransmit_interval: std::time::Duration,
472 pub(crate) initial_epoch: u16,
473 pub(crate) maximum_transmission_unit: usize,
474 pub(crate) maximum_retransmit_number: usize,
475 pub(crate) replay_protection_window: usize,
476}
477
478impl fmt::Debug for HandshakeConfig {
479 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
480 fmt.debug_struct("HandshakeConfig<T>")
481 .field("local_psk_identity_hint", &self.local_psk_identity_hint)
482 .field("local_cipher_suites", &self.local_cipher_suites)
483 .field("local_signature_schemes", &self.local_signature_schemes)
484 .field("extended_master_secret", &self.extended_master_secret)
485 .field(
486 "local_srtp_protection_profiles",
487 &self.local_srtp_protection_profiles,
488 )
489 .field("server_name", &self.server_name)
490 .field("client_auth", &self.client_auth)
491 .field("local_certificates", &self.local_certificates)
492 .field("name_to_certificate", &self.name_to_certificate)
493 .field("insecure_skip_verify", &self.insecure_skip_verify)
494 .field("insecure_verification", &self.insecure_verification)
495 .field("roots_cas", &self.roots_cas)
496 .field("retransmit_interval", &self.retransmit_interval)
497 .field("initial_epoch", &self.initial_epoch)
498 .field("maximum_transmission_unit", &self.maximum_transmission_unit)
499 .field("maximum_retransmit_number", &self.maximum_retransmit_number)
500 .field("replay_protection_window", &self.replay_protection_window)
501 .finish()
502 }
503}
504
505impl Default for HandshakeConfig {
506 fn default() -> Self {
507 HandshakeConfig {
508 local_psk_callback: None,
509 local_psk_identity_hint: None,
510 local_cipher_suites: vec![],
511 local_signature_schemes: vec![],
512 extended_master_secret: ExtendedMasterSecretType::Disable,
513 local_srtp_protection_profiles: vec![],
514 server_name: String::new(),
515 client_auth: ClientAuthType::NoClientCert,
516 local_certificates: vec![],
517 name_to_certificate: HashMap::new(),
518 insecure_skip_verify: false,
519 insecure_verification: false,
520 verify_peer_certificate: None,
521 roots_cas: rustls::RootCertStore::empty(),
522 server_cert_verifier: server_cert_verifier(Arc::new(gen_self_signed_root_cert()))
523 .expect("the built-in self-signed root is always a valid trust anchor"),
524 client_cert_verifier: None,
525 retransmit_interval: std::time::Duration::from_secs(0),
526 initial_epoch: 0,
527 maximum_transmission_unit: DEFAULT_MTU,
528 maximum_retransmit_number: 7,
529 replay_protection_window: DEFAULT_REPLAY_PROTECTION_WINDOW,
530 }
531 }
532}
533
534impl HandshakeConfig {
535 pub(crate) fn get_certificate(&self, server_name: &str) -> Result<Certificate> {
536 if self.local_certificates.is_empty() {
537 return Err(Error::ErrNoCertificates);
538 }
539
540 if self.local_certificates.len() == 1 {
541 return Ok(self.local_certificates[0].clone());
543 }
544
545 if server_name.is_empty() {
546 return Ok(self.local_certificates[0].clone());
547 }
548
549 let lower = server_name.to_lowercase();
550 let name = lower.trim_end_matches('.');
551
552 if let Some(cert) = self.name_to_certificate.get(name) {
553 return Ok(cert.clone());
554 }
555
556 let mut labels: Vec<&str> = name.split_terminator('.').collect();
559 for i in 0..labels.len() {
560 labels[i] = "*";
561 let candidate = labels.join(".");
562 if let Some(cert) = self.name_to_certificate.get(&candidate) {
563 return Ok(cert.clone());
564 }
565 }
566
567 Ok(self.local_certificates[0].clone())
569 }
570}