diff options
author | Vincent Breitmoser <look@my.amazin.horse> | 2023-12-28 12:51:27 +0100 |
---|---|---|
committer | Vincent Breitmoser <look@my.amazin.horse> | 2023-12-28 12:54:04 +0100 |
commit | d11de8a354ae13c27614241ee47012f1c47e7f53 (patch) | |
tree | 2fa9c853ba80bdf9b2722a3e5053eb51bc9f792e | |
parent | 1d1eedc319e4622d033070c94555752f00598fa2 (diff) |
hagrid: don't panic on short token size
-rw-r--r-- | src/sealed_state.rs | 23 | ||||
-rw-r--r-- | src/tokens.rs | 6 |
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"))?; |