From d6d345207530ec3232d937aeee3b0c9255b33129 Mon Sep 17 00:00:00 2001 From: Andreas Grois Date: Sun, 9 Oct 2022 14:00:38 +0200 Subject: Also add url_parsing to this crate. --- src/passwordmaker/hmac.rs | 58 +++++++++++++++++++++++++++++++++++++++++ src/passwordmaker/mod.rs | 66 ++++------------------------------------------- 2 files changed, 63 insertions(+), 61 deletions(-) create mode 100644 src/passwordmaker/hmac.rs (limited to 'src/passwordmaker') diff --git a/src/passwordmaker/hmac.rs b/src/passwordmaker/hmac.rs new file mode 100644 index 0000000..4c9d6aa --- /dev/null +++ b/src/passwordmaker/hmac.rs @@ -0,0 +1,58 @@ +use crate::Hasher; + +pub(super) fn hmac(key : K, data : M) -> T::Output + where T : Hasher, + T::Output : AsRef<[u8]>, + K : Iterator + Clone, + M : Iterator, +{ + let key_len = key.clone().count(); + let key = if key_len > 64 { + KeyOrHash::from_hash(T::hash(&key.collect::>())) + } else { + KeyOrHash::from_key(key) + }; + let key = key.chain(std::iter::repeat(0)); //if key[i] does not exist, use 0 instead. + + let mut inner_pad = [0u8;64]; + let mut outer_pad = [0u8;64]; + + let pads = inner_pad.iter_mut().zip(outer_pad.iter_mut()); + for ((i,o),k) in pads.zip(key) { + *i = k ^ 0x36; + *o = k ^ 0x5C; + } + + let hash = T::hash(&inner_pad.iter().copied().chain(data).collect::>()); + T::hash(&outer_pad.iter().chain(hash.as_ref().iter()).copied().collect::>()) +} + +enum KeyOrHash, H: AsRef<[u8]>> { + Key(K), + Hash{ + hash : H, + idx : usize + } +} + +impl, H: AsRef<[u8]>> KeyOrHash{ + fn from_key(key : K) -> Self { + Self::Key(key) + } + fn from_hash(hash : H) -> Self { + Self::Hash { hash, idx: 0 } + } +} + +impl, H: AsRef<[u8]>> Iterator for KeyOrHash{ + type Item = u8; + fn next(&mut self) -> Option { + match self { + KeyOrHash::Key(k) => k.next(), + KeyOrHash::Hash { hash: owned, idx } => { + *idx += 1; + owned.as_ref().get(*idx-1).copied() + }, + } + } +} \ No newline at end of file diff --git a/src/passwordmaker/mod.rs b/src/passwordmaker/mod.rs index 4874758..eb39c9e 100644 --- a/src/passwordmaker/mod.rs +++ b/src/passwordmaker/mod.rs @@ -10,6 +10,7 @@ use super::Hasher; mod remainders; mod remainders_impl; mod grapheme; +mod hmac; pub(crate) mod leet; impl<'y, H : super::HasherList> super::PasswordMaker<'y, H>{ @@ -18,8 +19,8 @@ impl<'y, H : super::HasherList> super::PasswordMaker<'y, H>{ } pub(super) fn generate_password_verified_input(self) -> String { - let modified_data = self.data.to_owned() + self.username + self.modifier; - let key = self.key.to_owned(); + let modified_data = self.data + self.username + self.modifier; + let key = self.key; let get_modified_key = move |i : usize| { if i == 0 {key.clone()} else {key.clone() + "\n" + &i.to_string()}}; //In Passwordmaker Pro, leet is applied on a per-password-part basis. This means that if a password part ends in an upper-case Sigma, @@ -111,7 +112,7 @@ impl<'y, H : super::HasherList> super::PasswordMaker<'y, H>{ let data = leetified_data.as_deref().unwrap_or(data); let key = yeet_upper_bytes(&key); let data = yeet_upper_bytes(data); - let hash = hmac::(key, data); + let hash = hmac::hmac::(key, data); let hash_as_integer = u128::from_be_bytes(hash); let grapheme_indices : Vec<_> = hash_as_integer.calc_remainders(characters.len() as u128).map(|llll| llll as usize).collect(); let grapheme_indices = yoink_additional_graphemes_for_06_if_needed(grapheme_indices); @@ -225,7 +226,7 @@ fn modern_hmac_to_grapheme_indices(key : &str, data: &str, to_ { let key = yeet_upper_bytes(key); let data = yeet_upper_bytes(data); - to_dividend(hmac::(key, data)).calc_remainders(divisor).map(to_usize).collect() + to_dividend(hmac::hmac::(key, data)).calc_remainders(divisor).map(to_usize).collect() } fn modern_message_to_grapheme_indices(data: &str, to_dividend : F, divisor : D, to_usize : U) -> Vec @@ -353,61 +354,4 @@ fn yeet_upper_bytes(input : &str) -> impl Iterator + Clone + '_ { fn yoink_additional_graphemes_for_06_if_needed(mut input : Vec) -> Vec { input.resize(32, 0); input -} - -fn hmac(key : K, data : M) -> T::Output - where T : Hasher, - T::Output : AsRef<[u8]>, - K : Iterator + Clone, - M : Iterator, -{ - let key_len = key.clone().count(); - let key = if key_len > 64 { - KeyOrHash::from_hash(T::hash(&key.collect::>())) - } else { - KeyOrHash::from_key(key) - }; - let key = key.chain(std::iter::repeat(0)); //if key[i] does not exist, use 0 instead. - - let mut inner_pad = [0u8;64]; - let mut outer_pad = [0u8;64]; - - let pads = inner_pad.iter_mut().zip(outer_pad.iter_mut()); - for ((i,o),k) in pads.zip(key) { - *i = k ^ 0x36; - *o = k ^ 0x5C; - } - - let hash = T::hash(&inner_pad.iter().copied().chain(data).collect::>()); - T::hash(&outer_pad.iter().chain(hash.as_ref().iter()).copied().collect::>()) -} - -enum KeyOrHash, H: AsRef<[u8]>> { - Key(K), - Hash{ - hash : H, - idx : usize - } -} - -impl, H: AsRef<[u8]>> KeyOrHash{ - fn from_key(key : K) -> Self { - Self::Key(key) - } - fn from_hash(hash : H) -> Self { - Self::Hash { hash, idx: 0 } - } -} - -impl, H: AsRef<[u8]>> Iterator for KeyOrHash{ - type Item = u8; - fn next(&mut self) -> Option { - match self { - KeyOrHash::Key(k) => k.next(), - KeyOrHash::Hash { hash: owned, idx } => { - *idx += 1; - owned.as_ref().get(*idx-1).copied() - }, - } - } } \ No newline at end of file -- cgit v1.2.3