coapcore/
error.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/// Error type returned from various functions that ingest any input to an authentication or
/// authorization step.
#[derive(Debug)]
pub struct CredentialError {
    #[expect(
        dead_code,
        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"
    )]
    detail: CredentialErrorDetail,
    pub(crate) position: Option<usize>,
}

#[derive(Debug, Copy, Clone)]
#[non_exhaustive]
pub(crate) enum CredentialErrorDetail {
    /// Input data contains items that violate a protocol.
    ///
    /// This is somewhat fuzzy towards [`UnsupportedExtension`] if extension points are not clearly
    /// documented or understood in a protocol.
    ProtocolViolation,
    /// Input data contains items that are understood in principle, but not supported by the
    /// implementation.
    ///
    /// In the fuzziness towards [`ProtocolViolation`], it is preferred to err on the side of
    /// `UnsupportedExtension`.
    UnsupportedExtension,
    /// Input data uses a COSE algorithm that is not supported by the implementation.
    UnsupportedAlgorithm,
    /// The data looks fine to a point, but exceeds the capacity of the implementation (data or
    /// identifier too long).
    ConstraintExceeded,
    /// Input data is understood, but self-contradictory.
    ///
    /// Example: A COSE encrypted item where the nonce length does not match the algorithm's
    /// requirements.
    InconsistentDetails,
    /// The peer expects to use key material which is not known to this system.
    KeyNotPresent,
    /// Data could be processed and keys were found, but cryptographic verification was
    /// unsuccessful.
    VerifyFailed,
}

impl From<CredentialErrorDetail> for CredentialError {
    fn from(value: CredentialErrorDetail) -> Self {
        Self {
            detail: value,
            position: None,
        }
    }
}

impl From<minicbor::decode::Error> for CredentialError {
    fn from(_: minicbor::decode::Error) -> Self {
        // FIXME: We could try to distinguish "extra field" (that tends to be UnsupportedExtension) from
        // "wrong type" (that tends to be ProtocolViolation).
        Self {
            detail: CredentialErrorDetail::UnsupportedExtension,
            position: None,
        }
    }
}

impl From<minicbor::encode::Error<minicbor_adapters::OutOfSpace>> for CredentialError {
    fn from(_: minicbor::encode::Error<minicbor_adapters::OutOfSpace>) -> Self {
        Self {
            detail: CredentialErrorDetail::ConstraintExceeded,
            position: None,
        }
    }
}