mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 19:04:07 +00:00
Handle AES key parsing outside of pak
This commit is contained in:
parent
6c2fe4dfb7
commit
d62915ec16
8 changed files with 29 additions and 20 deletions
|
@ -18,3 +18,4 @@ aes = "0.8"
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
hashbrown = "0.13"
|
hashbrown = "0.13"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
base64 = "0.21.0"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
pub fn list(path: String, key: String) -> Result<(), unpak::Error> {
|
pub fn list(path: String, key: Option<String>) -> Result<(), unpak::Error> {
|
||||||
for file in super::load_pak(path, key)?.files() {
|
for file in super::load_pak(path, key)?.files() {
|
||||||
println!("{file}");
|
println!("{file}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,27 @@ pub use {list::list, unpack::unpack, version::version};
|
||||||
|
|
||||||
fn load_pak(
|
fn load_pak(
|
||||||
path: String,
|
path: String,
|
||||||
key: String,
|
key: Option<String>,
|
||||||
) -> Result<unpak::Pak<std::io::BufReader<std::fs::File>>, unpak::Error> {
|
) -> Result<unpak::Pak<std::io::BufReader<std::fs::File>>, unpak::Error> {
|
||||||
|
use aes::cipher::KeyInit;
|
||||||
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
|
let key = key
|
||||||
|
.map(|k| {
|
||||||
|
general_purpose::STANDARD
|
||||||
|
.decode(k)
|
||||||
|
.as_ref()
|
||||||
|
.map_err(|_| unpak::Error::Base64)
|
||||||
|
.and_then(|bytes| {
|
||||||
|
aes::Aes256Dec::new_from_slice(bytes).map_err(|_| unpak::Error::Aes)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.transpose()?;
|
||||||
|
|
||||||
for ver in unpak::Version::iter() {
|
for ver in unpak::Version::iter() {
|
||||||
match unpak::Pak::new(
|
match unpak::Pak::new(
|
||||||
std::io::BufReader::new(std::fs::OpenOptions::new().read(true).open(&path)?),
|
std::io::BufReader::new(std::fs::OpenOptions::new().read(true).open(&path)?),
|
||||||
ver,
|
ver,
|
||||||
match key.as_bytes() {
|
key.clone(),
|
||||||
&[] => None,
|
|
||||||
key => Some(key),
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
Ok(pak) => {
|
Ok(pak) => {
|
||||||
return Ok(pak);
|
return Ok(pak);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
pub fn unpack(path: String, key: String) -> Result<(), unpak::Error> {
|
pub fn unpack(path: String, key: Option<String>) -> Result<(), unpak::Error> {
|
||||||
let folder = std::path::Path::new(
|
let folder = std::path::Path::new(
|
||||||
std::path::Path::new(&path)
|
std::path::Path::new(&path)
|
||||||
.file_stem()
|
.file_stem()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
pub fn version(path: String, key: String) -> Result<(), unpak::Error> {
|
pub fn version(path: String, key: Option<String>) -> Result<(), unpak::Error> {
|
||||||
println!("{}", super::load_pak(path, key)?.version());
|
println!("{}", super::load_pak(path, key)?.version());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ fn main() {
|
||||||
};
|
};
|
||||||
// can't map key to &[u8] because refers to owned data
|
// can't map key to &[u8] because refers to owned data
|
||||||
if let Err(e) = match args.next().unwrap_or_default().as_str() {
|
if let Err(e) = match args.next().unwrap_or_default().as_str() {
|
||||||
"version" => subcommands::version(path, args.next().unwrap_or_default()),
|
"version" => subcommands::version(path, args.next()),
|
||||||
"list" => subcommands::list(path, args.next().unwrap_or_default()),
|
"list" => subcommands::list(path, args.next()),
|
||||||
"unpack" | "" => subcommands::unpack(path, args.next().unwrap_or_default()),
|
"unpack" | "" => subcommands::unpack(path, args.next()),
|
||||||
"help" | _ => help(),
|
"help" | _ => help(),
|
||||||
} {
|
} {
|
||||||
eprintln!("{e}")
|
eprintln!("{e}")
|
||||||
|
|
|
@ -5,6 +5,8 @@ pub enum Error {
|
||||||
Strum(#[from] strum::ParseError),
|
Strum(#[from] strum::ParseError),
|
||||||
#[error("key hash is an incorrect length")]
|
#[error("key hash is an incorrect length")]
|
||||||
Aes,
|
Aes,
|
||||||
|
#[error("malformed base64")]
|
||||||
|
Base64,
|
||||||
// std errors
|
// std errors
|
||||||
#[error("io error: {0}")]
|
#[error("io error: {0}")]
|
||||||
Io(#[from] std::io::Error),
|
Io(#[from] std::io::Error),
|
||||||
|
|
13
src/pak.rs
13
src/pak.rs
|
@ -14,7 +14,7 @@ impl<R: io::Read + io::Seek> Pak<R> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
mut reader: R,
|
mut reader: R,
|
||||||
version: super::Version,
|
version: super::Version,
|
||||||
key_hash: Option<&[u8]>,
|
key: Option<aes::Aes256Dec>,
|
||||||
) -> Result<Self, super::Error> {
|
) -> Result<Self, super::Error> {
|
||||||
use super::ext::ReadExt;
|
use super::ext::ReadExt;
|
||||||
use byteorder::{ReadBytesExt, LE};
|
use byteorder::{ReadBytesExt, LE};
|
||||||
|
@ -24,20 +24,15 @@ impl<R: io::Read + io::Seek> Pak<R> {
|
||||||
// read index to get all the entry info
|
// read index to get all the entry info
|
||||||
reader.seek(io::SeekFrom::Start(footer.index_offset))?;
|
reader.seek(io::SeekFrom::Start(footer.index_offset))?;
|
||||||
let mut index = reader.read_len(footer.index_size as usize)?;
|
let mut index = reader.read_len(footer.index_size as usize)?;
|
||||||
let mut key = None;
|
|
||||||
// decrypt index if needed
|
// decrypt index if needed
|
||||||
if footer.encrypted {
|
if footer.encrypted {
|
||||||
let Some(hash) = key_hash else {
|
let Some(key) = &key else {
|
||||||
return Err(super::Error::Encrypted);
|
return Err(super::Error::Encrypted);
|
||||||
};
|
};
|
||||||
use aes::cipher::{BlockDecrypt, KeyInit};
|
use aes::cipher::BlockDecrypt;
|
||||||
let Ok(decrypter)= aes::Aes256Dec::new_from_slice(hash) else {
|
|
||||||
return Err(super::Error::Aes)
|
|
||||||
};
|
|
||||||
for chunk in index.chunks_mut(16) {
|
for chunk in index.chunks_mut(16) {
|
||||||
decrypter.decrypt_block(aes::Block::from_mut_slice(chunk))
|
key.decrypt_block(aes::Block::from_mut_slice(chunk))
|
||||||
}
|
}
|
||||||
key = Some(decrypter);
|
|
||||||
}
|
}
|
||||||
let mut index = io::Cursor::new(index);
|
let mut index = io::Cursor::new(index);
|
||||||
let mount_point = index.read_string()?;
|
let mount_point = index.read_string()?;
|
||||||
|
|
Loading…
Reference in a new issue