From 0c63fc23c4ca5b859a99e0d1864a41df6cc08d5f Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 20 Jan 2008 01:21:03 +0000 Subject: Fix zipfile decryption. The check for validity only worked on one type of encrypted zip files. Files using extended local headers needed to compare the check byte against different values. (according to reading the infozip unzip crypt.c source code) Fixes issue1003. --- Lib/test/test_zipfile.py | 21 +++++++++++++++++++++ Lib/zipfile.py | 13 +++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 40003aa..adc0dc1 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -698,31 +698,52 @@ class DecryptionTests(unittest.TestCase): '\x1a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\xb6\x81' '\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00' '\x00\x00L\x00\x00\x00\x00\x00' ) + data2 = ( + 'PK\x03\x04\x14\x00\t\x00\x08\x00\xcf}38xu\xaa\xb2\x14\x00\x00\x00\x00\x02' + '\x00\x00\x04\x00\x15\x00zeroUT\t\x00\x03\xd6\x8b\x92G\xda\x8b\x92GUx\x04' + '\x00\xe8\x03\xe8\x03\xc7>9)+1980, (d>>5)&0xF, d&0x1F, t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) @@ -790,11 +792,18 @@ class ZipFile: # The first 12 bytes in the cypher stream is an encryption header # used to strengthen the algorithm. The first 11 bytes are # completely random, while the 12th contains the MSB of the CRC, + # or the MSB of the file time depending on the header type # and is used to check the correctness of the password. bytes = zef_file.read(12) h = map(zd, bytes[0:12]) - if ord(h[11]) != ((zinfo.CRC>>24)&255): - raise RuntimeError, "Bad password for file %s" % name + if zinfo.flag_bits & 0x8: + # compare against the file type from extended local headers + check_byte = (zinfo._raw_time >> 8) & 0xff + else: + # compare against the CRC otherwise + check_byte = (zinfo.CRC >> 24) & 0xff + if ord(h[11]) != check_byte: + raise RuntimeError("Bad password for file", name) # build and return a ZipExtFile if zd is None: -- cgit v0.12