# ol.clave.certificate.impl.x509

X.509 encoding utilities for certificates and CSRs.

We don’t implement all of X.509 (lol), we implement just enough to:
- generate CSRs
- generate TLS-ALPN-01 challenge certificates

Provides:
- IDNA encoding for internationalized domain names in SANs
- GeneralName encoding for Subject Alternative Names
- Extension encoding for certificate extensions

## idna-encode

```clojure
(idna-encode domain)
```

Convert Unicode domain to ASCII (Punycode) using IDNA.

Normalizes to lowercase first, then applies IDNA conversion.
Throws ex-info with ::errors/invalid-idna on failure.

[source,window=_blank](https://github.com/outskirtslabs/clave/blob/main/src/ol/clave/certificate/impl/x509.clj#L22-L36)

---

## encode-extension

```clojure
(encode-extension oid critical? value)
```

Encode a single X.509 extension.

Arguments:
  oid       - OID string (e.g., "2.5.29.17" for subjectAltName)
  critical? - Boolean indicating if extension is critical
  value     - DER-encoded extension value bytes

Returns DER-encoded extension SEQUENCE.

[source,window=_blank](https://github.com/outskirtslabs/clave/blob/main/src/ol/clave/certificate/impl/x509.clj#L38-L53)

---

## encode-dns-general-name

```clojure
(encode-dns-general-name domain)
```

Encode DNS GeneralName (context tag 2).

Applies IDNA encoding to the domain before encoding.
Returns DER-encoded GeneralName for DNS identifier.

[source,window=_blank](https://github.com/outskirtslabs/clave/blob/main/src/ol/clave/certificate/impl/x509.clj#L55-L62)

---

## encode-ip-general-name

```clojure
(encode-ip-general-name ip-bytes)
```

Encode IP GeneralName (context tag 7) from raw bytes.

Arguments:
  ip-bytes - Raw IP address bytes (4 bytes for IPv4, 16 bytes for IPv6)

Returns DER-encoded GeneralName for IP identifier.

[source,window=_blank](https://github.com/outskirtslabs/clave/blob/main/src/ol/clave/certificate/impl/x509.clj#L64-L72)
