mirror of
https://github.com/xavo95/repak.git
synced 2025-01-18 19:04:07 +00:00
add encryption support
This commit is contained in:
parent
07bbbbc5ed
commit
c440ca6707
5 changed files with 23 additions and 2 deletions
|
@ -11,6 +11,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "*"
|
byteorder = "*"
|
||||||
strum = { version = "*", features = ["derive"] }
|
strum = { version = "*", features = ["derive"] }
|
||||||
|
aes = "*"
|
||||||
hashbrown = "*"
|
hashbrown = "*"
|
||||||
thiserror = "*"
|
thiserror = "*"
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ fn main() -> Result<(), un_pak::Error> {
|
||||||
let pak = un_pak::Pak::new(
|
let pak = un_pak::Pak::new(
|
||||||
std::io::BufReader::new(std::io::Cursor::new(include_bytes!("rando_p.pak"))),
|
std::io::BufReader::new(std::io::Cursor::new(include_bytes!("rando_p.pak"))),
|
||||||
un_pak::Version::CompressionEncryption,
|
un_pak::Version::CompressionEncryption,
|
||||||
|
None,
|
||||||
)?;
|
)?;
|
||||||
for file in pak.entries.keys() {
|
for file in pak.entries.keys() {
|
||||||
println!("{file}")
|
println!("{file}")
|
||||||
|
|
|
@ -5,6 +5,7 @@ fn main() -> Result<(), un_pak::Error> {
|
||||||
match un_pak::Pak::new(
|
match un_pak::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,
|
||||||
|
None,
|
||||||
) {
|
) {
|
||||||
Ok(un_pak::Pak { version, .. }) | Err(un_pak::Error::Version { version, .. }) => {
|
Ok(un_pak::Pak { version, .. }) | Err(un_pak::Error::Version { version, .. }) => {
|
||||||
println!("{}", version);
|
println!("{}", version);
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("io error: {0}")]
|
// dependency errors
|
||||||
Io(#[from] std::io::Error),
|
|
||||||
#[error("enum conversion: {0}")]
|
#[error("enum conversion: {0}")]
|
||||||
Strum(#[from] strum::ParseError),
|
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}")]
|
#[error("utf8 conversion: {0}")]
|
||||||
Utf8(#[from] std::string::FromUtf8Error),
|
Utf8(#[from] std::string::FromUtf8Error),
|
||||||
#[error("utf16 conversion: {0}")]
|
#[error("utf16 conversion: {0}")]
|
||||||
|
@ -11,6 +15,7 @@ pub enum Error {
|
||||||
#[error("bufwriter dereference: {0}")]
|
#[error("bufwriter dereference: {0}")]
|
||||||
IntoInner(#[from] std::io::IntoInnerError<std::io::BufWriter<Vec<u8>>>),
|
IntoInner(#[from] std::io::IntoInnerError<std::io::BufWriter<Vec<u8>>>),
|
||||||
#[error("found magic of {0:#x} instead of {:#x}", super::MAGIC)]
|
#[error("found magic of {0:#x} instead of {:#x}", super::MAGIC)]
|
||||||
|
// crate errors
|
||||||
Magic(u32),
|
Magic(u32),
|
||||||
#[error("used version {used} but pak is version {version}")]
|
#[error("used version {used} but pak is version {version}")]
|
||||||
Version {
|
Version {
|
||||||
|
|
13
src/pak.rs
13
src/pak.rs
|
@ -1,6 +1,7 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use super::ReadExt;
|
use super::ReadExt;
|
||||||
|
use aes::cipher::{BlockDecrypt, KeyInit};
|
||||||
use byteorder::{ReadBytesExt, LE};
|
use byteorder::{ReadBytesExt, LE};
|
||||||
|
|
||||||
use super::Version;
|
use super::Version;
|
||||||
|
@ -17,10 +18,22 @@ impl Pak {
|
||||||
pub fn new<R: io::Read + io::Seek>(
|
pub fn new<R: io::Read + io::Seek>(
|
||||||
mut reader: R,
|
mut reader: R,
|
||||||
version: super::Version,
|
version: super::Version,
|
||||||
|
key: Option<&[u8]>,
|
||||||
) -> Result<Self, super::Error> {
|
) -> Result<Self, super::Error> {
|
||||||
reader.seek(io::SeekFrom::End(-version.size()))?;
|
reader.seek(io::SeekFrom::End(-version.size()))?;
|
||||||
let footer = super::Footer::new(&mut reader, version)?;
|
let footer = super::Footer::new(&mut reader, version)?;
|
||||||
reader.seek(io::SeekFrom::Start(footer.offset))?;
|
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 mount_point = reader.read_string()?;
|
||||||
let len = reader.read_u32::<LE>()? as usize;
|
let len = reader.read_u32::<LE>()? as usize;
|
||||||
let mut entries = hashbrown::HashMap::with_capacity(len);
|
let mut entries = hashbrown::HashMap::with_capacity(len);
|
||||||
|
|
Loading…
Reference in a new issue