# `XGW.Certs`
[🔗](https://github.com/Lazarus404/xgw/blob/main/lib/xgw/certs.ex#L1)

Creates and fingerprints the TLS certificate used for DTLS.

## Why certificates matter here

Before media is encrypted with SRTP, the two peers run a **DTLS** handshake
(TLS over UDP). Each side presents a certificate. In WebRTC the certificate
is usually **self-signed**; trust comes from comparing its SHA-256 fingerprint
to the value advertised in SDP (`a=fingerprint:`), not from a public CA.

This module:

- Generates a self-signed cert/key pair with `openssl` when missing (`ensure!/1`).
- Computes the colon-separated uppercase hex fingerprint browsers expect.
- Checks that a remote SDP fingerprint matches a DER certificate.

## RFCs

* RFC 8122 -- SDP `a=fingerprint` attribute (certificate digests)
* RFC 9147 / RFC 6347 -- DTLS (certificate presented during handshake)

# `ensure!`

```elixir
@spec ensure!(Path.t()) :: {Path.t(), Path.t()}
```

Returns `{certfile, keyfile}` paths, generating a self-signed pair when missing.

# `fingerprint`

```elixir
@spec fingerprint(Path.t()) :: String.t()
```

SHA-256 fingerprint as colon-separated uppercase hex for SDP.

# `fingerprint_der`

```elixir
@spec fingerprint_der(binary()) :: String.t()
```

SHA-256 fingerprint as colon-separated uppercase hex from DER bytes.

## Examples

    iex> der = :crypto.hash(:sha256, "test")
    iex> fp = XGW.Certs.fingerprint_der(der)
    iex> String.match?(fp, ~r/^[0-9A-F]{2}(:[0-9A-F]{2}){31}$/)
    true

# `fingerprint_matches?`

```elixir
@spec fingerprint_matches?(XMediaLib.SDP.Fingerprint.t(), binary()) :: boolean()
```

Returns true when `der` matches an SDP `%Fingerprint{}` (sha-256 only for v1).

## Examples

    iex> der = "cert-bytes"
    iex> fp = XGW.Certs.fingerprint_der(der)
    iex> XGW.Certs.fingerprint_matches?(%{algorithm: "sha-256", value: fp}, der)
    true

    iex> XGW.Certs.fingerprint_matches?(%{algorithm: "sha-1", value: "x"}, <<>>)
    false

---

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