diff --git a/src/anonymize.rs b/src/anonymize.rs index f3d985d..67d5c3f 100644 --- a/src/anonymize.rs +++ b/src/anonymize.rs @@ -53,7 +53,7 @@ impl Anonymizer { Self { encrypter, padding } } - pub fn anonymize(&mut self, addr: IpAddr) -> IpAddr { + pub fn anonymize(&self, addr: IpAddr) -> IpAddr { let (addr_int, version) = match addr { IpAddr::V4(ipv4) => (u128::from(u32::from(ipv4)), 4), IpAddr::V6(ipv6) => (u128::from(ipv6), 6), @@ -76,7 +76,7 @@ impl Anonymizer { /// /// [`anonymize()`]: CryptoPAn::anonymize() #[allow(dead_code)] - pub(crate) fn anonymize_str(&mut self, addr: &str) -> IpAddr { + pub(crate) fn anonymize_str(&self, addr: &str) -> IpAddr { // FIX: panicking convenience method is considered unidiomatic // | we should decide whether ergonomic is so important or not // | (O) -> make this method `pub` @@ -87,7 +87,7 @@ impl Anonymizer { self.anonymize(addr) } - fn anonymize_bin(&mut self, addr: u128, version: u8) -> u128 { + fn anonymize_bin(&self, addr: u128, version: u8) -> u128 { // REFACTOR: add `anonymize_bytes()`, accepting any `&[u8; N]` where N <= 16 let (pos_max, ext_addr) = match version { 4 => (32, addr << 96), diff --git a/src/backends/openssl.rs b/src/backends/openssl.rs index 83d14e6..9788921 100644 --- a/src/backends/openssl.rs +++ b/src/backends/openssl.rs @@ -12,7 +12,7 @@ pub struct Aes128Enc { } impl Aes128Enc { - fn from_key(key: &[u8; 16]) -> Result { + pub fn new(key: &[u8; 16]) -> Result { let mut crypter = Crypter::new( Cipher::aes_128_ecb(), Mode::Encrypt, @@ -46,11 +46,12 @@ impl Aes128Enc { impl Encrypter for Aes128Enc { fn from_key(key: &[u8; 16]) -> Self { - Self::from_key(key).expect("https://github.com/SkuldNorniern/cryptoPAn-rs/issues/7") + Self::new(key).expect("https://github.com/SkuldNorniern/cryptoPAn-rs/issues/7") } fn encrypt(&self, input: &[u8; 16]) -> [u8; 16] { - self.encrypt(input).expect("https://github.com/SkuldNorniern/cryptoPAn-rs/issues/7") + self.encrypt(input) + .expect("https://github.com/SkuldNorniern/cryptoPAn-rs/issues/7") } } @@ -62,25 +63,32 @@ mod tests { // The encryption key and sample data are from the C++ reference implementation. // https://web.archive.org/web/20180908092841/https://www.cc.gatech.edu/computing/Telecomm/projects/cryptopan/ - const KEY: &[u8; 32] = b"\ + const ENC_KEY: &[u8; 16] = b"\ \x15\x22\x17\x8d\x33\xa4\xcf\x80\ \x13\x0a\x5b\x16\x49\x90\x7d\x10\ + "; + + const PAD_KEY: &[u8; 16] = b"\ \xd8\x98\x8f\x83\x79\x79\x65\x27\ \x62\x57\x4c\x2d\x2a\x84\x22\x02\ "; - fn run_test_cases(cases: &[(&str, &str)]) { - let mut pancake: Anonymizer = Anonymizer::new(KEY); + fn run_test_cases(cases: &[(&str, &str)]) -> Result<(), ErrorStack> { + let encrypter = Aes128Enc::new(ENC_KEY)?; + let pancake = Anonymizer::with_encrypter(encrypter, PAD_KEY); + for (addr, expected) in cases { let anonymized = pancake.anonymize_str(addr); let expected: IpAddr = expected.parse().unwrap(); assert_eq!(anonymized, expected); } + + Ok(()) } #[test] - fn test_anonymize_ipv4_full() { - let cases = [ + fn test_anonymize_ipv4_full() -> Result<(), ErrorStack> { + run_test_cases(&[ ("128.11.68.132", "135.242.180.132"), ("129.118.74.4", "134.136.186.123"), ("130.132.252.244", "133.68.164.234"), @@ -151,21 +159,17 @@ mod tests { ("64.14.118.196", "0.255.183.58"), ("64.34.154.117", "0.221.154.117"), ("64.39.15.238", "0.219.7.41"), - ]; - - run_test_cases(&cases) + ]) } #[test] - fn test_anonymize_ipv6_partial() { - let cases = [ + fn test_anonymize_ipv6_partial() -> Result<(), ErrorStack> { + run_test_cases(&[ ("::1", "78ff:f001:9fc0:20df:8380:b1f1:704:ed"), ("::2", "78ff:f001:9fc0:20df:8380:b1f1:704:ef"), ("::ffff", "78ff:f001:9fc0:20df:8380:b1f1:704:f838"), ("2001:db8::1", "4401:2bc:603f:d91d:27f:ff8e:e6f1:dc1e"), ("2001:db8::2", "4401:2bc:603f:d91d:27f:ff8e:e6f1:dc1c"), - ]; - - run_test_cases(&cases) + ]) } }