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

Why a CMS message could not be read, verified, written or decrypted.

The functions of `Cmsex` return it as `{:error, %Cmsex.Error{}}`, and their
bang variants raise it. Match on `:reason`; `:signer` is the position of
the signer in the message (from 0) when the error belongs to one signer,
or a list of positions for a countersignature (`[0, 1]` is the second
countersignature of the first signer); `:recipient` is the position of
the recipient in the list given to `Cmsex.encrypt/3` when the error
belongs to one; `:detail` adds what went wrong where that helps, such as
the OID of an unknown algorithm, a tuple, which the message shows in
dotted form.

Reading:

  * `:malformed` - not valid BER, or not the structure that was expected.
  * `:invalid_pem` - no PEM block with a label this library reads, or
    invalid Base64.
  * `:unsupported_content_type` - a ContentInfo of a type the function
    does not handle; `detail` is its OID.
  * `:limit_exceeded` - the message goes beyond a limit; `detail` is the
    option, such as `:max_depth` or `:max_signers`.

Content:

  * `:no_signers` - the message has no signers (a certificate bundle).
  * `:content_required` - a detached message, or one that needs the whole
    content, was given without it.
  * `:unexpected_content` - content given for a message that carries its
    own.

Signers and algorithms:

  * `:signer_not_found` - no certificate matches the signer identifier.
  * `:unsupported_algorithm` - an algorithm this library does not
    implement; `detail` is its OID.
  * `:weak_algorithm` - SHA-1 without `allow_sha1: true`, or MD5.
  * `:weak_key` - an RSA key shorter than `:min_rsa_bits`.
  * `:algorithm_mismatch` - the algorithms of a signer do not agree with
    each other or with the CMSAlgorithmProtection attribute.
  * `:key_mismatch` - the key of the certificate is not of the kind the
    algorithm needs.

Attributes and signatures:

  * `:missing_attribute` - a required attribute is missing; `detail` is
    which.
  * `:invalid_attribute` - a malformed or repeated attribute, or one with
    the wrong number of values; `detail` is which.
  * `:content_type_mismatch` - the content-type attribute is not the type
    of the content.
  * `:digest_mismatch` - the message-digest attribute, or the digest of
    a DigestedData, is not the digest of the content.
  * `:invalid_signature` - the signature does not verify.
  * `:signing_certificate_mismatch` - the signing-certificate attribute
    names another certificate.
  * `:untrusted` - the certificate path did not validate; `detail` is the
    reason given by `:public_key`.

Writing:

  * `:invalid_key` - the private key cannot be read.
  * `:invalid_certificate` - a certificate cannot be read.
  * `:key_certificate_mismatch` - the private key is not the key of the
    certificate.
  * `:signer_failed` - the signing function returned an error, or a
    signature that does not verify.
  * `:invalid_recipient` - a recipient cannot be used for encryption;
    `detail` says why.

Decrypting and MACs:

  * `:recipient_not_found` - no recipient of the message matches the
    credentials that were given.
  * `:decryption_failed` - the message does not decrypt with that key, or
    it was changed. The library gives no other detail, on purpose.
  * `:not_available` - the algorithm is known, but the `:crypto`
    application of this system (its OpenSSL) refuses it, such as RC2
    without the OpenSSL "legacy" provider; `detail` is the algorithm.
  * `:invalid_mac` - the MAC of an AuthenticatedData does not check
    with the key of the recipient, or the key does not unwrap. As with
    `:decryption_failed`, nothing tells these apart.

An error never carries key material, passwords or the content.

# `reason`

```elixir
@type reason() ::
  :malformed
  | :invalid_pem
  | :unsupported_content_type
  | :limit_exceeded
  | :no_signers
  | :content_required
  | :unexpected_content
  | :signer_not_found
  | :unsupported_algorithm
  | :weak_algorithm
  | :weak_key
  | :algorithm_mismatch
  | :key_mismatch
  | :missing_attribute
  | :invalid_attribute
  | :content_type_mismatch
  | :digest_mismatch
  | :invalid_signature
  | :signing_certificate_mismatch
  | :untrusted
  | :invalid_key
  | :invalid_certificate
  | :key_certificate_mismatch
  | :signer_failed
  | :invalid_recipient
  | :recipient_not_found
  | :decryption_failed
  | :not_available
  | :invalid_mac
```

# `t`

```elixir
@type t() :: %Cmsex.Error{
  __exception__: true,
  detail: term(),
  reason: reason(),
  recipient: non_neg_integer() | nil,
  signer: non_neg_integer() | [non_neg_integer()] | nil
}
```

---

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