use crate::errors::GetCookieError;
use aes;
use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, KeyIvInit};
use cbc;
use keyring;
use ring::pbkdf2;
use std::num::NonZeroU32;
const CREDENTIALS_LEN: usize = 16;
type Credential = [u8; CREDENTIALS_LEN];
type Aes128Cbc = cbc::Decryptor<aes::Aes128Dec>;
fn get_chrome_key() -> Result<Credential, GetCookieError> {
let keyring = keyring::Entry::new("Chrome Safe Storage", "Chrome");
let key = keyring.get_password()?;
let mut derived_key = [0u8; CREDENTIALS_LEN];
pbkdf2::derive(
pbkdf2::PBKDF2_HMAC_SHA1,
NonZeroU32::new(1003u32).unwrap(),
"saltysalt".as_bytes(),
key.as_bytes(),
&mut derived_key,
);
return Ok(derived_key);
}
pub fn decrypt_encrypted_cookie(mut cookie: Vec<u8>) -> Result<String, GetCookieError> {
let (signature, data) = cookie.split_at_mut(3);
if std::str::from_utf8(signature) != Ok("v10") {
return Err(GetCookieError::InvalidCookieFormat);
}
let key = get_chrome_key()?;
let iv = [0x20u8; CREDENTIALS_LEN];
let cypher = Aes128Cbc::new(&key.into(), &iv.into());
let output = cypher
.decrypt_padded_mut::<Pkcs7>(data)
.map_err(|_| GetCookieError::DecryptionError)?;
return String::from_utf8(output.into()).map_err(|_| GetCookieError::DecryptionError);
}