webrtc_dtls/config.rs
1use std::sync::Arc;
2
3use tokio::time::Duration;
4
5use crate::cipher_suite::*;
6use crate::crypto::*;
7use crate::error::*;
8use crate::extension::extension_use_srtp::SrtpProtectionProfile;
9use crate::handshaker::VerifyPeerCertificateFn;
10use crate::signature_hash_algorithm::SignatureScheme;
11
12/// Config is used to configure a DTLS client or server.
13/// After a Config is passed to a DTLS function it must not be modified.
14#[derive(Clone)]
15pub struct Config {
16 /// certificates contains certificate chain to present to the other side of the connection.
17 /// Server MUST set this if psk is non-nil
18 /// client SHOULD sets this so CertificateRequests can be handled if psk is non-nil
19 pub certificates: Vec<Certificate>,
20
21 /// cipher_suites is a list of supported cipher suites.
22 /// If cipher_suites is nil, a default list is used
23 pub cipher_suites: Vec<CipherSuiteId>,
24
25 /// signature_schemes contains the signature and hash schemes that the peer requests to verify.
26 pub signature_schemes: Vec<SignatureScheme>,
27
28 /// srtp_protection_profiles are the supported protection profiles
29 /// Clients will send this via use_srtp and assert that the server properly responds
30 /// Servers will assert that clients send one of these profiles and will respond as needed
31 pub srtp_protection_profiles: Vec<SrtpProtectionProfile>,
32
33 /// client_auth determines the server's policy for
34 /// TLS Client Authentication. The default is NoClientCert.
35 pub client_auth: ClientAuthType,
36
37 /// extended_master_secret determines if the "Extended Master Secret" extension
38 /// should be disabled, requested, or required (default requested).
39 pub extended_master_secret: ExtendedMasterSecretType,
40
41 /// flight_interval controls how often we send outbound handshake messages
42 /// defaults to time.Second
43 pub flight_interval: Duration,
44
45 /// psk sets the pre-shared key used by this DTLS connection
46 /// If psk is non-nil only psk cipher_suites will be used
47 pub psk: Option<PskCallback>,
48 pub psk_identity_hint: Option<Vec<u8>>,
49
50 /// insecure_skip_verify controls whether a client verifies the
51 /// server's certificate chain and host name.
52 /// If insecure_skip_verify is true, TLS accepts any certificate
53 /// presented by the server and any host name in that certificate.
54 /// In this mode, TLS is susceptible to man-in-the-middle attacks.
55 /// This should be used only for testing.
56 pub insecure_skip_verify: bool,
57
58 /// insecure_hashes allows the use of hashing algorithms that are known
59 /// to be vulnerable.
60 pub insecure_hashes: bool,
61
62 /// insecure_verification allows the use of verification algorithms that are
63 /// known to be vulnerable or deprecated
64 pub insecure_verification: bool,
65 /// VerifyPeerCertificate, if not nil, is called after normal
66 /// certificate verification by either a client or server. It
67 /// receives the certificate provided by the peer and also a flag
68 /// that tells if normal verification has succeeded. If it returns a
69 /// non-nil error, the handshake is aborted and that error results.
70 ///
71 /// If normal verification fails then the handshake will abort before
72 /// considering this callback. If normal verification is disabled by
73 /// setting insecure_skip_verify, or (for a server) when client_auth is
74 /// RequestClientCert or RequireAnyClientCert, then this callback will
75 /// be considered but the verifiedChains will always be nil.
76 pub verify_peer_certificate: Option<VerifyPeerCertificateFn>,
77
78 /// roots_cas defines the set of root certificate authorities
79 /// that one peer uses when verifying the other peer's certificates.
80 /// If RootCAs is nil, TLS uses the host's root CA set.
81 /// Used by Client to verify server's certificate
82 pub roots_cas: rustls::RootCertStore,
83
84 /// client_cas defines the set of root certificate authorities
85 /// that servers use if required to verify a client certificate
86 /// by the policy in client_auth.
87 /// Used by Server to verify client's certificate
88 pub client_cas: rustls::RootCertStore,
89
90 /// server_name is used to verify the hostname on the returned
91 /// certificates unless insecure_skip_verify is given.
92 pub server_name: String,
93
94 /// mtu is the length at which handshake messages will be fragmented to
95 /// fit within the maximum transmission unit (default is 1200 bytes)
96 pub mtu: usize,
97
98 /// replay_protection_window is the size of the replay attack protection window.
99 /// Duplication of the sequence number is checked in this window size.
100 /// Packet with sequence number older than this value compared to the latest
101 /// accepted packet will be discarded. (default is 64)
102 pub replay_protection_window: usize,
103}
104
105impl Default for Config {
106 fn default() -> Self {
107 Config {
108 certificates: vec![],
109 cipher_suites: vec![],
110 signature_schemes: vec![],
111 srtp_protection_profiles: vec![],
112 client_auth: ClientAuthType::default(),
113 extended_master_secret: ExtendedMasterSecretType::default(),
114 flight_interval: Duration::default(),
115 psk: None,
116 psk_identity_hint: None,
117 insecure_skip_verify: false,
118 insecure_hashes: false,
119 insecure_verification: false,
120 verify_peer_certificate: None,
121 roots_cas: rustls::RootCertStore::empty(),
122 client_cas: rustls::RootCertStore::empty(),
123 server_name: String::default(),
124 mtu: 0,
125 replay_protection_window: 0,
126 }
127 }
128}
129
130pub(crate) const DEFAULT_MTU: usize = 1200; // bytes
131
132// PSKCallback is called once we have the remote's psk_identity_hint.
133// If the remote provided none it will be nil
134pub(crate) type PskCallback = Arc<dyn (Fn(&[u8]) -> Result<Vec<u8>>) + Send + Sync>;
135
136// ClientAuthType declares the policy the server will follow for
137// TLS Client Authentication.
138#[derive(Default, Copy, Clone, PartialEq, Eq)]
139pub enum ClientAuthType {
140 #[default]
141 NoClientCert = 0,
142 RequestClientCert = 1,
143 RequireAnyClientCert = 2,
144 VerifyClientCertIfGiven = 3,
145 RequireAndVerifyClientCert = 4,
146}
147
148// ExtendedMasterSecretType declares the policy the client and server
149// will follow for the Extended Master Secret extension
150#[derive(Default, PartialEq, Eq, Copy, Clone)]
151pub enum ExtendedMasterSecretType {
152 #[default]
153 Request = 0,
154 Require = 1,
155 Disable = 2,
156}
157
158pub(crate) fn validate_config(is_client: bool, config: &Config) -> Result<()> {
159 if is_client && config.psk.is_some() && config.psk_identity_hint.is_none() {
160 return Err(Error::ErrPskAndIdentityMustBeSetForClient);
161 }
162
163 if !is_client && config.psk.is_none() && config.certificates.is_empty() {
164 return Err(Error::ErrServerMustHaveCertificate);
165 }
166
167 if !config.certificates.is_empty() && config.psk.is_some() {
168 return Err(Error::ErrPskAndCertificate);
169 }
170
171 if config.psk_identity_hint.is_some() && config.psk.is_none() {
172 return Err(Error::ErrIdentityNoPsk);
173 }
174
175 for cert in &config.certificates {
176 match cert.private_key.kind {
177 CryptoPrivateKeyKind::Ed25519(_) => {}
178 CryptoPrivateKeyKind::Ecdsa256(_) => {}
179 _ => return Err(Error::ErrInvalidPrivateKey),
180 }
181 }
182
183 parse_cipher_suites(
184 &config.cipher_suites,
185 config.psk.is_none(),
186 config.psk.is_some(),
187 )?;
188
189 Ok(())
190}