def downstream_recv(self, data):
try:
enc=data.peek()
if self._iv_dec is None: #receive IV
if len(enc)<BLOCK_SIZE:
return
self._iv_dec=enc[0:BLOCK_SIZE]
if AES is not None:
self.dec_cipher = AES.new(self.aes_key, AES.MODE_CBC, self._iv_dec)
else:
self.dec_cipher = pyaes.AESModeOfOperationCBC(self.aes_key, iv = self._iv_dec)
data.drain(BLOCK_SIZE)
enc=enc[BLOCK_SIZE:]
if not enc:
return
i=0
cleartext=b""
full_block=b""
while True:
if self.size_to_read is None:
if len(enc)<BLOCK_SIZE:
break
self.first_block=self.dec_cipher.decrypt(enc[0:BLOCK_SIZE])
data.drain(BLOCK_SIZE)
self.size_to_read=struct.unpack("<I", self.first_block[0:4])[0]
enc=enc[BLOCK_SIZE:]
if self.size_to_read is None:
break
if self.size_to_read <= len(self.first_block[4:]):
cleartext+=self.first_block[4:4+self.size_to_read] # the remaining data is padding, just drop it
self.size_to_read=None
self.first_block=b""
continue
s=(self.size_to_read-len(self.first_block[4:]))
blocks_to_read=s+(BLOCK_SIZE-(s%BLOCK_SIZE))
if len(enc) < blocks_to_read:
break
full_block=self.first_block[4:]+self.dec_cipher.decrypt(enc[:blocks_to_read])
cleartext+=full_block[0:self.size_to_read] # the remaining data is padding, just drop it
enc=enc[blocks_to_read:]
data.drain(blocks_to_read)
self.size_to_read=None
self.first_block=b""
self.upstream.write(cleartext)
except Exception as e:
logging.debug(traceback.format_exc())
评论列表
文章目录