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