# `XGW.DTLS.SrtpKeys`
[🔗](https://github.com/Lazarus404/xgw/blob/main/lib/xgw/dtls/srtp_keys.ex#L1)

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)

# `keys`

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

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

# `export`

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

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

# `export_safe`

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

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

# `parse_materials`

```elixir
@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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
