# `Sinetex.Certificate`
[🔗](https://github.com/openspb/sinetex/blob/v0.1.0/lib/sinetex/certificate.ex#L1)

An X.509 certificate as seen by the protocol: its serial number (C11/C13),
its certification authority code (C10/C12) and its RSA public key.

Load the counterparty's certificate with `load/2`. Your own certificate is
loaded together with its private key by `Sinetex.Identity.load/3`.

## Certification authority code (PC)

Fields C10 and C12 carry the code of the certification authority ("PC")
that issued the certificate (§5.1, Table 1):

| Code | PC |
|---:|---|
| `0x01` | SPB-Serpro |
| `0x02` | SPB-Certisign |
| `0x03` | Pessoas Físicas (STR-WEB only) |
| `0x04` | SPB-Serasa |
| `0x05` | SPB-CAIXA |
| `0x06` | SPB-Valid |
| `0x07` | SPB-Soluti |

SPB-style certificates carry `OU=CSPB-n` in their issuer (§4.2.6), where
`n` is the code, and `load/2` derives the code from it. Certificates without
it need the `:pc` option; otherwise loading fails with
`{:error, :pc_code_required}`. An explicit `:pc` always wins over the
derived code. The library never guesses the code from the issuer's name.

## Checks on load

  * RSA key of exactly 2048 bits (§4.4.16), which also means that the most
    significant bit of the modulus is set (§4.2.8);
  * public exponent other than 3 (§4.2.7);
  * serial number of at most 16 bytes, so that it fits C11/C13.

# `load_error`

```elixir
@type load_error() ::
  :invalid_certificate
  | :not_rsa
  | {:unsupported_key_size, pos_integer()}
  | {:invalid_public_exponent, integer()}
  | :serial_too_long
  | :invalid_serial
  | :pc_code_required
```

# `pc`

```elixir
@type pc() :: 1..255
```

A certification authority code, as written in C10/C12.

# `t`

```elixir
@type t() :: %Sinetex.Certificate{
  der: binary(),
  issuer: String.t(),
  key_bits: 2048,
  not_after: DateTime.t() | nil,
  not_before: DateTime.t() | nil,
  pc: pc(),
  public_key: :public_key.rsa_public_key(),
  serial: non_neg_integer(),
  serial_field: &lt;&lt;_::256&gt;&gt;,
  subject: String.t()
}
```

# `load`

```elixir
@spec load(binary(), keyword()) :: {:ok, t()} | {:error, load_error()}
```

Loads a certificate from PEM or DER.

## Options

  * `:pc` - the certification authority code (1..255) to write in C10/C12.
    Required when the issuer has no `OU=CSPB-n`.

## Examples

    {:ok, peer} = Sinetex.Certificate.load(File.read!("peer.pem"))
    {:ok, chamber} = Sinetex.Certificate.load(File.read!("chamber.pem"), pc: 0x04)

---

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