feat(nix-compat/narinfo): add PubKey::verify(fp, sig)
This makes it easy for each PubKey to check if a given Signature is correct for a given fingerprint. Change-Id: I56e6211d133f74f390fd1ae3ae799eef12221904 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10151 Reviewed-by: tazjin <tazjin@tvl.su> Autosubmit: flokli <flokli@flokli.de> Tested-by: BuildkiteCI
This commit is contained in:
		
							parent
							
								
									6af67af76e
								
							
						
					
					
						commit
						5fc737b02e
					
				
					 1 changed files with 32 additions and 0 deletions
				
			
		| 
						 | 
					@ -6,6 +6,8 @@ use std::fmt::Display;
 | 
				
			||||||
use data_encoding::BASE64;
 | 
					use data_encoding::BASE64;
 | 
				
			||||||
use ed25519_dalek::{VerifyingKey, PUBLIC_KEY_LENGTH};
 | 
					use ed25519_dalek::{VerifyingKey, PUBLIC_KEY_LENGTH};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use super::Signature;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// This represents a ed25519 public key and "name".
 | 
					/// This represents a ed25519 public key and "name".
 | 
				
			||||||
/// These are normally passed in the `trusted-public-keys` Nix config option,
 | 
					/// 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 `:`.
 | 
					/// and consist of a name and base64-encoded ed25519 pubkey, separated by a `:`.
 | 
				
			||||||
| 
						 | 
					@ -60,6 +62,19 @@ impl PubKey {
 | 
				
			||||||
    pub fn name(&self) -> &str {
 | 
					    pub fn name(&self) -> &str {
 | 
				
			||||||
        &self.name
 | 
					        &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)]
 | 
					#[derive(Debug, thiserror::Error)]
 | 
				
			||||||
| 
						 | 
					@ -93,7 +108,10 @@ mod test {
 | 
				
			||||||
    use ed25519_dalek::PUBLIC_KEY_LENGTH;
 | 
					    use ed25519_dalek::PUBLIC_KEY_LENGTH;
 | 
				
			||||||
    use test_case::test_case;
 | 
					    use test_case::test_case;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use crate::narinfo::Signature;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    use super::PubKey;
 | 
					    use super::PubKey;
 | 
				
			||||||
 | 
					    const FINGERPRINT: &'static 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("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("cheesecake:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=", "cheesecake", BASE64.decode(b"6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=").unwrap()[..].try_into().unwrap(); "cache.nixos.org different name")]
 | 
				
			||||||
| 
						 | 
					@ -114,4 +132,18 @@ mod test {
 | 
				
			||||||
    fn parse_fail(input: &'static str) {
 | 
					    fn parse_fail(input: &'static str) {
 | 
				
			||||||
        PubKey::parse(input).expect_err("must fail");
 | 
					        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));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue