coapcore/
error.rs

1/// Error type returned from various functions that ingest any input to an authentication or
2/// authorization step.
3#[derive(Debug)]
4pub struct CredentialError {
5    #[expect(
6        dead_code,
7        reason = "This is deliberately unused: The kind is merely a debug helper, and when no logging is active, code should not behave any different no matter in which way the credential processing failed"
8    )]
9    detail: CredentialErrorDetail,
10    pub(crate) position: Option<usize>,
11}
12
13/// Classification of a [`CredentialError`].
14///
15/// The variants in here are mainly used for debug output, and all signify *that*
16/// the processing of the token was not successful. This type can be used to
17/// construct a [`CredentialError`].
18#[derive(Debug, Copy, Clone)]
19#[non_exhaustive]
20pub enum CredentialErrorDetail {
21    /// Input data contains items that violate a protocol.
22    ///
23    /// This is somewhat fuzzy towards
24    /// [`UnsupportedExtension`][CredentialErrorDetail::UnsupportedExtension] if extension points
25    /// are not clearly documented or understood in a protocol.
26    ProtocolViolation,
27    /// Input data contains items that are understood in principle, but not supported by the
28    /// implementation.
29    ///
30    /// In the fuzziness towards [`ProtocolViolation`][CredentialErrorDetail::ProtocolViolation],
31    /// it is preferred to err on the side of `UnsupportedExtension`.
32    UnsupportedExtension,
33    /// Input data uses a COSE algorithm that is not supported by the implementation.
34    UnsupportedAlgorithm,
35    /// The data looks fine to a point, but exceeds the capacity of the implementation (data or
36    /// identifier too long).
37    ConstraintExceeded,
38    /// Input data is understood, but self-contradictory.
39    ///
40    /// Example: A COSE encrypted item where the nonce length does not match the algorithm's
41    /// requirements.
42    InconsistentDetails,
43    /// The peer expects to use key material which is not known to this system.
44    KeyNotPresent,
45    /// Data could be processed and keys were found, but cryptographic verification was
46    /// unsuccessful.
47    VerifyFailed,
48}
49
50impl From<CredentialErrorDetail> for CredentialError {
51    fn from(value: CredentialErrorDetail) -> Self {
52        Self {
53            detail: value,
54            position: None,
55        }
56    }
57}
58
59impl From<minicbor::decode::Error> for CredentialError {
60    fn from(_: minicbor::decode::Error) -> Self {
61        // FIXME: We could try to distinguish "extra field" (that tends to be UnsupportedExtension) from
62        // "wrong type" (that tends to be ProtocolViolation).
63        Self {
64            detail: CredentialErrorDetail::UnsupportedExtension,
65            position: None,
66        }
67    }
68}
69
70impl From<minicbor::encode::Error<minicbor_adapters::OutOfSpace>> for CredentialError {
71    fn from(_: minicbor::encode::Error<minicbor_adapters::OutOfSpace>) -> Self {
72        Self {
73            detail: CredentialErrorDetail::ConstraintExceeded,
74            position: None,
75        }
76    }
77}