add encryption support

This commit is contained in:
spuds 2023-01-13 12:12:39 +00:00
parent 07bbbbc5ed
commit c440ca6707
No known key found for this signature in database
GPG key ID: 0B6CA6068E827C8F
5 changed files with 23 additions and 2 deletions

View file

@ -11,6 +11,7 @@ edition = "2021"
[dependencies]
byteorder = "*"
strum = { version = "*", features = ["derive"] }
aes = "*"
hashbrown = "*"
thiserror = "*"

View file

@ -2,6 +2,7 @@ fn main() -> Result<(), un_pak::Error> {
let pak = un_pak::Pak::new(
std::io::BufReader::new(std::io::Cursor::new(include_bytes!("rando_p.pak"))),
un_pak::Version::CompressionEncryption,
None,
)?;
for file in pak.entries.keys() {
println!("{file}")

View file

@ -5,6 +5,7 @@ fn main() -> Result<(), un_pak::Error> {
match un_pak::Pak::new(
std::io::BufReader::new(std::fs::OpenOptions::new().read(true).open(&path)?),
ver,
None,
) {
Ok(un_pak::Pak { version, .. }) | Err(un_pak::Error::Version { version, .. }) => {
println!("{}", version);

View file

@ -1,9 +1,13 @@
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("io error: {0}")]
Io(#[from] std::io::Error),
// dependency errors
#[error("enum conversion: {0}")]
Strum(#[from] strum::ParseError),
#[error("key hash is an incorrect length")]
Aes,
// std errors
#[error("io error: {0}")]
Io(#[from] std::io::Error),
#[error("utf8 conversion: {0}")]
Utf8(#[from] std::string::FromUtf8Error),
#[error("utf16 conversion: {0}")]
@ -11,6 +15,7 @@ pub enum Error {
#[error("bufwriter dereference: {0}")]
IntoInner(#[from] std::io::IntoInnerError<std::io::BufWriter<Vec<u8>>>),
#[error("found magic of {0:#x} instead of {:#x}", super::MAGIC)]
// crate errors
Magic(u32),
#[error("used version {used} but pak is version {version}")]
Version {

View file

@ -1,6 +1,7 @@
use std::io;
use super::ReadExt;
use aes::cipher::{BlockDecrypt, KeyInit};
use byteorder::{ReadBytesExt, LE};
use super::Version;
@ -17,10 +18,22 @@ impl Pak {
pub fn new<R: io::Read + io::Seek>(
mut reader: R,
version: super::Version,
key: Option<&[u8]>,
) -> Result<Self, super::Error> {
reader.seek(io::SeekFrom::End(-version.size()))?;
let footer = super::Footer::new(&mut reader, version)?;
reader.seek(io::SeekFrom::Start(footer.offset))?;
let mut index = reader.read_len(footer.size as usize)?;
if let Some(key) = key {
match aes::Aes256Dec::new_from_slice(key) {
Ok(key) => {
for chunk in index.chunks_mut(16) {
key.decrypt_block(aes::Block::from_mut_slice(chunk))
}
}
Err(_) => return Err(super::Error::Aes),
}
}
let mount_point = reader.read_string()?;
let len = reader.read_u32::<LE>()? as usize;
let mut entries = hashbrown::HashMap::with_capacity(len);