Beispiel #1
0
 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]
             self.dec_cipher = NewAESCipher(self.aes_key, 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())
Beispiel #2
0
    def downstream_recv(self, data):
        try:
            if self.aes_key is None: #receive aes key
                logger.debug('Read AES Key')

                expected = self.rsa_key_size/8
                if len(data) < expected:
                    logger.debug('Read AES Key: Short read: {} < {}'.format(len(data), expected))
                    return

                cmsg = data.read(expected)

                try:
                    self.aes_key = rsa.decrypt(cmsg, self.pk)
                except rsa.pkcs1.DecryptionError:
                    logger.debug("decrypt failed")
                    self.close()
                    return

                self.enc_cipher = NewAESCipher(self.aes_key, self._iv_enc)
                logger.debug('client AES key received && decrypted from RSA private key')

                self.downstream.write(self._iv_enc) # send IV
                logger.debug('IV (len={}) sent to Client'.format(len(self._iv_enc)))

                if self.buffer:
                    logger.debug('Flush buffer to client')
                    super(RSA_AESServer, self).upstream_recv(self.buffer)
                    self.buffer = None

            super(RSA_AESServer, self).downstream_recv(data)

        except Exception as e:
            logger.debug(e)
Beispiel #3
0
    def downstream_recv(self, data):
        try:
            enc = data.peek()
            if self.aes_key is None:  #receive aes key
                if len(enc) < self.rsa_key_size / 8:
                    return
                cmsg = enc[:self.rsa_key_size / 8]
                try:
                    self.aes_key = rsa.decrypt(cmsg, self.pk)
                except rsa.pkcs1.DecryptionError:
                    self.close()
                    return
                data.drain(self.rsa_key_size / 8)

                self.enc_cipher = NewAESCipher(self.aes_key, self._iv_enc)
                logging.debug(
                    "client AES key received && decrypted from RSA private key"
                )
                self.downstream.write(self._iv_enc)  # send IV
                logging.debug("IV sent to Client")

                for f, args in self.post_handshake_callbacks:
                    f(*args)
                self.post_handshake_callbacks = []
            super(RSA_AESServer, self).downstream_recv(data)
        except Exception as e:
            logging.debug(e)
Beispiel #4
0
    def on_connect(self):
        pk = rsa.PublicKey.load_pkcs1(self.pubkey)
        if Random:
            self.aes_key = Random.new().read(self.key_size)
        else:
            self.aes_key = os.urandom(self.key_size)

        self.enc_cipher = NewAESCipher(self.aes_key, self._iv_enc)
        self.downstream.write(rsa.encrypt(self.aes_key, pk))
        logging.debug("AES key crypted with RSA public key and sent to server")
        self.downstream.write(self._iv_enc)
        logging.debug("IV sent to Server")
 def __init__(self, *args, **kwargs):
     super(AESTransport, self).__init__(*args, **kwargs)
     if "password" in kwargs:
         self.password=kwargs["password"]
     if self.password is None:
         raise TransportError("A password needs to be supplied for AES")
     self._salt = "__PupY_PBKDF2_S4l7__"
     logging.debug("deriving the key with %s iterations..."%self.iterations)
     if PBKDF2 is not None:
         self._derived_key = PBKDF2(self.password, self._salt, self.key_size, self.iterations, prf=lambda password, salt: HMAC.new(password, salt, SHA256).digest())
     else:
         self._derived_key = pbkdf2_bin(self.password, self._salt, keylen=self.key_size, iterations=self.iterations, hashfunc=hashlib.sha256)
     logging.debug("key derived ...")
     if Random:
         self._iv_enc = Random.new().read(BLOCK_SIZE)
     else:
         self._iv_enc = os.urandom(BLOCK_SIZE)
     self.enc_cipher = NewAESCipher(self._derived_key, self._iv_enc)
     self.dec_cipher = None
     self._iv_dec = None
     self.size_to_read=None
     self.first_block=b""
Beispiel #6
0
    def on_connect(self):
        pk = rsa.PublicKey.load_pkcs1(self.pubkey)
        if Random:
            self.aes_key = Random.new().read(self.key_size)
        else:
            self.aes_key = os.urandom(self.key_size)

        self.enc_cipher = NewAESCipher(self.aes_key, self._iv_enc)

        pkey = rsa.encrypt(self.aes_key, pk)
        self.downstream.write(pkey, notify=False)
        logger.debug('AES key crypted with RSA public key and sent to server (len={})'.format(len(pkey)))
        self.downstream.write(self._iv_enc)
        logger.debug('IV (len={}) sent to Server'.format(len(self._iv_enc)))
Beispiel #7
0
 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]
             self.dec_cipher = NewAESCipher(self.aes_key, 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())
Beispiel #8
0
    def downstream_recv(self, data):
        try:
            if __debug__:
                logger.debug('Recv data len={}'.format(len(data)))

            if not self._iv_dec:
                if __debug__:
                    logger.debug('Read IV')

                if len(data) < BLOCK_SIZE:
                    if __debug__:
                        logger.debug('Read IV: Short read: {} < {}'.format(len(data), BLOCK_SIZE))
                    return

                self._iv_dec = data.read(BLOCK_SIZE)
                self.dec_cipher = NewAESCipher(self.aes_key, self._iv_dec)

            while True:
                if not self.size_to_read:
                    if len(data) < BLOCK_SIZE:
                        if __debug__:
                            logger.debug('Read chunk header: Short read: {} < {}'.format(len(data), BLOCK_SIZE))
                        break

                    self.first_block = self.dec_cipher.decrypt(data.read(BLOCK_SIZE))
                    self.size_to_read = struct.unpack_from('<I', self.first_block)[0]

                    if self.size_to_read == 0:
                        raise ValueError('Zero sized chunk')

                    if __debug__:
                        logger.debug('Read chunk header: expect: {}'.format(self.size_to_read))

                if self.size_to_read <= len(self.first_block) - 4:
                    if __debug__:
                        logger.debug('Read chunk: consume small chunk')
                    # the remaining data is padding, just drop it
                    self.upstream.write(self.first_block[4:4+self.size_to_read])
                    self.size_to_read = 0
                    self.first_block = b''
                    continue

                if self.first_block:
                    if __debug__:
                        logger.debug('Read chunk: start: cleartext len = {}'.format(self.size_to_read))

                    self.upstream.write(self.first_block[4:], notify=False)
                    self.size_to_read -= BLOCK_SIZE - 4
                    self.first_block = b''

                s = self.size_to_read

                if s % BLOCK_SIZE:
                    s += BLOCK_SIZE - (s % BLOCK_SIZE)

                lb = len(data)
                lb -= lb % BLOCK_SIZE

                while s and lb:
                    if __debug__:
                        logger.debug('Read chunk: required: {} available: {}'.format(s, lb))

                    to_read = min(s, CHUNK_SIZE)
                    to_read = min(lb, to_read)

                    cleartext = self.dec_cipher.decrypt(data.read(to_read))
                    s -= to_read
                    lb -= to_read

                    if to_read >= self.size_to_read:
                        self.upstream.write(cleartext[:self.size_to_read])
                        self.size_to_read = 0

                        if __debug__:
                            logger.debug('Read chunk: chunk finished')

                    else:
                        self.upstream.write(cleartext, notify=False)
                        self.size_to_read -= to_read

                if not lb:
                    if __debug__:
                        logger.debug('Read chunk: No more data')

                    break

        except:
            logger.debug(traceback.format_exc())
Beispiel #9
0
class RSA_AESTransport(BasePupyTransport):
    """
    Implements a transport that simply apply a RSA_AES to each byte
    """
    password     = None
    iterations   = 1000
    key_size     = 32
    rsa_key_size = 4096
    aes_size     = 256

    __slots__ = (
        'aes_size', 'key_size',
        '_iv_enc', '_iv_dec',
        'enc_cipher', 'dec_cipher',
        'aes_key', 'size_to_read',
        'first_block', 'buffer'
    )

    def __init__(self, *args, **kwargs):
        super(RSA_AESTransport, self).__init__(*args, **kwargs)
        if self.aes_size == 256:
            self.key_size = 32
        elif self.aes_size == 128:
            self.key_size = 16
        else:
            raise TransportError("Only AES 256 and 128 are supported")

        if Random:
            self._iv_enc = Random.new().read(BLOCK_SIZE)
        else:
            self._iv_enc = os.urandom(BLOCK_SIZE)

        self.enc_cipher = None
        self.dec_cipher = None
        self._iv_dec = None
        self.aes_key = None
        self.size_to_read = None
        self.first_block = b""
        self.buffer = Buffer()

    def upstream_recv(self, data):
        try:
            with data:
                lctext = len(data)
                ltotal = lctext + 4
                lremainder = ltotal % BLOCK_SIZE
                if lremainder:
                    ltotal += BLOCK_SIZE - lremainder

                data.insert(struct.pack('<I', lctext))
                data.truncate(ltotal)

                if __debug__:
                    logger.debug('Send: cleartext len = {} padded+header = {}'.format(lctext, len(data)))

                data.write_to(
                    self.downstream,
                    modificator=self.enc_cipher.encrypt,
                    chunk_size=CHUNK_SIZE)

        except Exception as e:
            logger.debug(e)

    def downstream_recv(self, data):
        try:
            if __debug__:
                logger.debug('Recv data len={}'.format(len(data)))

            if not self._iv_dec:
                if __debug__:
                    logger.debug('Read IV')

                if len(data) < BLOCK_SIZE:
                    if __debug__:
                        logger.debug('Read IV: Short read: {} < {}'.format(len(data), BLOCK_SIZE))
                    return

                self._iv_dec = data.read(BLOCK_SIZE)
                self.dec_cipher = NewAESCipher(self.aes_key, self._iv_dec)

            while True:
                if not self.size_to_read:
                    if len(data) < BLOCK_SIZE:
                        if __debug__:
                            logger.debug('Read chunk header: Short read: {} < {}'.format(len(data), BLOCK_SIZE))
                        break

                    self.first_block = self.dec_cipher.decrypt(data.read(BLOCK_SIZE))
                    self.size_to_read = struct.unpack_from('<I', self.first_block)[0]

                    if self.size_to_read == 0:
                        raise ValueError('Zero sized chunk')

                    if __debug__:
                        logger.debug('Read chunk header: expect: {}'.format(self.size_to_read))

                if self.size_to_read <= len(self.first_block) - 4:
                    if __debug__:
                        logger.debug('Read chunk: consume small chunk')
                    # the remaining data is padding, just drop it
                    self.upstream.write(self.first_block[4:4+self.size_to_read])
                    self.size_to_read = 0
                    self.first_block = b''
                    continue

                if self.first_block:
                    if __debug__:
                        logger.debug('Read chunk: start: cleartext len = {}'.format(self.size_to_read))

                    self.upstream.write(self.first_block[4:], notify=False)
                    self.size_to_read -= BLOCK_SIZE - 4
                    self.first_block = b''

                s = self.size_to_read

                if s % BLOCK_SIZE:
                    s += BLOCK_SIZE - (s % BLOCK_SIZE)

                lb = len(data)
                lb -= lb % BLOCK_SIZE

                while s and lb:
                    if __debug__:
                        logger.debug('Read chunk: required: {} available: {}'.format(s, lb))

                    to_read = min(s, CHUNK_SIZE)
                    to_read = min(lb, to_read)

                    cleartext = self.dec_cipher.decrypt(data.read(to_read))
                    s -= to_read
                    lb -= to_read

                    if to_read >= self.size_to_read:
                        self.upstream.write(cleartext[:self.size_to_read])
                        self.size_to_read = 0

                        if __debug__:
                            logger.debug('Read chunk: chunk finished')

                    else:
                        self.upstream.write(cleartext, notify=False)
                        self.size_to_read -= to_read

                if not lb:
                    if __debug__:
                        logger.debug('Read chunk: No more data')

                    break

        except:
            logger.debug(traceback.format_exc())
Beispiel #10
0
class RSA_AESTransport(BasePupyTransport):
    """
    Implements a transport that simply apply a RSA_AES to each byte
    """
    password=None
    iterations=1000
    key_size=32
    rsa_key_size=4096
    aes_size=256
    def __init__(self, *args, **kwargs):
        super(RSA_AESTransport, self).__init__(*args, **kwargs)
        if self.aes_size==256:
            self.key_size=32
        elif self.aes_size==128:
            self.key_size=16
        else:
            raise TransportError("Only AES 256 and 128 are supported")
        if Random:
            self._iv_enc = Random.new().read(BLOCK_SIZE)
        else:
            self._iv_enc = os.urandom(BLOCK_SIZE)
        self.enc_cipher = None
        self.dec_cipher = None
        self._iv_dec = None
        self.aes_key=None
        self.size_to_read=None
        self.first_block=b""

    def upstream_recv(self, data):
        try:
            cleartext=data.peek()
            tosend=b""
            i=0
            packed_size=struct.pack("<I", len(cleartext))
            tosend=packed_size+cleartext
            tosend+=b"\x00"*(BLOCK_SIZE - (len(tosend)%BLOCK_SIZE))
            data.drain(len(cleartext))
            self.downstream.write(self.enc_cipher.encrypt(tosend))
        except Exception as e:
            logging.debug(e)


    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]
                self.dec_cipher = NewAESCipher(self.aes_key, 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())
class AESTransport(BasePupyTransport):
    """
    Implements a transport that simply apply a AES to each byte
    """
    password=None
    iterations=1000
    key_size=32

    def __init__(self, *args, **kwargs):
        super(AESTransport, self).__init__(*args, **kwargs)
        if "password" in kwargs:
            self.password=kwargs["password"]
        if self.password is None:
            raise TransportError("A password needs to be supplied for AES")
        self._salt = "__PupY_PBKDF2_S4l7__"
        logging.debug("deriving the key with %s iterations..."%self.iterations)
        if PBKDF2 is not None:
            self._derived_key = PBKDF2(self.password, self._salt, self.key_size, self.iterations, prf=lambda password, salt: HMAC.new(password, salt, SHA256).digest())
        else:
            self._derived_key = pbkdf2_bin(self.password, self._salt, keylen=self.key_size, iterations=self.iterations, hashfunc=hashlib.sha256)
        logging.debug("key derived ...")
        if Random:
            self._iv_enc = Random.new().read(BLOCK_SIZE)
        else:
            self._iv_enc = os.urandom(BLOCK_SIZE)
        self.enc_cipher = NewAESCipher(self._derived_key, self._iv_enc)
        self.dec_cipher = None
        self._iv_dec = None
        self.size_to_read=None
        self.first_block=b""

    def on_connect(self):
        self.downstream.write(self._iv_enc) # send IV

    def upstream_recv(self, data):
        try:
            cleartext=data.peek()
            tosend=b""
            i=0
            packed_size=struct.pack("<I", len(cleartext))
            tosend=packed_size+cleartext
            tosend+=b"\x00"*(BLOCK_SIZE - (len(tosend)%BLOCK_SIZE))
            data.drain(len(cleartext))
            self.downstream.write(self.enc_cipher.encrypt(tosend))
        except Exception as e:
            logging.debug(e)

    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]
                self.dec_cipher = NewAESCipher(self._derived_key, 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())
Beispiel #12
0
class RSA_AESTransport(BasePupyTransport):
    """
    Implements a transport that simply apply a RSA_AES to each byte
    """
    password = None
    iterations = 1000
    key_size = 32
    rsa_key_size = 4096
    aes_size = 256

    def __init__(self, *args, **kwargs):
        super(RSA_AESTransport, self).__init__(*args, **kwargs)
        if self.aes_size == 256:
            self.key_size = 32
        elif self.aes_size == 128:
            self.key_size = 16
        else:
            raise TransportError("Only AES 256 and 128 are supported")
        if Random:
            self._iv_enc = Random.new().read(BLOCK_SIZE)
        else:
            self._iv_enc = os.urandom(BLOCK_SIZE)
        self.enc_cipher = None
        self.dec_cipher = None
        self._iv_dec = None
        self.aes_key = None
        self.size_to_read = None
        self.first_block = b""

    def on_connect(self):
        self.downstream.write(self._iv_enc)  # send IV
        logging.debug("IV sent to Client")

    def upstream_recv(self, data):
        try:
            cleartext = data.peek()
            tosend = b""
            i = 0
            packed_size = struct.pack("<I", len(cleartext))
            tosend = packed_size + cleartext
            tosend += b"\x00" * (BLOCK_SIZE - (len(tosend) % BLOCK_SIZE))
            data.drain(len(cleartext))
            self.downstream.write(self.enc_cipher.encrypt(tosend))
        except Exception as e:
            logging.debug(e)

    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]
                self.dec_cipher = NewAESCipher(self.aes_key, 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())