about summary refs log tree commit diff
path: root/tvix/nix-compat/src/narinfo/public_keys.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/nix-compat/src/narinfo/public_keys.rs')
-rw-r--r--tvix/nix-compat/src/narinfo/public_keys.rs149
1 files changed, 0 insertions, 149 deletions
diff --git a/tvix/nix-compat/src/narinfo/public_keys.rs b/tvix/nix-compat/src/narinfo/public_keys.rs
deleted file mode 100644
index ced05cadb133..000000000000
--- a/tvix/nix-compat/src/narinfo/public_keys.rs
+++ /dev/null
@@ -1,149 +0,0 @@
-//! This module defines data structures and parsers for the public key format
-//! used inside Nix to verify signatures on .narinfo files.
-
-use std::fmt::Display;
-
-use data_encoding::BASE64;
-use ed25519_dalek::{VerifyingKey, PUBLIC_KEY_LENGTH};
-
-use super::Signature;
-
-/// This represents a ed25519 public key and "name".
-/// These are normally passed in the `trusted-public-keys` Nix config option,
-/// and consist of a name and base64-encoded ed25519 pubkey, separated by a `:`.
-#[derive(Debug)]
-pub struct PubKey {
-    name: String,
-    verifying_key: VerifyingKey,
-}
-
-impl PubKey {
-    pub fn new(name: String, verifying_key: VerifyingKey) -> Self {
-        Self {
-            name,
-            verifying_key,
-        }
-    }
-
-    pub fn parse(input: &str) -> Result<Self, Error> {
-        let (name, bytes64) = input.split_once(':').ok_or(Error::MissingSeparator)?;
-
-        if name.is_empty()
-            || !name
-                .chars()
-                .all(|c| char::is_alphanumeric(c) || c == '-' || c == '.')
-        {
-            return Err(Error::InvalidName(name.to_string()));
-        }
-
-        if bytes64.len() != BASE64.encode_len(PUBLIC_KEY_LENGTH) {
-            return Err(Error::InvalidPubKeyLen(bytes64.len()));
-        }
-
-        let mut buf = [0; PUBLIC_KEY_LENGTH + 1];
-        let mut bytes = [0; PUBLIC_KEY_LENGTH];
-        match BASE64.decode_mut(bytes64.as_bytes(), &mut buf) {
-            Ok(PUBLIC_KEY_LENGTH) => {
-                bytes.copy_from_slice(&buf[..PUBLIC_KEY_LENGTH]);
-            }
-            Ok(_) => unreachable!(),
-            // keeping DecodePartial gets annoying lifetime-wise
-            Err(_) => return Err(Error::DecodeError(input.to_string())),
-        }
-
-        let verifying_key = VerifyingKey::from_bytes(&bytes).map_err(Error::InvalidVerifyingKey)?;
-
-        Ok(Self {
-            name: name.to_string(),
-            verifying_key,
-        })
-    }
-
-    pub fn name(&self) -> &str {
-        &self.name
-    }
-
-    /// Verify the passed in signature is a correct signature for the passed in fingerprint and is signed
-    /// by the key material referred to by [Self],
-    /// which means the name in the signature has to match,
-    /// and the signature bytes themselves need to be a valid signature made by
-    /// the signing key identified by [Self::verifying key].
-    pub fn verify(&self, fingerprint: &str, signature: &Signature) -> bool {
-        if self.name() != signature.name() {
-            return false;
-        }
-
-        return signature.verify(fingerprint.as_bytes(), &self.verifying_key);
-    }
-}
-
-#[derive(Debug, thiserror::Error)]
-pub enum Error {
-    #[error("Invalid name: {0}")]
-    InvalidName(String),
-    #[error("Missing separator")]
-    MissingSeparator,
-    #[error("Invalid pubkey len: {0}")]
-    InvalidPubKeyLen(usize),
-    #[error("VerifyingKey error: {0}")]
-    InvalidVerifyingKey(ed25519_dalek::SignatureError),
-    #[error("Unable to base64-decode pubkey: {0}")]
-    DecodeError(String),
-}
-
-impl Display for PubKey {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(
-            f,
-            "{}:{}",
-            self.name,
-            BASE64.encode(self.verifying_key.as_bytes())
-        )
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use data_encoding::BASE64;
-    use ed25519_dalek::PUBLIC_KEY_LENGTH;
-    use test_case::test_case;
-
-    use crate::narinfo::Signature;
-
-    use super::PubKey;
-    const FINGERPRINT: &str = "1;/nix/store/syd87l2rxw8cbsxmxl853h0r6pdwhwjr-curl-7.82.0-bin;sha256:1b4sb93wp679q4zx9k1ignby1yna3z7c4c2ri3wphylbc2dwsys0;196040;/nix/store/0jqd0rlxzra1rs38rdxl43yh6rxchgc6-curl-7.82.0,/nix/store/6w8g7njm4mck5dmjxws0z1xnrxvl81xa-glibc-2.34-115,/nix/store/j5jxw3iy7bbz4a57fh9g2xm2gxmyal8h-zlib-1.2.12,/nix/store/yxvjs9drzsphm9pcf42a4byzj1kb9m7k-openssl-1.1.1n";
-
-    #[test_case("cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=", "cache.nixos.org-1", BASE64.decode(b"6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=").unwrap()[..].try_into().unwrap(); "cache.nixos.org")]
-    #[test_case("cheesecake:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=", "cheesecake", BASE64.decode(b"6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=").unwrap()[..].try_into().unwrap(); "cache.nixos.org different name")]
-    #[test_case("test1:tLAEn+EeaBUJYqEpTd2yeerr7Ic6+0vWe+aXL/vYUpE=", "test1", BASE64.decode(b"tLAEn+EeaBUJYqEpTd2yeerr7Ic6+0vWe+aXL/vYUpE=").unwrap()[..].try_into().unwrap(); "test-1")]
-    fn parse(
-        input: &'static str,
-        exp_name: &'static str,
-        exp_verifying_key_bytes: &[u8; PUBLIC_KEY_LENGTH],
-    ) {
-        let pubkey = PubKey::parse(input).expect("must parse");
-        assert_eq!(exp_name, pubkey.name());
-        assert_eq!(exp_verifying_key_bytes, pubkey.verifying_key.as_bytes());
-    }
-
-    #[test_case("6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="; "empty name")]
-    #[test_case("cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY"; "missing padding")]
-    #[test_case("cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDS"; "wrong length")]
-    fn parse_fail(input: &'static str) {
-        PubKey::parse(input).expect_err("must fail");
-    }
-
-    #[test_case("cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=", FINGERPRINT, "cache.nixos.org-1:TsTTb3WGTZKphvYdBHXwo6weVILmTytUjLB+vcX89fOjjRicCHmKA4RCPMVLkj6TMJ4GMX3HPVWRdD1hkeKZBQ==", true; "correct cache.nixos.org")]
-    #[test_case("cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=", FINGERPRINT, "cache.nixos.org:TsTTb3WGTZKphvYdBHXwo6weVILmTytUjLB+vcX89fOjjRicCHmKA4RCPMVLkj6TMJ4GMX3HPVWRdD1hkeKZBQ==", false; "wrong name mismatch")]
-    fn verify(
-        pubkey_str: &'static str,
-        fingerprint: &'static str,
-        signature_str: &'static str,
-        expected: bool,
-    ) {
-        let pubkey = PubKey::parse(pubkey_str).expect("must parse");
-        let signature = Signature::parse(signature_str).expect("must parse");
-
-        assert_eq!(expected, pubkey.verify(fingerprint, &signature));
-    }
-}