disable crc32 checks when handling aes encrypted data
This commit is contained in:
parent
852ab625fb
commit
12260f5623
3 changed files with 21 additions and 15 deletions
|
@ -51,7 +51,7 @@ All of these are enabled by default.
|
|||
MSRV
|
||||
----
|
||||
|
||||
Our current Minimum Supported Rust Version is **1.36.0**. When adding features,
|
||||
Our current Minimum Supported Rust Version is **1.42.0**. When adding features,
|
||||
we will follow these guidelines:
|
||||
|
||||
- We will always support the latest four minor Rust versions. This gives you a 6
|
||||
|
|
16
src/crc32.rs
16
src/crc32.rs
|
@ -10,15 +10,19 @@ pub struct Crc32Reader<R> {
|
|||
inner: R,
|
||||
hasher: Hasher,
|
||||
check: u32,
|
||||
/// Signals if `inner` stores aes encrypted data.
|
||||
/// AE-2 encrypted data doesn't use crc and sets the value to 0.
|
||||
aes_encrypted: bool,
|
||||
}
|
||||
|
||||
impl<R> Crc32Reader<R> {
|
||||
/// Get a new Crc32Reader which check the inner reader against checksum.
|
||||
pub fn new(inner: R, checksum: u32) -> Crc32Reader<R> {
|
||||
pub fn new(inner: R, checksum: u32, aes_encrypted: bool) -> Crc32Reader<R> {
|
||||
Crc32Reader {
|
||||
inner,
|
||||
hasher: Hasher::new(),
|
||||
check: checksum,
|
||||
aes_encrypted,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +38,7 @@ impl<R> Crc32Reader<R> {
|
|||
impl<R: Read> Read for Crc32Reader<R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let count = match self.inner.read(buf) {
|
||||
Ok(0) if !buf.is_empty() && !self.check_matches() => {
|
||||
Ok(0) if !buf.is_empty() && !self.check_matches() && !self.aes_encrypted => {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "Invalid checksum"))
|
||||
}
|
||||
Ok(n) => n,
|
||||
|
@ -55,10 +59,10 @@ mod test {
|
|||
let data: &[u8] = b"";
|
||||
let mut buf = [0; 1];
|
||||
|
||||
let mut reader = Crc32Reader::new(data, 0);
|
||||
let mut reader = Crc32Reader::new(data, 0, false);
|
||||
assert_eq!(reader.read(&mut buf).unwrap(), 0);
|
||||
|
||||
let mut reader = Crc32Reader::new(data, 1);
|
||||
let mut reader = Crc32Reader::new(data, 1, false);
|
||||
assert!(reader
|
||||
.read(&mut buf)
|
||||
.unwrap_err()
|
||||
|
@ -71,7 +75,7 @@ mod test {
|
|||
let data: &[u8] = b"1234";
|
||||
let mut buf = [0; 1];
|
||||
|
||||
let mut reader = Crc32Reader::new(data, 0x9be3e0a3);
|
||||
let mut reader = Crc32Reader::new(data, 0x9be3e0a3, false);
|
||||
assert_eq!(reader.read(&mut buf).unwrap(), 1);
|
||||
assert_eq!(reader.read(&mut buf).unwrap(), 1);
|
||||
assert_eq!(reader.read(&mut buf).unwrap(), 1);
|
||||
|
@ -86,7 +90,7 @@ mod test {
|
|||
let data: &[u8] = b"1234";
|
||||
let mut buf = [0; 5];
|
||||
|
||||
let mut reader = Crc32Reader::new(data, 0x9be3e0a3);
|
||||
let mut reader = Crc32Reader::new(data, 0x9be3e0a3, false);
|
||||
assert_eq!(reader.read(&mut buf[..0]).unwrap(), 0);
|
||||
assert_eq!(reader.read(&mut buf).unwrap(), 4);
|
||||
}
|
||||
|
|
14
src/read.rs
14
src/read.rs
|
@ -1,6 +1,6 @@
|
|||
//! Types for reading ZIP archives
|
||||
|
||||
use crate::aes::{AesReaderValid, AesReader};
|
||||
use crate::aes::{AesReader, AesReaderValid};
|
||||
use crate::compression::CompressionMethod;
|
||||
use crate::cp437::FromCp437;
|
||||
use crate::crc32::Crc32Reader;
|
||||
|
@ -205,8 +205,11 @@ fn make_reader<'a>(
|
|||
crc32: u32,
|
||||
reader: CryptoReader<'a>,
|
||||
) -> ZipFileReader<'a> {
|
||||
let aes_encrypted = matches!(reader, CryptoReader::Aes(_));
|
||||
match compression_method {
|
||||
CompressionMethod::Stored => ZipFileReader::Stored(Crc32Reader::new(reader, crc32)),
|
||||
CompressionMethod::Stored => {
|
||||
ZipFileReader::Stored(Crc32Reader::new(reader, crc32, aes_encrypted))
|
||||
}
|
||||
#[cfg(any(
|
||||
feature = "deflate",
|
||||
feature = "deflate-miniz",
|
||||
|
@ -214,12 +217,12 @@ fn make_reader<'a>(
|
|||
))]
|
||||
CompressionMethod::Deflated => {
|
||||
let deflate_reader = DeflateDecoder::new(reader);
|
||||
ZipFileReader::Deflated(Crc32Reader::new(deflate_reader, crc32))
|
||||
ZipFileReader::Deflated(Crc32Reader::new(deflate_reader, crc32, aes_encrypted))
|
||||
}
|
||||
#[cfg(feature = "bzip2")]
|
||||
CompressionMethod::Bzip2 => {
|
||||
let bzip2_reader = BzDecoder::new(reader);
|
||||
ZipFileReader::Bzip2(Crc32Reader::new(bzip2_reader, crc32))
|
||||
ZipFileReader::Bzip2(Crc32Reader::new(bzip2_reader, crc32, aes_encrypted))
|
||||
}
|
||||
_ => panic!("Compression method not supported"),
|
||||
}
|
||||
|
@ -514,7 +517,7 @@ impl<R: Read + io::Seek> ZipArchive<R> {
|
|||
limit_reader,
|
||||
password,
|
||||
data.aes_mode,
|
||||
data.compressed_size
|
||||
data.compressed_size,
|
||||
) {
|
||||
Ok(Ok(crypto_reader)) => Ok(Ok(ZipFile {
|
||||
crypto_reader: Some(crypto_reader),
|
||||
|
@ -616,7 +619,6 @@ pub(crate) fn central_header_to_zip_file<R: Read + io::Seek>(
|
|||
Err(e) => return Err(e),
|
||||
}
|
||||
|
||||
|
||||
let aes_enabled = result.compression_method == CompressionMethod::AES;
|
||||
if aes_enabled && result.aes_mode.is_none() {
|
||||
return Err(ZipError::InvalidArchive(
|
||||
|
|
Loading…
Add table
Reference in a new issue