def __init__(self, aes_properties: bytes, password: str, blocksize: Optional[int] = None) -> None: firstbyte = aes_properties[0] numcyclespower = firstbyte & 0x3F if firstbyte & 0xC0 != 0: saltsize = (firstbyte >> 7) & 1 ivsize = (firstbyte >> 6) & 1 secondbyte = aes_properties[1] saltsize += secondbyte >> 4 ivsize += secondbyte & 0x0F assert len(aes_properties) == 2 + saltsize + ivsize salt = aes_properties[2:2 + saltsize] iv = aes_properties[2 + saltsize:2 + saltsize + ivsize] assert len(salt) == saltsize assert len(iv) == ivsize assert numcyclespower <= 24 if ivsize < 16: iv += bytes("\x00" * (16 - ivsize), "ascii") key = calculate_key(password.encode("utf-16LE"), numcyclespower, salt, "sha256") self.cipher = AES.new(key, AES.MODE_CBC, iv) if blocksize: self.buf = Buffer(size=blocksize + 16) else: self.buf = Buffer(size=get_default_blocksize() + 16) else: raise UnsupportedCompressionMethodError
def __init__(self, filters=None, password=None, blocksize: Optional[int] = None): self.filters: List[Dict[str, Any]] = [] self.chain: List[ISevenZipCompressor] = [] self.digest = 0 self.packsize = 0 self._unpacksizes: List[int] = [] if blocksize: self._block_size = blocksize else: self._block_size = get_default_blocksize() if filters is None: self.filters = [{ "id": lzma.FILTER_LZMA2, "preset": 7 | lzma.PRESET_EXTREME }] else: self.filters = filters if len(self.filters) > 4: raise UnsupportedCompressionMethodError( filters, "Maximum cascade of filters is 4 but got {}.".format( len(self.filters))) self.methods_map = [ SupportedMethods.is_native_filter(filter) for filter in self.filters ] self.coders: List[Dict[str, Any]] = [] if all(self.methods_map) and SupportedMethods.is_compressor( self.filters[-1]): # all native self._set_native_compressors_coders(self.filters) return # has_lzma2 = False for f in self.filters: if f["id"] == FILTER_LZMA2: has_lzma2 = True break if not has_lzma2: # when specified other than lzma2, BCJ filters should be alternative for i, f in enumerate(self.filters): if (f["id"] == FILTER_X86 or f["id"] == FILTER_ARM or f["id"] == FILTER_ARMTHUMB or f["id"] == FILTER_SPARC or f["id"] == FILTER_POWERPC): self.methods_map[i] = False # if not any(self.methods_map): # all alternative for f in filters: self._set_alternate_compressors_coders(f, password) elif SupportedMethods.is_crypto_id(self.filters[-1]["id"]) and all( self.methods_map[:-1]): self._set_native_compressors_coders(self.filters[:-1]) self._set_alternate_compressors_coders(self.filters[-1], password) else: raise UnsupportedCompressionMethodError( filters, "Unknown combination of methods.")
def _split_file(self, filepath, size): chapters = 0 written = [0, 0] total_size = filepath.stat().st_size block_size = get_default_blocksize() with filepath.open("rb") as src: while written[0] <= total_size: with open(str(filepath) + ".%03d" % chapters, "wb") as tgt: written[1] = 0 while written[1] < size: read_size = min(block_size, size - written[1]) tgt.write(src.read(read_size)) written[1] += read_size written[0] += read_size chapters += 1
def __init__(self, filters=None, password=None, blocksize: Optional[int] = None): self.filters: List[Dict[str, Any]] = [] self.chain: List[ISevenZipCompressor] = [] self.digest = 0 self.packsize = 0 self._unpacksizes: List[int] = [] if blocksize: self._block_size = blocksize else: self._block_size = get_default_blocksize() if filters is None: self.filters = [{ "id": lzma.FILTER_LZMA2, "preset": 7 | lzma.PRESET_EXTREME }] else: self.filters = filters if len(self.filters) > 4: raise UnsupportedCompressionMethodError( "Maximum cascade of filters is 4 but got {}.".format( len(self.filters))) self.methods_map = [ SupportedMethods.is_native_filter(filter) for filter in self.filters ] self.coders: List[Dict[str, Any]] = [] if all(self.methods_map) and SupportedMethods.is_compressor( self.filters[-1]): # all native self._set_native_compressors_coders(self.filters) return # for i, f in enumerate(self.filters): if f["id"] == FILTER_X86: self.methods_map[i] = False # if not any(self.methods_map): # all alternative for f in filters: self._set_alternate_compressors_coders(f, password) elif SupportedMethods.is_crypto_id(self.filters[-1]["id"]) and all( self.methods_map[:-1]): self._set_native_compressors_coders(self.filters[:-1]) self._set_alternate_compressors_coders(self.filters[-1], password) else: raise UnsupportedCompressionMethodError
def __init__(self, password: str, blocksize: Optional[int] = None) -> None: self.cycles = 19 # as same as p7zip self.iv = get_random_bytes(16) self.salt = b"" self.method = CompressionMethod.CRYPT_AES256_SHA256 key = calculate_key(password.encode("utf-16LE"), self.cycles, self.salt, "sha256") self.iv += bytes( self.AES_CBC_BLOCKSIZE - len(self.iv)) # zero padding if iv < AES_CBC_BLOCKSIZE self.cipher = AES.new(key, AES.MODE_CBC, self.iv) self.flushed = False if blocksize: self.buf = Buffer(size=blocksize + self.AES_CBC_BLOCKSIZE * 2) else: self.buf = Buffer(size=get_default_blocksize() + self.AES_CBC_BLOCKSIZE * 2)
def __init__(self, properties: bytes, blocksize: Optional[int] = None): if not isinstance(properties, bytes): raise UnsupportedCompressionMethodError if len(properties) == 5: level, mem = struct.unpack("<BL", properties) elif len(properties) == 7: level, mem, _, _ = struct.unpack("<BLBB", properties) else: raise UnsupportedCompressionMethodError if blocksize: self.block_size = blocksize else: self.block_size = get_default_blocksize() self._buf = BufferedRW(self.block_size) self._buf = BufferedRW() self.decoder = None self.level = level self.mem = mem self.initialized = False
def __init__( self, coders: List[Dict[str, Any]], packsize: int, unpacksizes: List[int], crc: Optional[int], password: Optional[str] = None, blocksize: Optional[int] = None, ) -> None: self.input_size = packsize self.unpacksizes = unpacksizes self.consumed: int = 0 self.crc = crc self.digest: int = 0 if blocksize: self.block_size: int = blocksize else: self.block_size = get_default_blocksize() if len(coders) > 4: raise UnsupportedCompressionMethodError( "Maximum cascade of filters is 4 but got {}.".format( len(coders))) self.methods_map = [ SupportedMethods.is_native_coder(coder) for coder in coders ] # type: List[bool] # Check if password given for encrypted archive if SupportedMethods.needs_password(coders) and password is None: raise PasswordRequired( "Password is required for extracting given archive.") # Check filters combination and required parameters if len(coders) >= 2: target_compressor = False has_bcj = False bcj_index = -1 for i, coder in enumerate(coders): filter_id = SupportedMethods.get_filter_id(coder) if SupportedMethods.is_compressor_id( filter_id) and filter_id != FILTER_LZMA2: target_compressor = True if filter_id in [ FILTER_X86, FILTER_ARM, FILTER_ARMTHUMB, FILTER_POWERPC, FILTER_SPARC, ]: has_bcj = True bcj_index = i # hack for LZMA1+BCJ which should be native+alternative if target_compressor and has_bcj: self.methods_map[bcj_index] = False break self.chain = [ ] # type: List[Union[bz2.BZ2Decompressor, lzma.LZMADecompressor, ISevenZipDecompressor]] self._unpacksizes = [] # type: List[int] self.input_size = self.input_size shift = 0 prev = False for i, r in enumerate(self.methods_map): shift += 1 if r and prev else 0 prev = r self._unpacksizes.append(unpacksizes[i - shift]) self._unpacked = [0 for _ in range(len(self._unpacksizes))] self.consumed = 0 self._unused = bytearray() self._buf = bytearray() self._pos = 0 # --- if all(self.methods_map): decompressor = self._get_lzma_decompressor(coders, unpacksizes[-1]) self.chain.append(decompressor) elif not any(self.methods_map): for i in range(len(coders)): self.chain.append( self._get_alternative_decompressor(coders[i], unpacksizes[i], password)) elif any(self.methods_map): for i in range(len(coders)): if (not any(self.methods_map[:i])) and all( self.methods_map[i:]): for j in range(i): self.chain.append( self._get_alternative_decompressor( coders[j], unpacksizes[j], password)) self.chain.append( self._get_lzma_decompressor(coders[i:], unpacksizes[i])) break else: for i in range(len(coders)): if self.methods_map[i]: self.chain.append( self._get_lzma_decompressor([coders[i]], unpacksizes[i])) else: self.chain.append( self._get_alternative_decompressor( coders[i], unpacksizes[i], password)) else: raise UnsupportedCompressionMethodError