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