dimpl
dimpl — DTLS 1.2 and 1.3 implementation (Sans‑IO, Sync)
dimpl is a DTLS 1.2 and 1.3 implementation aimed at WebRTC. It is a Sans‑IO state machine you embed into your own UDP/RTC event loop: you feed incoming datagrams, poll for outgoing records or timers, and wire up certificate verification and SRTP key export yourself.
Goals
- DTLS 1.2 and 1.3: Implements the DTLS handshake and record layer used by WebRTC.
- Safety:
forbid(unsafe_code)throughout the crate. - Minimal Rust‑only deps: Uses small, well‑maintained Rust crypto crates.
- Low overhead: Tight control over allocations and buffers; Sans‑IO integration.
Non‑goals
- DTLS 1.0
- Async (the crate is Sans‑IO and event‑loop agnostic)
- no_std (at least not without allocation)
- RSA
- DHE
Version selection
Three constructors control which DTLS version is used:
- [
Dtls::new_12] — explicit DTLS 1.2 - [
Dtls::new_13] — explicit DTLS 1.3 - [
Dtls::new_auto] — auto‑sense: the first incoming ClientHello determines the version (based on thesupported_versionsextension)
Cryptography surface
- Cipher suites (TLS 1.2 over DTLS)
ECDHE_ECDSA_AES256_GCM_SHA384ECDHE_ECDSA_AES128_GCM_SHA256
- Cipher suites (TLS 1.3 over DTLS)
TLS_AES_128_GCM_SHA256TLS_AES_256_GCM_SHA384
- AEAD: AES‑GCM 128/256 only (no CBC/EtM modes).
- Key exchange: ECDHE (P‑256/P‑384)
- Signatures: ECDSA P‑256/SHA‑256, ECDSA P‑384/SHA‑384
- DTLS‑SRTP: Exports keying material for
SRTP_AEAD_AES_256_GCM,SRTP_AEAD_AES_128_GCM, andSRTP_AES128_CM_SHA1_80(RFC 5764, RFC 7714). - Extended Master Secret (RFC 7627) is negotiated and enforced (DTLS 1.2).
- Not supported: PSK cipher suites.
Certificate model
During the handshake the engine emits [Output::PeerCert] with the peer's
leaf certificate (DER). The crate uses that certificate to verify DTLS
handshake messages, but it does not perform any PKI validation. Your
application is responsible for validating the peer certificate according to
your policy (fingerprint, chain building, name/EKU checks, pinning, etc.).
Sans‑IO integration model
Drive the engine with three calls:
Dtls::handle_packet— feed an entire received UDP datagram.Dtls::poll_output— drain pending output: DTLS records, timers, events.Dtls::handle_timeout— trigger retransmissions/time‑based progress.
The output is an [Output] enum with borrowed references into your provided buffer:
Packet(&[u8]): send on your UDP socketTimeout(Instant): schedule a timer and callhandle_timeoutat/after itConnected: handshake completePeerCert(&[u8]): peer leaf certificate (DER) — validate in your appKeyingMaterial(KeyingMaterial, SrtpProfile): DTLS‑SRTP exportApplicationData(&[u8]): plaintext received from peer
Example (Sans‑IO loop)
use Arc;
use Instant;
use ;
// Stub I/O to keep the example focused on the state machine
// Putting it together
let dtls = mk_dtls_client;
let _ = example_event_loop;
MSRV
Rust 1.81.0
Status
- Session resumption is not implemented (WebRTC does a full handshake on ICE restart).
- Renegotiation is not implemented (WebRTC does full restart).
License: MIT OR Apache-2.0