XGW.DTLS.SrtpKeys (xgw v0.1.0)

Copy Markdown View Source

Turns a finished DTLS handshake into the keys SRTP needs for media.

Plain-language flow

After DTLS succeeds, TLS has a shared secret but media packets still use a different encryption format called SRTP (Secure Real-time Transport Protocol). RFC 5764 defines how to export a fixed-length blob of keying material from DTLS and split it into client/server write keys and salts.

This module:

  1. Calls OTP :ssl.export_key_materials/4 with the DTLS-SRTP extractor label.
  2. Parses the 60-byte layout into {client_key, client_salt, server_key, server_salt}.
  3. Leaves HMAC key derivation to XMediaLib.Srtp (SRTP KDF).

OTP expects the Contexts argument as a list (for example [:no_context]), not a bare atom -- a common footgun when calling the exporter by hand.

RFCs

  • RFC 5764 -- DTLS-SRTP key export (EXTRACTOR-dtls_srtp) and key/salt layout
  • RFC 3711 -- SRTP (consumes the exported material via SRTP KDF)

Summary

Types

Parsed DTLS-SRTP keying material (client and server write pairs).

Functions

Exports and parses DTLS-SRTP keying material from a connected DTLS socket.

Like export/1, but rescues unexpected errors and returns {:error, exception}.

Parses exported key material (RFC 5764: 60-byte master keys and salts).

Types

keys()

@type keys() ::
  {client_key :: binary(), client_salt :: binary(), server_key :: binary(),
   server_salt :: binary()}

Parsed DTLS-SRTP keying material (client and server write pairs).

Functions

export(ssl_sock)

@spec export(:ssl.sslsocket()) :: {:ok, keys()} | {:error, term()}

Exports and parses DTLS-SRTP keying material from a connected DTLS socket.

export_safe(ssl_sock)

@spec export_safe(:ssl.sslsocket()) :: {:ok, keys()} | {:error, term()}

Like export/1, but rescues unexpected errors and returns {:error, exception}.

parse_materials(materials)

@spec parse_materials(binary()) :: {:ok, keys()} | :error

Parses exported key material (RFC 5764: 60-byte master keys and salts).

Extra exporter bytes are ignored. HMAC keys are derived by SRTP KDF, not this split.

Examples

iex> blob = :crypto.strong_rand_bytes(60)
iex> {:ok, {ck, cs, sk, ss}} = XGW.DTLS.SrtpKeys.parse_materials(blob)
iex> {byte_size(ck), byte_size(cs), byte_size(sk), byte_size(ss)}
{16, 14, 16, 14}

iex> XGW.DTLS.SrtpKeys.parse_materials(<<1, 2, 3>>)
:error