rtc_dtls/lib.rs
1#![warn(rust_2018_idioms)]
2#![warn(missing_docs)]
3#![allow(dead_code)]
4
5//! DTLS 1.2 for the Sans-I/O WebRTC stack.
6//!
7//! An implementation of Datagram Transport Layer Security ([RFC 6347]) with the extensions
8//! WebRTC requires: DTLS-SRTP key export ([RFC 5764]), extended master secret
9//! ([RFC 7627]), and elliptic-curve cipher suites ([RFC 4492], [RFC 5289]). It secures the
10//! media and data-channel path: SRTP keying material comes out of the DTLS handshake, and
11//! SCTP data channels run over the DTLS association itself.
12//!
13//! # Structure
14//!
15//! * [`endpoint`] — the Sans-I/O entry point: feed it datagrams, poll it for the datagrams
16//! it wants to send and the events it produces. No sockets, no timers of its own.
17//! * [`config`] — certificates, cipher-suite and curve preferences, the client/server role,
18//! and the SRTP protection profiles to negotiate.
19//! * [`handshake`], [`flight`], [`state`] — the handshake message types and the flight state
20//! machine that drives them, including retransmission.
21//! * [`cipher_suite`], [`crypto`], [`curve`], [`signature_hash_algorithm`] — the
22//! cryptographic primitives and the negotiated-suite abstraction.
23//! * [`extension`] — the ClientHello/ServerHello extensions, including `use_srtp` and SNI.
24//! * [`alert`], [`content`], [`record_layer`] — the record layer and its content types.
25//!
26//! # Example
27//!
28//! A WebRTC handshake is configured with a self-signed certificate and the SRTP profiles to
29//! negotiate through `use_srtp`; the keys for those profiles are then exported from the
30//! completed handshake rather than signalled:
31//!
32//! ```
33//! use rtc_dtls::config::{ConfigBuilder, ExtendedMasterSecretType};
34//! use rtc_dtls::extension::extension_use_srtp::SrtpProtectionProfile;
35//!
36//! let builder = ConfigBuilder::default()
37//! .with_srtp_protection_profiles(vec![
38//! SrtpProtectionProfile::Srtp_Aead_Aes_128_Gcm,
39//! SrtpProtectionProfile::Srtp_Aes128_Cm_Hmac_Sha1_80,
40//! ])
41//! .with_extended_master_secret(ExtendedMasterSecretType::Require);
42//! # let _ = builder;
43//! ```
44//!
45//! Most applications do not depend on this crate directly — the
46//! [`rtc`](https://docs.rs/rtc) crate drives it as one layer of the peer-connection
47//! pipeline.
48//!
49//! [RFC 6347]: https://datatracker.ietf.org/doc/html/rfc6347
50//! [RFC 5764]: https://datatracker.ietf.org/doc/html/rfc5764
51//! [RFC 7627]: https://datatracker.ietf.org/doc/html/rfc7627
52//! [RFC 4492]: https://datatracker.ietf.org/doc/html/rfc4492
53//! [RFC 5289]: https://datatracker.ietf.org/doc/html/rfc5289
54
55/// Alert records: fatal errors and the orderly `close_notify`.
56pub mod alert;
57/// Application data records — the payload DTLS carries once the handshake completes.
58pub mod application_data;
59/// The ChangeCipherSpec record, which switches a side over to the negotiated keys.
60pub mod change_cipher_spec;
61/// The negotiable cipher suites and the [`CipherSuite`] trait they
62/// implement.
63pub mod cipher_suite;
64/// Certificate types a server may request from a client.
65pub mod client_certificate_type;
66/// The compression-methods field. DTLS in WebRTC always negotiates null compression.
67pub mod compression_methods;
68/// Handshake configuration: certificates, roles, cipher-suite and SRTP profile preferences.
69pub mod config;
70/// Connection state shared across the handshake and record layers.
71pub mod conn;
72/// Record content types: handshake, alert, change-cipher-spec and application data.
73pub mod content;
74/// Cryptographic primitives: the AEAD and CBC ciphers, certificates and signatures.
75pub mod crypto;
76/// Elliptic curves and the key-exchange values exchanged over them.
77pub mod curve;
78/// The Sans-I/O entry point: feed it datagrams, poll it for output and events.
79pub mod endpoint;
80/// ClientHello and ServerHello extensions, including `use_srtp` and SNI.
81pub mod extension;
82/// The flight state machine, which drives the handshake and its retransmissions.
83pub mod flight;
84/// Reassembly of handshake messages fragmented across datagrams.
85pub mod fragment_buffer;
86/// The handshake message types and the cache that hashes them for `Finished`.
87pub mod handshake;
88/// Handshake orchestration: state, roles and the verification callbacks.
89pub mod handshaker;
90/// The pseudo-random function that expands the master secret into keys.
91pub mod prf;
92/// The record layer: framing, sequence numbers and epochs.
93pub mod record_layer;
94/// Signature and hash algorithm pairs, as negotiated for certificate verification.
95pub mod signature_hash_algorithm;
96/// The negotiated connection state: keys, sequence numbers and peer identity.
97pub mod state;
98
99use cipher_suite::*;
100use extension::extension_use_srtp::SrtpProtectionProfile;
101
102#[cfg(all(feature = "aws-lc-rs", feature = "ring"))]
103compile_error!("At most one of the features \"aws-lc-rs\" and \"ring\" can be enabled.");
104#[cfg(not(any(feature = "aws-lc-rs", feature = "ring")))]
105compile_error!("At least one of the features \"aws-lc-rs\" and \"ring\" must be enabled.");
106#[cfg(feature = "aws-lc-rs")]
107extern crate aws_lc_rs as ring;
108
109pub(crate) fn find_matching_srtp_profile(
110 a: &[SrtpProtectionProfile],
111 b: &[SrtpProtectionProfile],
112) -> Result<SrtpProtectionProfile, ()> {
113 for a_profile in a {
114 for b_profile in b {
115 if a_profile == b_profile {
116 return Ok(*a_profile);
117 }
118 }
119 }
120 Err(())
121}
122
123pub(crate) fn find_matching_cipher_suite(
124 a: &[CipherSuiteId],
125 b: &[CipherSuiteId],
126) -> Result<CipherSuiteId, ()> {
127 for a_suite in a {
128 for b_suite in b {
129 if a_suite == b_suite {
130 return Ok(*a_suite);
131 }
132 }
133 }
134 Err(())
135}