glow_control_lib/util/
auth.rs

1use crate::util::rc4::Rc4;
2use anyhow::Result;
3use rand::RngCore;
4use sha1::Digest;
5use sha1::Sha1;
6
7const SHARED_KEY_CHALLENGE: &[u8] = b"evenmoresecret!!";
8pub struct Auth;
9
10impl Auth {
11    pub fn make_challenge_response(challenge: &[u8], mac_address: &str) -> Result<String> {
12        let derived_key = Self::derive_key(SHARED_KEY_CHALLENGE, mac_address);
13        let mut rc4_cipher = Rc4::new(&derived_key);
14        let mut encrypted_challenge = challenge.to_vec();
15        rc4_cipher.apply_keystream(&mut encrypted_challenge);
16
17        let mut hasher = Sha1::new();
18        hasher.update(&encrypted_challenge);
19        let result = hasher.finalize();
20
21        Ok(hex::encode(result))
22    }
23
24    // Helper function to convert a MAC address string to bytes
25    pub fn mac_to_bytes(mac: &str) -> Vec<u8> {
26        mac.split(':')
27            .map(|part| u8::from_str_radix(part, 16).unwrap())
28            .collect()
29    }
30
31    // Function to derive the key from the shared key and MAC address
32    pub fn derive_key(shared_key: &[u8], mac_address: &str) -> Vec<u8> {
33        let mac_bytes = Self::mac_to_bytes(mac_address);
34        let mut derived_key = Vec::new();
35        for (i, &byte) in shared_key.iter().enumerate() {
36            derived_key.push(byte ^ mac_bytes[i % mac_bytes.len()]);
37        }
38        derived_key
39    }
40
41    pub fn generate_challenge() -> Vec<u8> {
42        let mut challenge = vec![0u8; 32];
43        rand::thread_rng().fill_bytes(&mut challenge);
44        challenge
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn test_generate_challenge() {
54        let challenge = Auth::generate_challenge();
55        assert_eq!(challenge.len(), 32);
56    }
57}