about summary refs log tree commit diff
path: root/tvix/nix-compat/src/narinfo/signature.rs
diff options
context:
space:
mode:
authorFlorian Klink <flokli@flokli.de>2023-11-19T17·02+0200
committerclbot <clbot@tvl.fyi>2023-11-19T21·58+0000
commita5749fada5c048093f0496ae23a5800e343b88be (patch)
tree0807ae9ecdaffcc9808ed26a2c3e35b9fc17d816 /tvix/nix-compat/src/narinfo/signature.rs
parent6039b97b559511858776d2750eeeb2ae0e6b7e77 (diff)
refactor(nix-compat/narinfo): move signature into separate file r/7040
Change-Id: Ic257475e2afebf059c5317c1cc5b04ba63d5d318
Reviewed-on: https://cl.tvl.fyi/c/depot/+/10078
Tested-by: BuildkiteCI
Autosubmit: flokli <flokli@flokli.de>
Reviewed-by: raitobezarius <tvl@lahfa.xyz>
Diffstat (limited to 'tvix/nix-compat/src/narinfo/signature.rs')
-rw-r--r--tvix/nix-compat/src/narinfo/signature.rs54
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 0000000000..5a7481591c
--- /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))
+    }
+}