diff options
Diffstat (limited to 'tvix/nix-compat/src/narinfo/signature.rs')
-rw-r--r-- | tvix/nix-compat/src/narinfo/signature.rs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/tvix/nix-compat/src/narinfo/signature.rs b/tvix/nix-compat/src/narinfo/signature.rs new file mode 100644 index 000000000000..5a7481591ce5 --- /dev/null +++ b/tvix/nix-compat/src/narinfo/signature.rs @@ -0,0 +1,54 @@ +use std::fmt::{self, Display}; + +use data_encoding::BASE64; + +#[derive(Debug)] +pub struct Signature<'a> { + name: &'a str, + bytes: [u8; 64], +} + +impl<'a> Signature<'a> { + pub fn parse(input: &'a str) -> Result<Signature<'a>, SignatureError> { + let (name, bytes64) = input + .split_once(':') + .ok_or(SignatureError::MissingSeparator)?; + + let mut buf = [0; 66]; + let mut bytes = [0; 64]; + match BASE64.decode_mut(bytes64.as_bytes(), &mut buf) { + Ok(64) => { + bytes.copy_from_slice(&buf[..64]); + } + Ok(n) => return Err(SignatureError::InvalidSignatureLen(n)), + // keeping DecodePartial gets annoying lifetime-wise + Err(_) => return Err(SignatureError::DecodeError(input.to_string())), + } + + Ok(Signature { name, bytes }) + } + + pub fn name(&self) -> &'a str { + self.name + } + + pub fn bytes(&self) -> &[u8; 64] { + &self.bytes + } +} + +#[derive(Debug, thiserror::Error)] +pub enum SignatureError { + #[error("Missing separator")] + MissingSeparator, + #[error("Invalid signature len: {0}")] + InvalidSignatureLen(usize), + #[error("Unable to base64-decode signature: {0}")] + DecodeError(String), +} + +impl Display for Signature<'_> { + fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { + write!(w, "{}:{}", self.name, BASE64.encode(&self.bytes)) + } +} |