aboutsummaryrefslogtreecommitdiff
path: root/src/zip/encryption.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/zip/encryption.rs')
-rw-r--r--src/zip/encryption.rs49
1 files changed, 38 insertions, 11 deletions
diff --git a/src/zip/encryption.rs b/src/zip/encryption.rs
index 84e30d5..28a6bdb 100644
--- a/src/zip/encryption.rs
+++ b/src/zip/encryption.rs
@@ -1,12 +1,35 @@
1use crate::utils::ReadUtils; 1use crate::utils::ReadUtils;
2use crate::zip::ZipResult; 2use crate::zip::{ZipError, ZipResult};
3use crc32fast::Hasher;
4use std::io::{Read, Result as IoResult}; 3use std::io::{Read, Result as IoResult};
5 4
6fn crc32(byte: u8, crc32: u32) -> u32 { 5const TABLE: [u32; 256] = generate_table();
7 let mut hasher = Hasher::new_with_initial(crc32 ^ 0xFFFFFFFF); 6
8 hasher.update(&[byte]); 7const fn generate_table() -> [u32; 256] {
9 hasher.finalize() ^ 0xFFFFFFFF 8 let mut table = [0; 256];
9
10 let mut b = 0;
11 while b <= 255 {
12 let mut crc = b as u32;
13
14 let mut i = 0;
15 while i < 8 {
16 if (crc & 1) > 0 {
17 crc = (crc >> 1) ^ 0xEDB88320
18 } else {
19 crc >>= 1
20 }
21 i += 1;
22 }
23
24 table[b] = crc;
25 b += 1
26 }
27
28 table
29}
30
31fn crc32(byte: u8, crc: u32) -> u32 {
32 (crc >> 8) ^ TABLE[((crc & 0xFF) as u8 ^ byte) as usize]
10} 33}
11 34
12pub struct WeakDecoder<Io: Read> { 35pub struct WeakDecoder<Io: Read> {
@@ -17,7 +40,7 @@ pub struct WeakDecoder<Io: Read> {
17} 40}
18 41
19impl<Io: Read> WeakDecoder<Io> { 42impl<Io: Read> WeakDecoder<Io> {
20 pub fn new(io: Io, password: &str) -> ZipResult<Self> { 43 pub fn new(io: Io, check: u8, password: &[u8]) -> ZipResult<Self> {
21 let mut decoder = Self { 44 let mut decoder = Self {
22 key0: 305419896, 45 key0: 305419896,
23 key1: 591751049, 46 key1: 591751049,
@@ -25,11 +48,14 @@ impl<Io: Read> WeakDecoder<Io> {
25 io, 48 io,
26 }; 49 };
27 50
28 for c in password.chars() { 51 for c in password {
29 decoder.update_keys(c as u8) 52 decoder.update_keys(*c)
30 } 53 }
31 54
32 let buf = decoder.read_arr::<12>()?; 55 let buf = decoder.read_arr::<12>()?;
56 if check != buf[11] {
57 return Err(ZipError::IncorrectPassword.into());
58 }
33 59
34 Ok(decoder) 60 Ok(decoder)
35 } 61 }
@@ -46,7 +72,9 @@ impl<Io: Read> WeakDecoder<Io> {
46 72
47 fn decode_byte(&mut self, byte: u8) -> u8 { 73 fn decode_byte(&mut self, byte: u8) -> u8 {
48 let key = self.key2 | 2; 74 let key = self.key2 | 2;
49 byte ^ (((key * (key ^ 1)) >> 8) as u8) 75 let byte = byte ^ ((key * (key ^ 1)) >> 8) as u8;
76 self.update_keys(byte);
77 byte
50 } 78 }
51} 79}
52 80
@@ -55,7 +83,6 @@ impl<Io: Read> Read for WeakDecoder<Io> {
55 let bytes = self.io.read(buf)?; 83 let bytes = self.io.read(buf)?;
56 for i in 0..bytes { 84 for i in 0..bytes {
57 buf[i] = self.decode_byte(buf[i]); 85 buf[i] = self.decode_byte(buf[i]);
58 self.update_keys(buf[i])
59 } 86 }
60 Ok(bytes) 87 Ok(bytes)
61 } 88 }