# `Sat.Certificados.Credential`

Credencial SAT: certificado (`.cer`) y llave privada (`.key`) asociados.

# `t`

```elixir
@type t() :: %Sat.Certificados.Credential{
  certificate: Sat.Certificados.Certificate.t(),
  private_key: Sat.Certificados.PrivateKey.t()
}
```

# `belongs_to?`

```elixir
@spec belongs_to?(t(), String.t()) :: boolean()
```

`true` si el RFC del certificado coincide (case insensitive) con `rfc`.

# `create`

```elixir
@spec create(String.t(), String.t(), String.t() | nil) ::
  {:ok, t()} | {:error, term()}
```

Carga certificado y llave desde rutas de archivo.

# `from_pem`

```elixir
@spec from_pem(String.t(), String.t()) :: {:ok, t()} | {:error, term()}
```

Crea una credencial a partir de strings PEM (cer y key sin cifrar).

# `is_csd?`

```elixir
@spec is_csd?(t()) :: boolean()
```

Ver `Sat.Certificados.Certificate.is_csd?/1`.

# `is_fiel?`

```elixir
@spec is_fiel?(t()) :: boolean()
```

Ver `Sat.Certificados.Certificate.is_fiel?/1`.

# `key_matches_certificate?`

```elixir
@spec key_matches_certificate?(t()) :: boolean()
```

`true` si la llave privada corresponde al certificado de la credencial.

# `legal_name`

```elixir
@spec legal_name(t()) :: String.t()
```

Nombre legal del titular.

# `no_certificado`

```elixir
@spec no_certificado(t()) :: String.t()
```

Número de certificado SAT.

# `rfc`

```elixir
@spec rfc(t()) :: String.t()
```

RFC del titular (desde el certificado).

# `serial_number`

```elixir
@spec serial_number(t()) :: String.t()
```

Número de serie del certificado (hex).

# `sign`

```elixir
@spec sign(t(), iodata(), atom()) :: String.t()
```

Firma datos con la llave privada (SHA-256 por defecto, Base64).

# `to_map`

```elixir
@spec to_map(t()) :: map()
```

Proyecta la credencial a un mapa con metadata del certificado anidada y
flags de la credencial.

La llave privada NO se incluye en el mapa (es PII; usar
`PrivateKey.sign/3` o `Credential.sign/3` para firmar sin extraerla).

Opciones:
  * `:keys` — `:atom` (default), `:string` o `:existing`. Misma semántica
    que `CFDI.to_map/2`. Se propaga al certificado anidado.

# `to_map`

```elixir
@spec to_map(
  t(),
  keyword()
) :: map()
```

# `valid?`

```elixir
@spec valid?(t()) :: boolean()
```

`true` si el certificado no está vencido.

# `verify`

```elixir
@spec verify(t(), iodata(), String.t(), atom()) :: boolean()
```

Verifica una firma Base64 contra `data` usando la llave pública del certificado.

---

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