diff options
author | Florian Klink <flokli@flokli.de> | 2023-11-27T14·36+0200 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2023-11-27T15·12+0000 |
commit | b7de931cc6edd78b6c59ed97bf4485ae90c3de06 (patch) | |
tree | a635d71147fd39060dc03d64216a382a976e4ad4 /tvix/nix-compat/src | |
parent | dfaaf41cefe004eeb35f362cee3ba145bf0b9d35 (diff) |
fix(nix-compat/narinfo): don't panic trying to parse signatures r/7074
BASE64.decode_mut panics if we're passing data that has the wrong size. Do the size check first and error out there. Also update the error, and talk about b64-encoded sizes. Change-Id: I290f80a37d48526a30bf1df9d1d9fe34865008eb Reviewed-on: https://cl.tvl.fyi/c/depot/+/10146 Tested-by: BuildkiteCI Reviewed-by: edef <edef@edef.eu> Autosubmit: flokli <flokli@flokli.de>
Diffstat (limited to 'tvix/nix-compat/src')
-rw-r--r-- | tvix/nix-compat/src/narinfo/signature.rs | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/tvix/nix-compat/src/narinfo/signature.rs b/tvix/nix-compat/src/narinfo/signature.rs index 26e062a09eea..53e75c587353 100644 --- a/tvix/nix-compat/src/narinfo/signature.rs +++ b/tvix/nix-compat/src/narinfo/signature.rs @@ -20,13 +20,15 @@ impl<'a> Signature<'a> { .split_once(':') .ok_or(SignatureError::MissingSeparator)?; - let mut buf = [0; SIGNATURE_LENGTH + 2]; + if bytes64.len() != BASE64.encode_len(SIGNATURE_LENGTH) { + return Err(SignatureError::InvalidSignatureLen(bytes64.len())); + } + let mut bytes = [0; SIGNATURE_LENGTH]; + let mut buf = [0; SIGNATURE_LENGTH + 2]; match BASE64.decode_mut(bytes64.as_bytes(), &mut buf) { - Ok(SIGNATURE_LENGTH) => { - bytes.copy_from_slice(&buf[..SIGNATURE_LENGTH]); - } - Ok(n) => return Err(SignatureError::InvalidSignatureLen(n)), + Ok(SIGNATURE_LENGTH) => bytes.copy_from_slice(&buf[..SIGNATURE_LENGTH]), + Ok(_) => unreachable!(), // keeping DecodePartial gets annoying lifetime-wise Err(_) => return Err(SignatureError::DecodeError(input.to_string())), } @@ -54,7 +56,7 @@ impl<'a> Signature<'a> { pub enum SignatureError { #[error("Missing separator")] MissingSeparator, - #[error("Invalid signature len: {0}")] + #[error("Invalid signature len: (expected {} b64-encoded, got {}", BASE64.encode_len(SIGNATURE_LENGTH), .0)] InvalidSignatureLen(usize), #[error("Unable to base64-decode signature: {0}")] DecodeError(String), @@ -111,4 +113,9 @@ mod test { let sig = Signature::parse(sig_str).expect("must parse"); assert_eq!(expect_valid, sig.verify(fp.as_bytes(), verifying_key)); } + + #[test_case("cache.nixos.org-1:o1DTsjCz0PofLJ216P2RBuSulI8BAb6zHxWE4N+tzlcELk5Uk/GO2SCxWTRN5wJutLZZ+cHTMdWqOHF8"; "wrong_length")] + fn parse_fail(input: &'static str) { + Signature::parse(input).expect_err("must fail"); + } } |