Esempio n. 1
0
    def send_handshake_finished(
        self, handshake_keys: HandshakeKeys, handshake_hash: bytes
    ):
        hh_payload = HandshakeFinishedHandshakePayload.generate(
            handshake_keys.client_handshake_traffic_secret, handshake_hash
        )
        hh_header = HandshakeHeader(
            HandshakeFinishedHandshakePayload.default_htype(),
            len(hh_payload.verify_data),
        )
        plaintext_payload = b"".join(
            [hh_header.serialize(), hh_payload.verify_data, b"\x16"]
        )

        record_header = RecordHeader(rtype=0x17, size=len(plaintext_payload) + 16)

        encryptor = AES.new(
            handshake_keys.client_key, AES.MODE_GCM, handshake_keys.client_iv
        )
        encryptor.update(record_header.serialize())
        ciphertext_payload = encryptor.encrypt(plaintext_payload)
        tag = encryptor.digest()

        w = Wrapper(record_header=record_header, payload=ciphertext_payload + tag)
        self.socket.send(w.serialize())
Esempio n. 2
0
    def __init__(self, domain: bytes, public_key_bytes: bytes):
        self.record_header = RecordHeader(
            rtype=0x16, legacy_proto_version=0x0301, size=0
        )
        self.handshake_header = HandshakeHeader(message_type=0x01, size=0)
        self.client_version = 0x0303
        self.client_random = secrets.token_bytes(32)
        self.session_id = secrets.token_bytes(32)
        # hard coded for now...
        # 13 01 - assigned value for TLS_AES_128_GCM_SHA256
        # 13 02 - assigned value for TLS_AES_256_GCM_SHA384
        # 13 03 - assigned value for TLS_CHACHA20_POLY1305_SHA256
        self.cipher_suites = bytes.fromhex("130113021303")

        extensions = [
            ExtensionServerName(domain),
            ExtensionSupportedGroups(),
            ExtensionSignatureAlgorithms(),
            ExtensionKeyShare(public_key_bytes),
            ExtensionPSKKeyExchangeModes(),
            ExtensionSupportedVersions(),
        ]

        self.extension_data = b"".join([ex.serialize() for ex in extensions])
        self.extension_length = len(self.extension_data)
Esempio n. 3
0
    def deserialize(klass, byte_stream: BufferedReader):
        rh = RecordHeader.deserialize(byte_stream.read(5))
        hh = HandshakeHeader.deserialize(byte_stream.read(4))
        server_version, = struct.unpack(">h", byte_stream.read(2))
        server_random = byte_stream.read(32)
        session_id_length, = struct.unpack("b", byte_stream.read(1))
        session_id = byte_stream.read(session_id_length)
        cipher_suite, = struct.unpack(">h", byte_stream.read(2))
        _compression_mode = byte_stream.read(1)
        extensions_length, = struct.unpack(">h", byte_stream.read(2))

        extensions = []
        while extensions_length > 0:
            assigned_value, = struct.unpack(">h", byte_stream.peek()[:2])
            extension_klass = EXTENSIONS_MAP[assigned_value]
            res = extension_klass.deserialize(byte_stream)
            extensions.append(res)
            extensions_length -= res.size + 2

        return ServerHello(
            rh=rh,
            hh=hh,
            server_version=server_version,
            server_random=server_random,
            session_id=session_id,
            cipher_suite=cipher_suite,
            extensions=extensions,
        )
Esempio n. 4
0
    def _recv(self):
        bytes_buffer = BufferedReader(BytesIO(self.socket.recv(4096)))

        if len(bytes_buffer.peek()) < 4:
            bytes_buffer = BufferedReader(
                BytesIO(bytes_buffer.read() + self.socket.recv(4096))
            )
        res = self.__recv(bytes_buffer)
        # while res[-1] != 0x17:
        # count =1
        while True:
            if res[-1] == 0x17:
                yield res[:-1]
            if res[-1] == 0x16:
                plaintext_buffer = BufferedReader(BytesIO(res[:-1]))
                while plaintext_buffer.peek():
                    hh = HandshakeHeader.deserialize(plaintext_buffer.read(4))
                    hh_payload_buffer = plaintext_buffer.read(hh.size)
                    # print("recv", len(hh_payload_buffer), hh.size, hh)
                    # print(res[:-1])
                    hh_payload = HANDSHAKE_HEADER_TYPES[hh.message_type].deserialize(
                        hh_payload_buffer
                    )
                    # print(hh_payload)
                    if type(hh_payload) is NewSessionTicketHandshakePayload:
                        self.session_tickets.append(hh_payload)

            if len(bytes_buffer.peek()) < 4:
                bytes_buffer = BufferedReader(
                    BytesIO(bytes_buffer.read() + self.socket.recv(4096))
                )
            res = self.__recv(bytes_buffer)
Esempio n. 5
0
    def recv_server_encrypted_extensions(self, bytes_buffer) -> bytes:
        def parse_wrapper(bytes_buffer):
            wrapper = Wrapper.deserialize(bytes_buffer)
            while wrapper.record_header.size > len(wrapper.payload):
                wrapper.payload += self.socket.recv(
                    wrapper.record_header.size - len(wrapper.payload))

            recdata = wrapper.record_header.serialize()
            authtag = wrapper.auth_tag

            ciphertext = wrapper.encrypted_data

            decryptor = AES.new(
                self.handshake_keys.server_key,
                AES.MODE_GCM,
                xor_iv(self.handshake_keys.server_iv,
                       self.handshake_recv_counter),
            )
            decryptor.update(recdata)

            plaintext = decryptor.decrypt(bytes(ciphertext))
            self.handshake_recv_counter += 1

            decryptor.verify(authtag)
            return plaintext[:-1]

        plaintext = bytearray()
        plaintext += parse_wrapper(bytes_buffer)
        plaintext_buffer = BufferedReader(BytesIO(plaintext))
        # TODO: change this to walrus operator
        while True:
            if len(plaintext_buffer.peek()) < 4:
                res = parse_wrapper(bytes_buffer)
                plaintext += res
                plaintext_buffer = BufferedReader(
                    BytesIO(plaintext_buffer.peek() + res))

            hh = HandshakeHeader.deserialize(plaintext_buffer.read(4))

            hh_payload_buffer = plaintext_buffer.read(hh.size)
            while len(hh_payload_buffer) < hh.size:
                res = parse_wrapper(bytes_buffer)
                plaintext += res
                plaintext_buffer = BufferedReader(
                    BytesIO(plaintext_buffer.peek() + res))

                prev_len = len(hh_payload_buffer)
                hh_payload_buffer = hh_payload_buffer + plaintext_buffer.read(
                    hh.size - prev_len)

            hh_payload = HANDSHAKE_HEADER_TYPES[hh.message_type].deserialize(
                hh_payload_buffer)

            if type(hh_payload) is HandshakeFinishedHandshakePayload:
                break

        return plaintext
Esempio n. 6
0
class ClientHello:
    def __init__(self, domain: bytes, public_key_bytes: bytes):
        self.record_header = RecordHeader(rtype=0x16,
                                          legacy_proto_version=0x0301,
                                          size=0)
        self.handshake_header = HandshakeHeader(message_type=0x01, size=0)
        self.client_version = 0x0303
        self.client_random = secrets.token_bytes(32)
        self.session_id = secrets.token_bytes(32)
        # hard coded for now...
        # 13 01 - assigned value for TLS_AES_128_GCM_SHA256
        # 13 02 - assigned value for TLS_AES_256_GCM_SHA384
        # 13 03 - assigned value for TLS_CHACHA20_POLY1305_SHA256
        self.cipher_suites = bytes.fromhex("130113021303")

        self.extensions = [
            ExtensionServerName(domain),
            ExtensionSupportedGroups(),
            ExtensionSignatureAlgorithms(),
            ExtensionKeyShare(public_key_bytes),
            ExtensionPSKKeyExchangeModes(),
            ExtensionSupportedVersions(),
        ]

    def add_extension(self, extension: ClientHelloExtension):
        self.extensions.append(extension)

    def calc_record_size(self) -> int:
        data = self._serialize()
        self.record_header.size = len(data) - 5
        self.handshake_header.size = self.record_header.size - 4

    def _serialize(self) -> bytes:
        self.extension_data = b"".join(
            [ex.serialize() for ex in self.extensions])
        self.extension_length = len(self.extension_data)
        return b"".join([
            self.record_header.serialize(),
            self.handshake_header.serialize(),
            struct.pack(">h", self.client_version),
            struct.pack("32s", self.client_random),
            struct.pack("b32s", len(self.session_id), self.session_id),
            struct.pack(
                f">h{len(self.cipher_suites)}s",
                len(self.cipher_suites),
                self.cipher_suites,
            ),
            struct.pack("bb", 1, 0),  # compression mode
            struct.pack(">h", self.extension_length),
            self.extension_data,
        ])

    def serialize(self) -> bytes:
        self.calc_record_size()
        return self._serialize()
Esempio n. 7
0
def test_handshake_headers():
    plaintext = b"\x08\x00\x00\x02\x00\x00\x0b\x00\x0c\x1f\x00\x00\x0c\x1b\x00\x07W0\x82\x07S0\x82\x06;\xa0\x03\x02\x01\x02\x02\x10\x03}\xe4\x06\xf9@+$3\xc5\x95\xbc\x1c\xba\x8f\x880\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x000u1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x150\x13\x06\x03U\x04\n\x13\x0cDigiCert Inc1\x190\x17\x06\x03U\x04\x0b\x13\x10www.digicert.com1402\x06\x03U\x04\x03\x13+DigiCert SHA2 Extended Validation Server CA0\x1e\x17\r181030000000Z\x17\r201103120000Z0\x81\xcf1\x1d0\x1b\x06\x03U\x04\x0f\x0c\x14Private Organization1\x130\x11\x06\x0b+\x06\x01\x04\x01\x827<\x02\x01\x03\x13\x02US1\x190\x17\x06\x0b+\x06\x01\x04\x01\x827<\x02\x01\x02\x13\x08Delaware1\x100\x0e\x06\x03U\x04\x05\x13\x0747108751\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\x08\x13\nCalifornia1\x160\x14\x06\x03U\x04\x07\x13\rSan Francisco1\x190\x17\x06\x03U\x04\n\x13\x10Cloudflare, Inc.1\x170\x15\x06\x03U\x04\x03\x13\x0ecloudflare.com0\x82\x01\"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\x9b\xaaW1\x80\x0815\xbf,\xee\\r\xae\xf9\x16\xdf\x01\xfe\xd9\xcf\xf5\xde=\xe4\xc4J\xa4\xdb\x85m\xb4]\xed2\xee\x98Lfl6\xe1\xdeM\x02\x07\xf6wB.\xbb\xcdG4\xa5\x9e\xba\xd9H5N\x8b\x81\xe9\xe9\xe46\xa6zo\x90t\xf0\x88;h\x9d\xa2\x7fC\xfdZ\xeb\x0e\x98\xbd\x9e#\xb27\x049m\x89~\xe8\x17:B]\x17\xe4\x83!\xf4}\xa2\xf7v\x93y\xe3\xa3_;\xc1Z\x90\xa2a\xb0\x89\xcc\x00U\x8a\x13IY\x06\xe5\xb3\x14\x03N\xfa\xa4tw\x11I\x12\x83B\x07Y\x02\xbaI\x14Qd\x9d[\xca\xa3\xd5\x06\x98\x95\xad\x00\x19B\x1a\xed\xc7\x1a\x96m.\xe7\xf5\xaa\xf4lz\xf3\xf8k]s\x07\xf0\xa0\xe0\x13\x1dv\xddh2p}1\xb6\xda\x96$\x98Q_\x12d;`\xaa\x8d\x0b\xeeHu\x8d\xbe`\xf5\xb8\x86\xd5\xb2\xe8x\tu\xca\x88XM!\x00\xa0\x8c\xe87F\x1d\x98P2-\x89$\x91\x06\xa5;\xbc\xd42w\xfeJC\xec|\xb9\x02\x03\x01\x00\x01\xa3\x82\x03\x820\x82\x03~0\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14=\xd3P\xa5\xd6\xa0\xad\xee\xf3J`\ne\xd3!\xd4\xf8\xf8\xd6\x0f0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\xbe\xb5\xc4\xce\r\xda\xe0T\xfb`S58\x07=;\xa4\x8a\x1e\xe20-\x06\x03U\x1d\x11\x04&0$\x82\x0ecloudflare.com\x82\x12www.cloudflare.com0\x0e\x06\x03U\x1d\x0f\x01\x01\xff\x04\x04\x03\x02\x05\xa00\x1d\x06\x03U\x1d%\x04\x160\x14\x06\x08+\x06\x01\x05\x05\x07\x03\x01\x06\x08+\x06\x01\x05\x05\x07\x03\x020u\x06\x03U\x1d\x1f\x04n0l04\xa02\xa00\x86.http://crl3.digicert.com/sha2-ev-server-g2.crl04\xa02\xa00\x86.http://crl4.digicert.com/sha2-ev-server-g2.crl0K\x06\x03U\x1d \x04D0B07\x06\t`\x86H\x01\x86\xfdl\x02\x010*0(\x06\x08+\x06\x01\x05\x05\x07\x02\x01\x16\x1chttps://www.digicert.com/CPS0\x07\x06\x05g\x81\x0c\x01\x010\x81\x88\x06\x08+\x06\x01\x05\x05\x07\x01\x01\x04|0z0$\x06\x08+\x06\x01\x05\x05\x070\x01\x86\x18http://ocsp.digicert.com0R\x06\x08+\x06\x01\x05\x05\x070\x02\x86Fhttp://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt0\x0c\x06\x03U\x1d\x13\x01\x01\xff\x04\x020\x000\x82\x01\x7f\x06\n+\x06\x01\x04\x01\xd6y\x02\x04\x02\x04\x82\x01o\x04\x82\x01k\x01i\x00w\x00\xa4\xb9\t\x90\xb4\x18X\x14\x87\xbb\x13\xa2\xccgp\n<5\x98\x04\xf9\x1b\xdf\xb8\xe3w\xcd\x0e\xc8\r\xdc\x10\x00\x00\x01f\xc6\x88{\xbf\x00\x00\x04\x03\x00H0F\x02!\x00\xc9\x12\x00\xdb\xcaxb#m\xaeQ\x0ee\xd5\xbdB\x1d\xec\x14\xd7o\xa2S\x02\x95\xe6\xf7\x06\xdc\xfc\x89\x9e\x02!\x00\xe7W\xf5\xbd]Z=\x9e\xae?0\n\x99\x13\xd6\x99\xbc\xd87\x0b\x83TXJ\xcc\xee\xf0<\x1c\xc6\xb3*\x00v\x00\x87u\xbf\xe7Y|\xf8\x8cC\x99_\xbd\xf3n\xffV\x8dGV6\xffJ\xb5`\xc1\xb4\xea\xff^\xa0\x83\x0f\x00\x00\x01f\xc6\x88}\x8e\x00\x00\x04\x03\x00G0E\x02!\x00\xacF43\x9e\xcd\xe6'a\x0e\x04R\xcb\x19%m\xfe\xe9\x88\xb9\xf2S[5V\x11\x8c\x03`-\x9e\xcf\x02 \\\xca\xaa\xdc\xb5\x1b\xb7\x0eX\xdb\x03\xa7&\x9d\xc4\x1bE\x9b*s\x893\x97\xee\xf3\xea\xf3\x15\xa5\xcd\xed?\x00v\x00\xeeK\xbd\xb7u\xce`\xba\xe1Bi\x1f\xab\xe1\x9ef\xa3\x0f~_\xb0r\xd8\x83\x00\xc4{\x89z\xa8\xfd\xcb\x00\x00\x01f\xc6\x88|\x0c\x00\x00\x04\x03\x00G0E\x02!\x00\xf0\x9b\xe0\x08\x9c\x0cpk\xf9\x88OU\xf8\x8c\x19\xd7\xe9\x8e\xbbi\x97\x7f\x8d}\xc9c\x92\r\xb5h7\xf9\x02 :/p\x94`\xbc5\x00Y\xa8\xafb\xb5[X>0\xdb#d\xf1$\xf5\xa2o\xfb\xdff\xda]\xb7B0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x88\xdd\x9b\xebN\x84\xb6-\xdc\x0c\xe5\x132M\xf9Q\x94\xae0\x92\x8e\xaf\xfd\x81Z\x86V|kR\xf19\x98\x16Oc@,\xfag\x00Ya\x94\xcb\x8c\xd5\x12H6|]\xa0\x95\xfb/0 j\xd8\x1e'\xc4u\n*\xfd\xaf\xaa;\xf8\x8e\xf8>\x83\xe598l\xc7\x87\x18\xb57\x82\x85\xcd0I\xb2\xd5\x129\r\xb6\x16\x1c\x95\x1aGyX\x9c\xb7\xe1\xe8\xfb\xa6\xbf\xc7\xa8\xee\x9f\xceC\xdf\xe9s\xff\xc5\n\xac\xb1\x9f\xdd\xab\xd7\xb7/rT\xf2\xe4\xed\xcb\\9\xb31\x81\xc0\x0f\xef\x91'\x9a\ra\x9f\xd3\xcd#*li\xcf\x0e\x0cS\x04~IK\\\xe9\xc9\x9dDT\x99\xa7\\\x95\x06\x0bn\x83L\x0b^\xed\x02D\x10\x88\xff\xf5gH\xd1J!@\xcf\xbe\xa1\xe1\xba|.\xd10U\xf0\xbd0\x1c~\x05]B\x97R\x00\xb8(\xfdWB\xdc\xa5\x8d\x14\xd1A\x06/\xf4+\x1f\xf0\xc5\xc1\xc9\xb0y\xa6E>\xb0\x8b%S\xd0}e\xfb\xb8n\xc9G/A\xc6&S\x00\x00\x00\x04\xba0\x82\x04\xb60\x82\x03\x9e\xa0\x03\x02\x01\x02\x02\x10\x0cy\xa9D\xb0\x8c\x11\x95 \x92a_\xe2k\x1d\x830\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x000l1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x150\x13\x06\x03U\x04\n\x13\x0cDigiCert Inc1\x190\x17\x06\x03U\x04\x0b\x13\x10www.digicert.com1+0)\x06\x03U\x04\x03\x13\"DigiCert High Assurance EV Root CA0\x1e\x17\r131022120000Z\x17\r281022120000Z0u1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x150\x13\x06\x03U\x04\n\x13\x0cDigiCert Inc1\x190\x17\x06\x03U\x04\x0b\x13\x10www.digicert.com1402\x06\x03U\x04\x03\x13+DigiCert SHA2 Extended Validation Server CA0\x82\x01\"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xd7S\xa4\x04Q\xf8\x99\xa6\x16HKg'\xaa\x93I\xd09\xed\x0c\xb0\xb0\x00\x87\xf1g(\x86\x85\x8c\x8ec\xda\xbc\xb1@8\xe2\xd3\xf5\xec\xa5\x05\x18\xb8=>\xc5\x99\x172\xec\x18\x8c\xfa\xf1\x0c\xa6d!\x85\xcb\x07\x104\xb0R\x88+\x1fh\x9b\xd2\xb1\x8f\x12\xb0\xb3\xd2\xe7\x88\x1f\x1f\xef8wTS_\x80y?.\x1a\xaa\xa8\x1eK+\r\xab\xb7c\xb95\xb7}\x14\xbcYK\xdfQJ\xd2\xa1\xe2\x0c\xe2\x90\x82\x87j\xae\xea\xd7d\xd6\x98U\xe8\xfd\xaf\x1aPlT\xbc\x11\xf2\xfdJ\xf2\x9d\xbb\x7f\x0e\xf4\xd5\xbe\x8e\x16\x89\x12U\xd8\xc0q4\xee\xf6\xdc-\xec\xc4\x87%\x86\x8d\xd8!\xe4\xb0M\x0c\x89\xdc9&\x17\xdd\xf6\xd7\x94\x85\xd8\x04!p\x9doo\xff\\\xba\x19\xe1E\xcbVW(~\x1c\rAW\xaa\xb7\xb8'\xbb\xb1\xe4\xfa*\xef!#u\x1a\xad-\x9b\x865\x8c\x9cw\xb5s\xad\xd8\x94-\xe4\xf3\x0c\x9d\xee\xc1Nb~\x17\xc0q\x9e,\xde\xf1\xf9\x10(\x193\x02\x03\x01\x00\x01\xa3\x82\x01I0\x82\x01E0\x12\x06\x03U\x1d\x13\x01\x01\xff\x04\x080\x06\x01\x01\xff\x02\x01\x000\x0e\x06\x03U\x1d\x0f\x01\x01\xff\x04\x04\x03\x02\x01\x860\x1d\x06\x03U\x1d%\x04\x160\x14\x06\x08+\x06\x01\x05\x05\x07\x03\x01\x06\x08+\x06\x01\x05\x05\x07\x03\x0204\x06\x08+\x06\x01\x05\x05\x07\x01\x01\x04(0&0$\x06\x08+\x06\x01\x05\x05\x070\x01\x86\x18http://ocsp.digicert.com0K\x06\x03U\x1d\x1f\x04D0B0@\xa0>\xa0<\x86:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl0=\x06\x03U\x1d \x0460402\x06\x04U\x1d \x000*0(\x06\x08+\x06\x01\x05\x05\x07\x02\x01\x16\x1chttps://www.digicert.com/CPS0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14=\xd3P\xa5\xd6\xa0\xad\xee\xf3J`\ne\xd3!\xd4\xf8\xf8\xd6\x0f0\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14\xb1>\xc3i\x03\xf8\xbfG\x01\xd4\x98&\x1a\x08\x02\xefcd+\xc30\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x9d\xb6\xd0\x90\x86\xe1\x86\x02\xed\xc5\xa0\xf04\x1ct\xc1\x8dv\xcc\x86\n\xa8\xf0J\x8aB\xd6?\xc8\xa9M\xad|\x08\xad\xe6\xb6P\xb8\xa2\x1aM\x88\x07\xb1)!\xdc\xe7\xda\xc6<!\xe0\xe3\x11Ip\xacz\x1d\x01\xa4\xca\x11:W\xab}W*@t\xfd\xd3\x1d\x85\x18P\xdfWGu\xa1}U .G7Pr\x8c\x7f\x82\x1b\xd2b\x8f-\x03Z\xda\xc3\xc8\xa1\xce,R\xa2\x00c\xebs\xbaq\xc8I'#\x97d\x85\x9e8\x0e\xadch<\xbaR\x81Xy\xa3,\x0c\xdf\xdem\xeb1\xf2\xba\xa0|l\xf1,\xd4\xe1\xbdw\x847\x03\xce2\xb5\xc8\x9a\x81\x1aJ\x92N;F\x9a\x85\xfe\x83\xa2\xf9\x9e\x8c\xa3\xcc\r^\xb3=\xcf\x04x\x8f\x14\x14{2\x9c\xc7\x00\xa6\\\xc4\xb5\xa1U\x8dZVh\xa4\"p\xaa<\x81q\xd9\x9d\xa8E;\xf4\xe5\xf6\xa2Q\xdd\xc7{b\xe8o\x0ct\xeb\xb8\xda\xf8\xbf\x87\ryP\x91\x90\x9b\x18;\x91Y'\xf15(\x13\xab&~\xd5\xf7z\x00\x00\x0f\x00\x01\x04\x08\x04\x01\x00\x17\xe2L\x95\xdb\xce\xa4\x96\xc8\xd6\x9b\xd4\x1c\x00\xc3\xb4\xfa\xdfY\"i\x13\xf7\x8e%\xc0\x8d),1\xcfo\xfe\xbd%\xa8p\xdc\x8c7P,\xdc\xd3O\xa7ocH\\\xf0\x9f\xb5[\xcf\x15\x08|Y\x12!\xfd\x03\xf6mD\xcab\xb3b9\xf3;tS\xee:\x93\x9a\x81\xfa\xd3Wv\"}\xbfE\xff\x8b\xb8\xf3\xf5\xdc\x0f?\x1e\x8f\x8c5\x10\xd5\xcc\xb4(^\xf5\xaa\xcb\xbe\x9f\x97\xdbe\xfc\x86('\xdc\x04\x8b\r\xdcV\xf4\x17O\n\xae|l\x06\xcbM&\x147\x10N\xe6\xb4\\\xbe\xae\xa7\xba\xca=\xbf*\x9f\xc1\xd1\xba\xeds\xa5\xfel\xbf\x1e\xe6r\x17\xdb\xa4x\x9b\x8a0)\xa31ef\x83\xec`\xa8\xb8-\xe2\x0f`\xae\x11\x03\xd2\x15n\x9b%\xe9P&\\3D\x96\xc6b!\x0f@}=Ft1\xfe\x0e\xccK\xe1\xdaE\x1e\xee\xa1\x95i\x06\xa6\x9b@k^\xff<\x10\x85\xbb\x16\"\xcf;i\x8ft\x10\xf3(\xcc\xc7!\xe9\xd8\x93m7s\xf7\xb1J\xcd-\x14\x00\x00 \xe4\x85\xf1\x7fL\x7f\x91Z\x03\xc08\xa3\x88\x83{\x18\xb2\x98Q\x13x\xb0_\xe60A\x0e:+\xd6Hp\x16"
    plaintext_buffer = BytesIO(plaintext)
    # TODO: change this to walrus operator
    while plaintext_buffer.tell() < len(plaintext) - 1:
        hh = HandshakeHeader.deserialize(plaintext_buffer.read(4))
        hh_payload_buffer = plaintext_buffer.read(hh.size)
        hh_payload = HANDSHAKE_HEADER_TYPES[hh.message_type].deserialize(
            hh_payload_buffer)
        assert issubclass(type(hh_payload), HandshakePayload)
        assert len(hh_payload.data) == hh.size
Esempio n. 8
0
    def recv_server_encrypted_extensions(self, bytes_buffer) -> bytes:
        def parse_wrapper(bytes_buffer):
            wrapper = Wrapper.deserialize(bytes_buffer)
            while wrapper.record_header.size > len(wrapper.payload):
                wrapper.payload += self.socket.recv(
                    wrapper.record_header.size - len(wrapper.payload)
                )

            recdata = wrapper.record_header.serialize()
            authtag = wrapper.auth_tag

            ciphertext = wrapper.encrypted_data

            decryptor = AES.new(
                self.handshake_keys.server_key,
                AES.MODE_GCM,
                xor_iv(self.handshake_keys.server_iv, self.handshake_recv_counter),
            )
            decryptor.update(recdata)

            plaintext = decryptor.decrypt(bytes(ciphertext))
            self.handshake_recv_counter += 1

            decryptor.verify(authtag)
            return plaintext[:-1]

        plaintext = bytearray()
        plaintext += parse_wrapper(bytes_buffer)
        plaintext_buffer = BufferedReader(BytesIO(plaintext))
        # TODO: change this to walrus operator
        while True:
            # print("difference 1", plaintext_buffer.tell() < len(plaintext))
            hh = HandshakeHeader.deserialize(plaintext_buffer.read(4))
            # print("hh", hh)
            hh_payload_buffer = plaintext_buffer.read(hh.size)
            while len(hh_payload_buffer) < hh.size:
                res = parse_wrapper(bytes_buffer)
                plaintext += res
                plaintext_buffer = BufferedReader(
                    BytesIO(plaintext_buffer.peek() + res)
                )

                prev_len = len(hh_payload_buffer)
                hh_payload_buffer = hh_payload_buffer + plaintext_buffer.read(
                    hh.size - prev_len
                )

            #     # print("difference", hh.size - len(hh_payload_buffer))
            #     new_bytes = parse_wrapper(bytes_buffer)
            #     index = plaintext_buffer.tell()
            #     plaintext_buffer.seek(0, 2)
            #     plaintext_buffer.write(new_bytes)
            #     plaintext_buffer.seek(index)
            #     hh_payload_buffer = hh_payload_buffer + plaintext_buffer.read(hh.size - len(hh_payload_buffer))
            # print("updated plaintext_buffer!!!")
            # print(bytes(plaintext_buffer.getbuffer()))
            # raise Exception("We need more data!!!")
            hh_payload = HANDSHAKE_HEADER_TYPES[hh.message_type].deserialize(
                hh_payload_buffer
            )
            # print("hh_payload", len(hh_payload.data), hh, type(hh_payload))
            if type(hh_payload) is HandshakeFinishedHandshakePayload:
                break

        # print("done!!")
        return plaintext
Esempio n. 9
0
def test_HandshakeHeader():
    hh = HandshakeHeader.deserialize(bytes.fromhex("02000076"))
    assert hh.size == 0x76
    assert hh.message_type == 0x02
Esempio n. 10
0
def test_handshake_header_serialize():
    packet = bytes.fromhex("14000020")
    hh = HandshakeHeader.deserialize(packet)
    assert hh.serialize() == packet