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}