From 3057f1bc95733727f5a6c1134c70f9998fdc8cbb Mon Sep 17 00:00:00 2001 From: Alex Page Date: Mon, 19 Jun 2023 02:49:46 -0400 Subject: [PATCH] Fix bink1998 verify --- src/bink1998.rs | 15 ++++++--------- src/key.rs | 8 ++++---- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/bink1998.rs b/src/bink1998.rs index 3c1061b..1cee8a1 100644 --- a/src/bink1998.rs +++ b/src/bink1998.rs @@ -6,7 +6,7 @@ use openssl::{ sha::sha1, }; -use crate::{key::unbase24, FIELD_BYTES}; +use crate::{key::base24_decode, FIELD_BYTES}; #[derive(Clone, Copy, Debug)] struct ProductKey { @@ -24,11 +24,7 @@ pub fn verify( ) -> Result { let mut num_context = BigNumContext::new()?; - let p_raw = unbase24(p_key); - for byte in &p_raw { - print!("{:02X}, ", *byte); - } - println!(); + let p_raw = base24_decode(p_key); let product_key = unpack(&p_raw)?; let p_data = product_key.serial << 1 | product_key.upgrade as u32; @@ -63,7 +59,7 @@ pub fn verify( let msg_digest = sha1(&msg_buffer); - let hash: u32 = u32::from_be_bytes(msg_digest[0..4].try_into().unwrap()) & ((1 << 28) - 1); + let hash: u32 = u32::from_le_bytes(msg_digest[0..4].try_into().unwrap()) >> 4 & ((1 << 28) - 1); Ok(hash == product_key.hash) } @@ -82,11 +78,12 @@ pub fn generate( fn unpack(p_raw: &[u8]) -> Result { const HASH_LENGTH_BITS: u8 = 28; const SERIAL_LENGTH_BITS: u8 = 30; + const UPGRADE_LENGTH_BITS: u8 = 1; + const EVERYTHING_ELSE: u8 = HASH_LENGTH_BITS + SERIAL_LENGTH_BITS + UPGRADE_LENGTH_BITS; let mut reader = BitReader::new(p_raw); // The signature length is unknown, but everything else is, so we can calculate it - let signature_length_bits = - (p_raw.len() * 8) as u8 - (HASH_LENGTH_BITS + SERIAL_LENGTH_BITS + 1); + let signature_length_bits = (p_raw.len() * 8) as u8 - EVERYTHING_ELSE; let p_signature = reader.read_u64(signature_length_bits)?; let p_hash = reader.read_u32(HASH_LENGTH_BITS)?; diff --git a/src/key.rs b/src/key.rs index 583dce8..193acbc 100644 --- a/src/key.rs +++ b/src/key.rs @@ -9,7 +9,7 @@ const P_CHARSET: [char; 24] = [ const PK_LENGTH: usize = 25; -pub fn unbase24(cd_key: &str) -> Vec { +pub fn base24_decode(cd_key: &str) -> Vec { let p_decoded_key: Vec = cd_key .chars() .filter_map(|c| P_CHARSET.iter().position(|&x| x == c).map(|i| i as u8)) @@ -25,7 +25,7 @@ pub fn unbase24(cd_key: &str) -> Vec { y.to_vec() } -pub fn base24(byte_seq: &[u8]) -> String { +pub fn base24_encode(byte_seq: &[u8]) -> String { let mut z = BigNum::from_slice(byte_seq).unwrap(); let mut out: VecDeque = VecDeque::new(); (0..=24).for_each(|_| out.push_front(P_CHARSET[z.div_word(24).unwrap() as usize])); @@ -37,9 +37,9 @@ mod tests { #[test] fn test_base24() { let input = "JTW3TJ7PFJ7V9CCMX84V9PFT8"; - let unbase24 = super::unbase24(input); + let unbase24 = super::base24_decode(input); println!("{:?}", unbase24); - let base24 = super::base24(&unbase24); + let base24 = super::base24_encode(&unbase24); println!("{}", base24); assert_eq!(input, base24); }