Cmsex.Signer (cmsex v0.1.0)

Copy Markdown View Source

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.

Summary

Functions

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.

Types

key()

@type key() :: binary() | tuple() | (map() -> {:ok, binary()} | {:error, term()})

t()

@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()
}

Functions

new!(signer)

@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.