move AesMode and AesVendorVersion out of aes-crypto feature

This commit is contained in:
Lireer 2020-10-14 16:06:56 +02:00
parent ed94e8b369
commit 48b52a7e86
4 changed files with 46 additions and 50 deletions

View file

@ -5,6 +5,7 @@
//! AE-2 doesn't set the CRC field correctly, even though some zip files still have CRC set even with AE-2.
use crate::aes_ctr;
use crate::types::AesMode;
use constant_time_eq::constant_time_eq;
use hmac::{Hmac, Mac, NewMac};
use sha1::Sha1;
@ -33,37 +34,6 @@ fn cipher_from_mode(aes_mode: AesMode, key: &[u8]) -> Box<dyn aes_ctr::AesCipher
}
}
#[cfg(feature = "aes-crypto")]
#[derive(Copy, Clone, Debug)]
pub enum AesVendorVersion {
Ae1,
Ae2,
}
#[cfg(feature = "aes-crypto")]
/// AES variant used.
#[derive(Copy, Clone, Debug)]
pub enum AesMode {
Aes128,
Aes192,
Aes256,
}
#[cfg(feature = "aes-crypto")]
impl AesMode {
pub fn salt_length(&self) -> usize {
self.key_length() / 2
}
pub fn key_length(&self) -> usize {
match self {
Self::Aes128 => 16,
Self::Aes192 => 24,
Self::Aes256 => 32,
}
}
}
// An aes encrypted file starts with a salt, whose length depends on the used aes mode
// followed by a 2 byte password verification value
// then the variable length encrypted data

View file

@ -1,13 +1,13 @@
//! Types for reading ZIP archives
#[cfg(feature = "aes-crypto")]
use crate::aes::{AesMode, AesReader, AesReaderValid, AesVendorVersion};
use crate::aes::{AesReader, AesReaderValid};
use crate::compression::CompressionMethod;
use crate::cp437::FromCp437;
use crate::crc32::Crc32Reader;
use crate::result::{InvalidPassword, ZipError, ZipResult};
use crate::spec;
use crate::types::{DateTime, System, ZipFileData};
use crate::types::{AesMode, AesVendorVersion, DateTime, System, ZipFileData};
use crate::zipcrypto::{ZipCryptoReader, ZipCryptoReaderValid, ZipCryptoValidator};
use byteorder::{LittleEndian, ReadBytesExt};
use std::borrow::Cow;
@ -175,7 +175,7 @@ fn make_crypto_reader<'a>(
using_data_descriptor: bool,
reader: io::Take<&'a mut dyn io::Read>,
password: Option<&[u8]>,
#[cfg(feature = "aes-crypto")] aes_info: Option<(AesMode, AesVendorVersion)>,
aes_info: Option<(AesMode, AesVendorVersion)>,
#[cfg(feature = "aes-crypto")] compressed_size: u64,
) -> ZipResult<Result<CryptoReader<'a>, InvalidPassword>> {
#[allow(deprecated)]
@ -185,10 +185,13 @@ fn make_crypto_reader<'a>(
}
}
#[cfg(not(feature = "aes-crypto"))]
let aes_info: Option<()> = None;
let reader = match (password, aes_info) {
#[cfg(not(feature = "aes-crypto"))]
(Some(_), Some(_)) => {
return Err(ZipError::UnsupportedArchive(
"AES encrypted files cannot be decrypted without the aes-crypto feature.",
))
}
#[cfg(feature = "aes-crypto")]
(Some(password), Some((aes_mode, vendor_version))) => {
match AesReader::new(reader, aes_mode, compressed_size).validate(&password)? {
@ -210,7 +213,8 @@ fn make_crypto_reader<'a>(
Some(r) => CryptoReader::ZipCrypto(r),
}
}
_ => CryptoReader::Plaintext(reader),
(None, Some(_)) => return Ok(Err(InvalidPassword)),
(None, None) => CryptoReader::Plaintext(reader),
};
Ok(Ok(reader))
}
@ -549,7 +553,6 @@ impl<R: Read + io::Seek> ZipArchive<R> {
data.using_data_descriptor,
limit_reader,
password,
#[cfg(feature = "aes-crypto")]
data.aes_mode,
#[cfg(feature = "aes-crypto")]
data.compressed_size,
@ -646,7 +649,6 @@ pub(crate) fn central_header_to_zip_file<R: Read + io::Seek>(
data_start: 0,
external_attributes: external_file_attributes,
large_file: false,
#[cfg(feature = "aes-crypto")]
aes_mode: None,
};
@ -696,7 +698,6 @@ fn parse_extra_field(file: &mut ZipFileData) -> ZipResult<()> {
len_left -= 8;
}
}
#[cfg(feature = "aes-crypto")]
0x9901 => {
// AES
if len != 7 {
@ -1048,7 +1049,6 @@ pub fn read_zipfile_from_stream<'a, R: io::Read>(
// from standard input, this field is set to zero.'
external_attributes: 0,
large_file: false,
#[cfg(feature = "aes-crypto")]
aes_mode: None,
};
@ -1075,7 +1075,6 @@ pub fn read_zipfile_from_stream<'a, R: io::Read>(
result.using_data_descriptor,
limit_reader,
None,
#[cfg(feature = "aes-crypto")]
None,
#[cfg(feature = "aes-crypto")]
result.compressed_size,

View file

@ -1,8 +1,5 @@
//! Types that specify what is contained in a ZIP.
#[cfg(feature = "aes-crypto")]
use crate::aes::{AesMode, AesVendorVersion};
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum System {
Dos = 0,
@ -251,7 +248,6 @@ pub struct ZipFileData {
pub external_attributes: u32,
/// Reserve local ZIP64 extra field
pub large_file: bool,
#[cfg(feature = "aes-crypto")]
/// AES mode if applicable
pub aes_mode: Option<(AesMode, AesVendorVersion)>,
}
@ -301,6 +297,39 @@ impl ZipFileData {
}
}
/// The encryption specification used to encrypt a file with AES.
///
/// According to the [specification](https://www.winzip.com/win/en/aes_info.html#winzip11) AE-2
/// does not make use of the CRC check.
#[derive(Copy, Clone, Debug)]
pub enum AesVendorVersion {
Ae1,
Ae2,
}
/// AES variant used.
#[derive(Copy, Clone, Debug)]
pub enum AesMode {
Aes128,
Aes192,
Aes256,
}
#[cfg(feature = "aes-crypto")]
impl AesMode {
pub fn salt_length(&self) -> usize {
self.key_length() / 2
}
pub fn key_length(&self) -> usize {
match self {
Self::Aes128 => 16,
Self::Aes192 => 24,
Self::Aes256 => 32,
}
}
}
#[cfg(test)]
mod test {
#[test]
@ -335,7 +364,6 @@ mod test {
central_header_start: 0,
external_attributes: 0,
large_file: false,
#[cfg(feature = "aes-crypto")]
aes_mode: None,
};
assert_eq!(

View file

@ -334,7 +334,6 @@ impl<W: Write + io::Seek> ZipWriter<W> {
central_header_start: 0,
external_attributes: permissions << 16,
large_file: options.large_file,
#[cfg(feature = "aes-crypto")]
aes_mode: None,
};
write_local_file_header(writer, &file)?;