aboutsummaryrefslogtreecommitdiff
path: root/src/zip/file/read.rs
diff options
context:
space:
mode:
authorIgor Tolmachev <me@igorek.dev>2024-07-21 16:59:14 +0900
committerIgor Tolmachev <me@igorek.dev>2024-07-21 16:59:14 +0900
commit4c411b76cad9cc735687dc739d2e2db5d00e5eac (patch)
tree818168ca5726ad3f9d24089dba31a24ff6b1b1f4 /src/zip/file/read.rs
parent7bcdc3b4ca460aec2b98fb2dca6165788c562b05 (diff)
downloadarchivator-4c411b76cad9cc735687dc739d2e2db5d00e5eac.tar.gz
archivator-4c411b76cad9cc735687dc739d2e2db5d00e5eac.zip
Add AES encryption
Diffstat (limited to 'src/zip/file/read.rs')
-rw-r--r--src/zip/file/read.rs71
1 files changed, 45 insertions, 26 deletions
diff --git a/src/zip/file/read.rs b/src/zip/file/read.rs
index 80bdcfb..d25655e 100644
--- a/src/zip/file/read.rs
+++ b/src/zip/file/read.rs
@@ -24,21 +24,34 @@ enum Encryption<Io: Read> {
24 Aes256(AesDecoder<Io, Aes256>), 24 Aes256(AesDecoder<Io, Aes256>),
25} 25}
26 26
27impl<Io: Read> Encryption<Io> { 27impl<Io: Read + Seek> Encryption<IoCursor<Io>> {
28 #[inline] 28 #[inline]
29 pub fn new(mut io: Io, info: &ZipFileInfo, password: Option<&[u8]>) -> ZipResult<Self> { 29 pub fn new(
30 mut io: Io,
31 cursor: u64,
32 end: u64,
33 info: &ZipFileInfo,
34 password: Option<&[u8]>,
35 ) -> ZipResult<Self> {
30 Ok(match info.encryption_method { 36 Ok(match info.encryption_method {
31 EncryptionMethod::None => Self::None(io), 37 EncryptionMethod::None => Self::None(IoCursor::new(io, cursor, end)),
32 EncryptionMethod::Weak => { 38 EncryptionMethod::Weak => {
33 let mut keys = Keys::new(); 39 let mut keys = Keys::new();
34 keys.set_password(password.ok_or(ZipError::PasswordIsNotSpecified)?);
35 40
36 let check = keys.set_header(io.read_arr()?); 41 for b in password.ok_or(ZipError::PasswordIsNotSpecified)? {
37 if check != info.password_check() { 42 keys.update(*b)
38 return Err(ZipError::IncorrectPassword); 43 }
44
45 let header = io.read_arr::<12>()?;
46 for b in &header[..11] {
47 keys.decode_byte(*b);
39 } 48 }
40 49
41 Self::Weak(WeakDecoder::new(io, keys)) 50 if keys.decode_byte(header[11]) != info.password_check() {
51 return Err(ZipError::WrongPassword);
52 }
53
54 Self::Weak(WeakDecoder::new(IoCursor::new(io, cursor + 12, end), keys))
42 } 55 }
43 EncryptionMethod::Aes128 => { 56 EncryptionMethod::Aes128 => {
44 let header = io.read_arr::<10>()?; 57 let header = io.read_arr::<10>()?;
@@ -53,10 +66,13 @@ impl<Io: Read> Encryption<Io> {
53 let key = &hash[..16]; 66 let key = &hash[..16];
54 67
55 if check != &hash[32..] { 68 if check != &hash[32..] {
56 return Err(ZipError::IncorrectPassword); 69 return Err(ZipError::WrongPassword);
57 } 70 }
58 71
59 Self::Aes128(AesDecoder::new(io, Aes128::new(key.into()))?) 72 Self::Aes128(AesDecoder::new(
73 IoCursor::new(io, cursor + 10, end - 10),
74 Aes128::new(key.into()),
75 )?)
60 } 76 }
61 EncryptionMethod::Aes192 => { 77 EncryptionMethod::Aes192 => {
62 let header = io.read_arr::<14>()?; 78 let header = io.read_arr::<14>()?;
@@ -71,10 +87,13 @@ impl<Io: Read> Encryption<Io> {
71 let key = &hash[..24]; 87 let key = &hash[..24];
72 88
73 if check != &hash[48..] { 89 if check != &hash[48..] {
74 return Err(ZipError::IncorrectPassword); 90 return Err(ZipError::WrongPassword);
75 } 91 }
76 92
77 Self::Aes192(AesDecoder::new(io, Aes192::new(key.into()))?) 93 Self::Aes192(AesDecoder::new(
94 IoCursor::new(io, cursor + 14, end - 10),
95 Aes192::new(key.into()),
96 )?)
78 } 97 }
79 EncryptionMethod::Aes256 => { 98 EncryptionMethod::Aes256 => {
80 let header = io.read_arr::<18>()?; 99 let header = io.read_arr::<18>()?;
@@ -89,10 +108,13 @@ impl<Io: Read> Encryption<Io> {
89 let key = &hash[..32]; 108 let key = &hash[..32];
90 109
91 if check != &hash[64..] { 110 if check != &hash[64..] {
92 return Err(ZipError::IncorrectPassword); 111 return Err(ZipError::WrongPassword);
93 } 112 }
94 113
95 Self::Aes256(AesDecoder::new(io, Aes256::new(key.into()))?) 114 Self::Aes256(AesDecoder::new(
115 IoCursor::new(io, cursor + 18, end - 10),
116 Aes256::new(key.into()),
117 )?)
96 } 118 }
97 EncryptionMethod::Unsupported => return Err(ZipError::UnsupportedEncryptionMethod), 119 EncryptionMethod::Unsupported => return Err(ZipError::UnsupportedEncryptionMethod),
98 }) 120 })
@@ -215,20 +237,17 @@ impl<'d, Io: Read + Seek> ZipFileReader<'d, Io> {
215 if buf[..4] != FILE_HEADER_SIGNATURE { 237 if buf[..4] != FILE_HEADER_SIGNATURE {
216 return Err(ZipError::InvalidFileHeaderSignature); 238 return Err(ZipError::InvalidFileHeaderSignature);
217 } 239 }
218 let data_pointer = info.header_pointer 240
219 + 30 241 let cursor = io.seek(SeekFrom::Start(
220 + u16::from_le_bytes(buf[26..28].try_into().unwrap()) as u64 242 info.header_pointer
221 + u16::from_le_bytes(buf[28..30].try_into().unwrap()) as u64; 243 + 30
244 + u16::from_le_bytes(buf[26..28].try_into().unwrap()) as u64
245 + u16::from_le_bytes(buf[28..30].try_into().unwrap()) as u64,
246 ))?;
247 let end = cursor + info.compressed_size;
222 248
223 Ok(Self { 249 Ok(Self {
224 io: Compression::new( 250 io: Compression::new(Encryption::new(io, cursor, end, info, password)?, info)?,
225 Encryption::new(
226 IoCursor::new(io, data_pointer, data_pointer + info.compressed_size)?,
227 info,
228 password,
229 )?,
230 info,
231 )?,
232 info, 251 info,
233 }) 252 })
234 } 253 }