use std::io::{Read, Write}; use bytemuck::{bytes_of, Pod, Zeroable}; use chrono::{Datelike, Timelike}; use hmac::Hmac; use md5::{Digest, Md5}; use rc4::{Rc4, Rc4Core, StreamCipher}; use rc4::cipher::StreamCipherCoreWrapper; use rc4::consts::U16; use hmac::Mac; use rc4::KeyInit; use crate::rmc::structures::RmcSerialize; type Md5Hmac = Hmac; pub fn derive_key(pid: u32, password: [u8; 16]) -> [u8; 16]{ let iteration_count = 65000 + pid%1024; let mut key = password; for _ in 0..iteration_count { let mut md5 = Md5::new(); md5.update(key); key = md5.finalize().try_into().unwrap(); } key } #[derive(Pod, Zeroable, Copy, Clone)] #[repr(transparent)] pub struct KerberosDateTime(u64); impl KerberosDateTime{ pub fn new(second: u64, minute: u64, hour: u64, day: u64, month: u64, year:u64 ) -> Self { Self(second | (minute << 6) | (hour << 12) | (day << 17) | (month << 22) | (year << 26)) } pub fn now() -> Self{ let now = chrono::Utc::now(); Self::new( now.second() as u64, now.minute() as u64, now.hour() as u64, now.day() as u64, now.month() as u64, now.year() as u64, ) } } #[derive(Pod, Zeroable, Copy, Clone)] #[repr(C, packed)] pub struct TicketInternalData{ issued_time: KerberosDateTime, pub pid: u32, pub session_key: [u8; 32], } impl TicketInternalData{ pub(crate) fn new(pid: u32) -> Self{ Self{ issued_time: KerberosDateTime::now(), pid, session_key: rand::random() } } pub(crate) fn encrypt(&self, key: [u8; 16]) -> Box<[u8]>{ let mut data = bytes_of(self).to_vec(); let mut rc4: StreamCipherCoreWrapper> = Rc4::new_from_slice(&key).unwrap(); rc4.apply_keystream(&mut data); let mut hmac = ::new_from_slice(&key).unwrap(); hmac.write_all(&data[..]).expect("failed to write data to hmac"); let hmac_result = &hmac.finalize().into_bytes()[..]; data.write_all(&hmac_result).expect("failed to write data to vec"); data.into_boxed_slice() } } #[derive(Pod, Zeroable, Copy, Clone)] #[repr(C, packed)] pub struct Ticket{ pub session_key: [u8; 32], pub pid: u32, } impl Ticket{ pub(crate) fn encrypt(&self, key: [u8; 16], internal_data: &[u8]) -> Box<[u8]>{ let mut data = bytes_of(self).to_vec(); internal_data.serialize(&mut data).expect("unable to write to vec"); let mut rc4: StreamCipherCoreWrapper> = Rc4::new_from_slice(&key).unwrap(); rc4.apply_keystream(&mut data); let mut hmac = ::new_from_slice(&key).unwrap(); hmac.write_all(&data[..]).expect("failed to write data to hmac"); let hmac_result = &hmac.finalize().into_bytes()[..]; data.write_all(&hmac_result).expect("failed to write data to vec"); data.into_boxed_slice() } }