kumo_dkim/
errors.rs

1use dns_resolver::DnsError;
2use thiserror::Error;
3
4/// DKIM error status
5#[derive(Debug, Copy, Clone, Eq, PartialEq)]
6pub enum Status {
7    Permfail,
8    Tempfail,
9}
10
11#[derive(Debug, PartialEq, Clone, Error)]
12/// DKIM errors
13pub enum DKIMError {
14    #[error("unsupported hash algorithm: {0}")]
15    UnsupportedHashAlgorithm(String),
16    #[error("unsupported canonicalization: {0}")]
17    UnsupportedCanonicalizationType(String),
18    #[error("signature syntax error: {0}")]
19    SignatureSyntaxError(String),
20    #[error("signature missing required tag ({0})")]
21    SignatureMissingRequiredTag(&'static str),
22    #[error("incompatible version")]
23    IncompatibleVersion,
24    #[error("domain mismatch")]
25    DomainMismatch,
26    #[error("From field not signed")]
27    FromFieldNotSigned,
28    #[error("signature expired")]
29    SignatureExpired,
30    #[error("unacceptable signature header")]
31    UnacceptableSignatureHeader,
32    #[error("unsupported query method")]
33    UnsupportedQueryMethod,
34    #[error("key unavailable: {0}")]
35    KeyUnavailable(String),
36    #[error("internal error: {0}")]
37    UnknownInternalError(String),
38    #[error("no key for signature")]
39    NoKeyForSignature,
40    #[error("key syntax error")]
41    KeySyntaxError,
42    #[error("key incompatible version")]
43    KeyIncompatibleVersion,
44    #[error("inappropriate key algorithm")]
45    InappropriateKeyAlgorithm,
46    #[error("signature did not verify")]
47    SignatureDidNotVerify,
48    #[error("body hash did not verify")]
49    BodyHashDidNotVerify,
50    #[error("malformed email body")]
51    MalformedBody,
52    #[error("failed sign: {0}")]
53    FailedToSign(String),
54    #[error("failed to build object: {0}")]
55    BuilderError(&'static str),
56    #[error("failed to serialize DKIM header: {0}")]
57    HeaderSerializeError(String),
58    #[error("failed to load private key: {0}")]
59    PrivateKeyLoadError(String),
60    #[error("failed to parse message: {0:#}")]
61    MailParsingError(#[from] mailparsing::MailParsingError),
62    #[error("Canonical CRLF line endings are required for correct signing and verification")]
63    CanonicalLineEndingsRequired,
64    #[error(transparent)]
65    Dns(#[from] DnsError),
66    #[error("ARC instance tag is invalid")]
67    InvalidARCInstance,
68    #[error("ARC Set Instance {0} has duplicate headers")]
69    DuplicateARCInstance(u8),
70    #[error("ARC Set Instance {0} has missing headers")]
71    MissingARCInstance(u8),
72}
73
74impl DKIMError {
75    pub fn status(self) -> Status {
76        use DKIMError::*;
77        match self {
78            SignatureSyntaxError(_)
79            | SignatureMissingRequiredTag(_)
80            | IncompatibleVersion
81            | DomainMismatch
82            | FromFieldNotSigned
83            | SignatureExpired
84            | UnacceptableSignatureHeader
85            | UnsupportedQueryMethod
86            | NoKeyForSignature
87            | KeySyntaxError
88            | KeyIncompatibleVersion
89            | InappropriateKeyAlgorithm
90            | SignatureDidNotVerify
91            | BodyHashDidNotVerify
92            | MalformedBody
93            | CanonicalLineEndingsRequired
94            | InvalidARCInstance
95            | DuplicateARCInstance(_)
96            | MissingARCInstance(_)
97            | MailParsingError(_)
98            | UnsupportedCanonicalizationType(_)
99            | UnsupportedHashAlgorithm(_) => Status::Permfail,
100            KeyUnavailable(_)
101            | UnknownInternalError(_)
102            | BuilderError(_)
103            | FailedToSign(_)
104            | PrivateKeyLoadError(_)
105            | HeaderSerializeError(_) => Status::Tempfail,
106            Dns(dns) => match dns {
107                DnsError::InvalidName(_) => Status::Permfail,
108                DnsError::ResolveFailed(_) => Status::Tempfail,
109            },
110        }
111    }
112}