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}