# `Cmsex.Signer`
[🔗](https://github.com/openspb/cmsex/blob/v0.1.0/lib/cmsex/signer.ex#L1)

A signer for `Cmsex.sign/3`: a certificate, its private key, and how to
sign. `Cmsex.sign/3` also takes it as a plain map or keyword list with
the same fields, and turns it into this struct, whose `Inspect` leaves
the key out.

Fields:

  * `:certificate` - the certificate of the signer, in DER. Required.
  * `:key` - the private key, required: PKCS #8 in DER (such as the
    `private_key` of a PKCS #12 file), a key record of `:public_key`
    (`RSAPrivateKey`, `ECPrivateKey`, Ed25519 and Ed448 included, or a
    decoded `PrivateKeyInfo`), or a function, for a key that never
    leaves an HSM, a token or a KMS (see below).
  * `:chain` - more certificates in DER that go in the message with
    this signer's, such as its intermediates (`[]`).
  * `:digest` - `:sha256`, `:sha224`, `:sha384` or `:sha512`. The default
    is SHA-256; SHA-512 for Ed25519 (RFC 8419); the hash of the key for
    an RSASSA-PSS key with parameters; the hash of a ready digest given
    as the content. Ed448 always takes SHAKE256 (RFC 8419).
  * `:rsa_padding` - `:pkcs1` (PKCS #1 v1.5, the default) or `:pss`
    (RSASSA-PSS, with MGF1 of the same hash and a salt of the size of
    the hash).
  * `:identifier` - `:issuer_and_serial` (the default) or
    `:subject_key_identifier`, which needs that extension in the
    certificate.
  * `:signing_time` - `true` (now, the default), `false`, or a
    `DateTime`.
  * `:algorithm_protection` - the CMSAlgorithmProtection attribute
    (RFC 6211), which binds the algorithms to the signature (`true`).
  * `:signed_attributes` - more signed attributes, as `Cmsex.Attribute`
    structs, such as `Cmsex.Attribute.signing_certificate_v2/2` (`[]`).
    The content-type and message-digest attributes are always written
    by `Cmsex.sign/3`, and so are signing-time and CMSAlgorithmProtection
    unless turned off; none of them may be repeated here.
  * `:unsigned_attributes` - unsigned attributes, as `Cmsex.Attribute`
    structs (`[]`).
  * `:verify_signature` - with a function as the key, verify what it
    returns against the certificate before writing the message (`true`).

`:digest`, `:rsa_padding`, `:identifier`, `:signing_time` and
`:algorithm_protection` left out take the value of the option of the
same name of `Cmsex.sign/3`, or else the default.

## A key as a function

The function is called once per signature with a map:

  * `:tbs` - the bytes to sign.
  * `:hash` - the hash of the signature, or `nil` for EdDSA.
  * `:digest` - the hash of `:tbs` for RSA and ECDSA, which is what a
    KMS usually signs; `nil` for EdDSA, which signs `:tbs` itself.
  * `:scheme` - `:rsa_pkcs1`, `:rsa_pss`, `:ecdsa`, `:ed25519` or
    `:ed448`.
  * `:pss` - for RSASSA-PSS, `%{hash, mgf_hash, salt_length,
    trailer_field}`; `nil` otherwise.

It returns `{:ok, signature}` or `{:error, reason}`. An ECDSA signature
is the DER `Ecdsa-Sig-Value`; for RSA PKCS #1 v1.5 the function signs the
digest and builds the DigestInfo itself, as any KMS does. An error, or a
signature that does not verify, is `:signer_failed`.

# `key`

```elixir
@type key() :: binary() | tuple() | (map() -&gt; {:ok, binary()} | {:error, term()})
```

# `t`

```elixir
@type t() :: %Cmsex.Signer{
  algorithm_protection: boolean() | nil,
  certificate: binary(),
  chain: [binary()],
  digest: :sha224 | :sha256 | :sha384 | :sha512 | nil,
  identifier: :issuer_and_serial | :subject_key_identifier | nil,
  key: key(),
  rsa_padding: :pkcs1 | :pss | nil,
  signed_attributes: [Cmsex.Attribute.t()],
  signing_time: boolean() | DateTime.t() | nil,
  unsigned_attributes: [Cmsex.Attribute.t()],
  verify_signature: boolean()
}
```

# `new!`

```elixir
@spec new!(t() | map() | keyword()) :: t()
```

A signer from a map, a keyword list or a signer, with its fields
checked. A field that is unknown, missing, given twice or of the wrong
kind raises `ArgumentError`; whether the key and the certificate can be read is
checked by `Cmsex.sign/3`.

---

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