summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Breitmoser <look@my.amazin.horse>2023-12-28 12:51:27 +0100
committerVincent Breitmoser <look@my.amazin.horse>2023-12-28 12:54:04 +0100
commitd11de8a354ae13c27614241ee47012f1c47e7f53 (patch)
tree2fa9c853ba80bdf9b2722a3e5053eb51bc9f792e
parent1d1eedc319e4622d033070c94555752f00598fa2 (diff)
hagrid: don't panic on short token size
-rw-r--r--src/sealed_state.rs23
-rw-r--r--src/tokens.rs6
2 files changed, 22 insertions, 7 deletions
diff --git a/src/sealed_state.rs b/src/sealed_state.rs
index ec548c6..f4a358e 100644
--- a/src/sealed_state.rs
+++ b/src/sealed_state.rs
@@ -29,9 +29,13 @@ impl SealedState {
}
}
- pub fn unseal(&self, mut data: Vec<u8>) -> Result<String, &'static str> {
- let (nonce, sealed) = data.split_at_mut(NONCE_LEN);
- let unsealed = open_in_place(&self.opening_key, nonce, &[], 0, sealed)
+ pub fn unseal(&self, data: &[u8]) -> Result<String, &'static str> {
+ if data.len() < NONCE_LEN {
+ return Err("invalid sealed value: too short");
+ }
+ let (nonce, sealed) = data.split_at(NONCE_LEN);
+ let mut sealed_copy = sealed.to_vec();
+ let unsealed = open_in_place(&self.opening_key, nonce, &[], 0, &mut sealed_copy)
.map_err(|_| "invalid key/nonce/value: bad seal")?;
::std::str::from_utf8(unsealed)
@@ -67,8 +71,19 @@ mod tests {
let sv = SealedState::new("swag");
let sealed = sv.seal("test");
- let unsealed = sv.unseal(sealed).unwrap();
+ let unsealed = sv.unseal(sealed.as_slice()).unwrap();
assert_eq!("test", unsealed);
}
+
+ #[test]
+ fn too_short() {
+ let sv = SealedState::new("swag");
+
+ let sealed = sv.seal("test");
+ let sealed_short = &sealed[0..8];
+ let unsealed_error = sv.unseal(sealed_short);
+
+ assert_eq!(Err("invalid sealed value: too short"), unsealed_error);
+ }
}
diff --git a/src/tokens.rs b/src/tokens.rs
index c22d1b7..7dc756e 100644
--- a/src/tokens.rs
+++ b/src/tokens.rs
@@ -43,11 +43,11 @@ impl Service {
T: StatelessSerializable,
{
let token_sealed = base64::decode_config(&token_encoded, base64::URL_SAFE_NO_PAD)
- .map_err(|_| anyhow!("invalid b64"))?;
+ .map_err(|_| anyhow!("Invalid base64. Did you follow a correct link?"))?;
let token_str = self
.sealed_state
- .unseal(token_sealed)
- .map_err(|_| anyhow!("failed to validate"))?;
+ .unseal(token_sealed.as_slice())
+ .map_err(|_| anyhow!("Failed to validate. Did you follow a correct link?"))?;
let token: Token =
serde_json::from_str(&token_str).map_err(|_| anyhow!("failed to deserialize"))?;