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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use std::{num, str, string};
/// Represents all of the errors that can arise when creating, deserializing, or verifying macaroons.
#[derive(Debug)]
pub enum MacaroonError {
/// Represents a runtime error in the lower-level cryptographic library, or situations like
/// zero-length ciphertext.
CryptoError(&'static str),
/// Can occur when constructing or deserializing a [`Macaroon`](crate::Macaroon) and expected fields are not present.
IncompleteMacaroon(&'static str),
/// Can occur when constructing or deserializing [`Caveat`](crate::Caveat) and expected fields are not present.
IncompleteCaveat(&'static str),
/// Represents a broad category of issues when parsing a macaroon token in any format.
DeserializationError(String),
/// Arises when verifying a [`Macaroon`](crate::Macaroon), when it has any caveat not
/// satisfied by any "exact" or "general" satisfiers configured on the
/// [`Verifier`](crate::Verifier). Indicates a failure to authenticate the macaroon.
CaveatNotSatisfied(String),
/// Arises when verifying a [`Macaroon`](crate::Macaroon), with a set of discharges configured
/// on the verifier, and one or more are not used during the verification process. Indicates a
/// failure to authenticate the macaroon.
DischargeNotUsed,
/// Arises when verifying a [`Macaroon`](crate::Macaroon), and the signature does not match
/// what is expected. Indicates a failure to authenticate the macaroon.
InvalidSignature,
/// Arises when adding a caveat to a [`Macaroon`](crate::Macaroon), or when
/// deserializing a token, would exceed the maximum allowed number of
/// caveats. Protects against memory exhaustion from pathological inputs.
TooManyCaveats,
/// Arises when a field (identifier, location, predicate, third-party caveat
/// id) would exceed [`MAX_FIELD_SIZE_BYTES`](crate::MAX_FIELD_SIZE_BYTES).
/// Applied on construction and deserialization so producer and consumer
/// agree: a macaroon that this crate serializes can always be parsed back.
FieldTooLarge {
/// The name of the field that was too large (e.g. `"identifier"`,
/// `"predicate"`).
field: &'static str,
/// The actual size, in bytes.
size: usize,
},
/// The operating system (or JavaScript `crypto.getRandomValues`) failed to
/// provide random bytes. Surfaces from
/// [`MacaroonKey::generate_random`](crate::MacaroonKey::generate_random)
/// and [`Macaroon::add_third_party_caveat`](crate::Macaroon::add_third_party_caveat).
RngError(&'static str),
}
#[cfg(feature = "v2json")]
impl From<serde_json::Error> for MacaroonError {
fn from(error: serde_json::Error) -> MacaroonError {
MacaroonError::DeserializationError(format!("{}", error))
}
}
impl From<string::FromUtf8Error> for MacaroonError {
fn from(error: string::FromUtf8Error) -> MacaroonError {
MacaroonError::DeserializationError(format!("{}", error))
}
}
impl From<base64::DecodeError> for MacaroonError {
fn from(error: base64::DecodeError) -> MacaroonError {
MacaroonError::DeserializationError(format!("{}", error))
}
}
impl From<num::ParseIntError> for MacaroonError {
fn from(error: num::ParseIntError) -> MacaroonError {
MacaroonError::DeserializationError(format!("{}", error))
}
}
impl From<str::Utf8Error> for MacaroonError {
fn from(error: str::Utf8Error) -> MacaroonError {
MacaroonError::DeserializationError(format!("{}", error))
}
}
impl std::error::Error for MacaroonError {}
impl std::fmt::Display for MacaroonError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
MacaroonError::CryptoError(s) => write!(
f,
"Error performing lower-level cryptographic function: {}",
s
),
MacaroonError::IncompleteMacaroon(s) => {
write!(f, "Macaroon was missing required field: {}", s)
}
MacaroonError::IncompleteCaveat(s) => {
write!(f, "Caveat was missing required field: {}", s)
}
MacaroonError::DeserializationError(s) => {
write!(f, "Failed to deserialize macaroon: {}", s)
}
MacaroonError::CaveatNotSatisfied(s) => write!(
f,
"Macaroon failed to verify because one or more caveats were not satisfied: {}",
s
),
MacaroonError::DischargeNotUsed => write!(
f,
"Macaroon failed to verify because one or more discharges were not used"
),
MacaroonError::InvalidSignature => write!(
f,
"Macaroon failed to verify because signature did not match"
),
MacaroonError::TooManyCaveats => write!(
f,
"Macaroon exceeds the maximum allowed number of caveats ({})",
crate::MAX_CAVEATS
),
MacaroonError::FieldTooLarge { field, size } => write!(
f,
"Macaroon field `{}` is {} bytes, exceeds the maximum of {} bytes",
field,
size,
crate::MAX_FIELD_SIZE_BYTES
),
MacaroonError::RngError(s) => {
write!(f, "Failed to obtain random bytes from the OS RNG: {}", s)
}
}
}
}