Esempio n. 1
0
    def post_send(self, status):
        cipher_suite = status.cipher
        if self.extended_master_secret is None:
            self.extended_master_secret = status.extended_master_secret

        if not status.resuming:
            if self.extended_master_secret:
                master_secret = \
                    calcExtendedMasterSecret(status.version,
                                             cipher_suite,
                                             status.premaster_secret,
                                             status.handshake_hashes)
            else:
                master_secret = calcMasterSecret(status.version, cipher_suite,
                                                 status.premaster_secret,
                                                 status.client_random,
                                                 status.server_random)

            status.master_secret = master_secret

            # in case of resumption, the pending states are generated
            # during receive of server sent CCS
            calc_pending_states(status)

        status.msg_sock.changeWriteState()
    def to_bytes(self):
        [client_hello] = [
            msg.body for msg in self.handshake_messages
            if msg.handshake_type == HandshakeType.client_hello
        ]
        [server_hello] = [
            msg.body for msg in self.handshake_messages
            if msg.handshake_type == HandshakeType.server_hello
        ]

        negotiated_version = server_hello.version
        negotiated_version = negotiated_version.to_bytes(2, byteorder="big")
        negotiated_version = (negotiated_version[0], negotiated_version[1])
        negotiated_cipher_suite = server_hello.cipher_suite

        handshake_messages = EMPTY_BYTES.join(
            [m.to_bytes() for m in self.handshake_messages])

        master_secret = calcMasterSecret(
            negotiated_version,
            negotiated_cipher_suite,
            self.pre_master_secret,
            client_hello.random_bytes,
            server_hello.random_bytes,
        )
        finished = PRF(
            master_secret,
            self.FINISHED_LABEL,
            MD5(handshake_messages) + SHA1(handshake_messages),
            12,
        )
        return bytes.fromhex("00" * 48)  # doesn't matter
Esempio n. 3
0
    def post_send(self, status):
        """Generate new encryption keys for connection."""
        cipher_suite = status.cipher
        status.msg_sock.encryptThenMAC = status.encrypt_then_mac
        if self.extended_master_secret is None:
            self.extended_master_secret = status.extended_master_secret

        if not status.resuming:
            if self.extended_master_secret:
                # in case client certificates are used, we need to omit
                # certificate verify message
                hh = status.certificate_verify_handshake_hashes
                if not hh:
                    hh = status.handshake_hashes
                master_secret = \
                    calcExtendedMasterSecret(status.version,
                                             cipher_suite,
                                             status.premaster_secret,
                                             hh)
            else:
                master_secret = calcMasterSecret(status.version,
                                                 cipher_suite,
                                                 status.premaster_secret,
                                                 status.client_random,
                                                 status.server_random)

            status.master_secret = master_secret

            # in case of resumption, the pending states are generated
            # during receive of server sent CCS
            calc_pending_states(status)

        status.msg_sock.changeWriteState()
    def test_with_empty_values(self):
        ret = calcMasterSecret((3, 3), 0, bytearray(48), bytearray(32),
                               bytearray(32))

        self.assertEqual(bytearray(
            b'I\xcf\xae\xe5[\x86\x92\xd3\xbbm\xd6\xeekSo/' +
            b'\x17\xaf\xbc\x84\x18\tGc\xbc\xb5\xbe\xd6\xb0\x05\xad\xf8' +
            b'\x88\xd0`\xe4\x8c^\xb2&ls\xcb\x1a=-Kh'
            ), ret)
        self.assertEqual(48, len(ret))
    def test_with_empty_values(self):
        ret = calcMasterSecret((3, 3), 0, bytearray(48), bytearray(32),
                               bytearray(32))

        self.assertEqual(
            bytearray(
                b'I\xcf\xae\xe5[\x86\x92\xd3\xbbm\xd6\xeekSo/' +
                b'\x17\xaf\xbc\x84\x18\tGc\xbc\xb5\xbe\xd6\xb0\x05\xad\xf8' +
                b'\x88\xd0`\xe4\x8c^\xb2&ls\xcb\x1a=-Kh'), ret)
        self.assertEqual(48, len(ret))
Esempio n. 6
0
    def post_send(self, status):
        cipher_suite = status.cipher

        master_secret = calcMasterSecret(status.version, cipher_suite,
                                         status.premaster_secret,
                                         status.client_random,
                                         status.server_random)

        status.master_secret = master_secret

        status.msg_sock.calcPendingStates(cipher_suite, master_secret,
                                          status.client_random,
                                          status.server_random, None)

        status.msg_sock.changeWriteState()
Esempio n. 7
0
    def post_send(self, status):
        cipher_suite = status.cipher

        master_secret = calcMasterSecret(status.version,
                                         cipher_suite,
                                         status.premaster_secret,
                                         status.client_random,
                                         status.server_random)

        status.master_secret = master_secret

        status.msg_sock.calcPendingStates(cipher_suite,
                                          master_secret,
                                          status.client_random,
                                          status.server_random,
                                          None)

        status.msg_sock.changeWriteState()
Esempio n. 8
0
    def post_send(self, status):
        cipher_suite = status.cipher

        if not status.resuming:
            master_secret = calcMasterSecret(status.version,
                                             cipher_suite,
                                             status.premaster_secret,
                                             status.client_random,
                                             status.server_random)

            status.master_secret = master_secret

            # in case of resumption, the pending states are generated
            # during receive of server sent CCS
            status.msg_sock.calcPendingStates(cipher_suite,
                                              master_secret,
                                              status.client_random,
                                              status.server_random,
                                              None)

        status.msg_sock.changeWriteState()
Esempio n. 9
0
def handshakeProxy(c_conn, s_conn, oracle):
    s_conn._handshakeStart(client=False)
    c_conn._handshakeStart(client=True)

    s_settings = HandshakeSettings()
    c_settings = HandshakeSettings()

    # CLIENT HELLO          C -> S
    for result in s_conn._getMsg(ContentType.handshake,
                                 HandshakeType.client_hello):
        if result in (0, 1): yield result
        else: break
    clientHello = result

    c_conn.version = (3, 1)  # Hardcoded version

    for result in c_conn._sendMsg(clientHello):
        yield result

    # Send Server Hello, Certificate and Server Hello Done in one packet
    s_conn.sock.buffer_writes = True

    # SERVER HELLO           S -> C
    for result in c_conn._getMsg(ContentType.handshake,
                                 HandshakeType.server_hello):
        if result in (0, 1): yield result
        else: break
    serverHello = result

    s_conn.version = serverHello.server_version
    cipherSuite = serverHello.cipher_suite

    for result in s_conn._sendMsg(serverHello):
        yield result

    # CERTIFICATE           S -> C
    for result in c_conn._getMsg(
            ContentType.handshake, HandshakeType.certificate,
            serverHello.certificate_type):  # FIXME : we should only allow RSA
        if result in (0, 1): yield result
        else: break
    serverCertificate = result

    for result in s_conn._sendMsg(serverCertificate):
        yield result

    # CERTIFICATE REQUEST   S -> C
    if 0:
        for result in c_conn._getMsg(ContentType.handshake,
                                     HandshakeType.certificate_request):
            if result in (0, 1): yield result
            else: break
        certificate_request = result

        for result in s_conn._sendMsg(certificate_request):
            yield result

    # SERVER HELLO DONE     S -> C
    for result in c_conn._getMsg(ContentType.handshake,
                                 HandshakeType.server_hello_done):
        if result in (0, 1): yield result
        else: break
    serverHelloDone = result

    for result in s_conn._sendMsg(serverHelloDone):
        yield result

    s_conn.sock.flush()
    s_conn.sock.buffer_writes = False

    # Send Client Key Exchange, Change Cipher Spec, Finished in one message
    c_conn.sock.buffer_writes = True

    # CERTIFICATE           C -> S
    if 0:
        for result in s_conn._getMsg(ContentType.handshake,
                                     HandshakeType.certificate,
                                     serverHello.certificate_type
                                     ):  # FIXME : we should allow anything ?
            if result in (0, 1): yield result
            else: break
        clientCertificate = result

        for result in c_conn._sendMsg(clientCertificate):
            yield result

    # CLIENT KEY EXCHANGE   C -> S
    for result in s_conn._getMsg(ContentType.handshake,
                                 HandshakeType.client_key_exchange,
                                 cipherSuite):
        if result in (0, 1): yield result
        else: break
    clientKeyExchange = result

    # Ask the oracle if we continue
    epms = clientKeyExchange.encryptedPreMasterSecret
    if not oracle(epms):
        # YOU SHALL NOT PASS !
        print("Shall not pass")
        return

    print("Decoding phase")

    # Decrypt master key
    dec = subprocess.Popen(['./decrypt', '{}:{}'.format(*oracleaddr), cert],
                           stdin=subprocess.PIPE,
                           stdout=subprocess.PIPE)
    dec.stdin.write(hexlify(epms) + b'\n')
    dec.stdin.close()
    res = dec.stdout.readline().strip().split()[-1]
    dec.stdout.close()
    print(res)
    premasterSecret = unhexlify(res)

    # If it's ok, continue
    for result in c_conn._sendMsg(clientKeyExchange):
        yield result

    settings = HandshakeSettings()

    masterSecret = calcMasterSecret(c_conn.version, cipherSuite,
                                    premasterSecret, clientHello.random,
                                    serverHello.random)

    print(masterSecret)

    s_conn._calcPendingStates(cipherSuite, masterSecret, clientHello.random,
                              serverHello.random,
                              settings.cipherImplementations)
    c_conn._calcPendingStates(cipherSuite, masterSecret, clientHello.random,
                              serverHello.random,
                              settings.cipherImplementations)

    print('foobar')

    # CHANGE-CIPHER-SPEC   C -> S
    for result in s_conn._getMsg(ContentType.change_cipher_spec):
        if result in (0, 1):
            yield result
    s_changeCipherSpec = result
    for result in c_conn._sendMsg(s_changeCipherSpec):
        yield result

    s_conn._changeReadState()
    c_conn._changeWriteState()

    # SERVER-FINISHED   C -> S
    for result in s_conn._getMsg(ContentType.handshake,
                                 HandshakeType.finished):
        if result in (0, 1):
            yield result
    server_finished = result
    for result in c_conn._sendMsg(server_finished):
        yield result

    c_conn.sock.flush()
    c_conn.sock.buffer_writes = False

    # Send New Session Ticket, Change Cipher Spec, Finished in one message
    s_conn.sock.buffer_writes = True

    # NEW-SESSION-TICKET
    for result in c_conn._getMsg(ContentType.handshake,
                                 HandshakeType.new_session_ticket):
        if result in (0, 1):
            yield result
    newSessionTicket = result
    for result in s_conn._sendMsg(newSessionTicket):
        yield result

    # CHANGE-CIPHER-SPEC
    for result in c_conn._getMsg(ContentType.change_cipher_spec):
        if result in (0, 1):
            yield result
    c_changeCipherSpec = result
    for result in s_conn._sendMsg(c_changeCipherSpec):
        yield result

    c_conn._changeReadState()
    s_conn._changeWriteState()

    # SERVER-FINISHED
    for result in c_conn._getMsg(ContentType.handshake,
                                 HandshakeType.finished):
        if result in (0, 1):
            yield result
    client_finished = result
    for result in s_conn._sendMsg(client_finished):
        yield result

    s_conn.sock.flush()
    s_conn.sock.buffer_writes = False

    c_conn._handshakeDone(False)
    s_conn._handshakeDone(False)

    cont = True
    while cont:
        for c_data, s_data in zip(c_conn.readAsync(), s_conn.readAsync()):
            if c_data in (0, 1):
                yield c_data
            elif not c_data:
                # End connection
                print('server ended')
                cont = False
            else:
                print('c', c_data)
                for result in s_conn.writeAsync(c_data):
                    yield result
            if s_data in (0, 1):
                yield s_data
            elif not s_data:
                # End connection
                print('client ended')
                cont = False
            else:
                print('s', s_data)
                for result in c_conn.writeAsync(s_data):
                    yield result

    c_conn.close()
    s_conn.close()

    print("The end")
Esempio n. 10
0
    def test_full_connection_with_external_server(self):

        # TODO test is slow (100ms) move to integration test suite
        #
        # start a regular TLS server locally before running this test
        # e.g.: openssl s_server -key localhost.key -cert localhost.crt

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect(("127.0.0.1", 4433))

        record_layer = TLSRecordLayer(sock)

        record_layer._handshakeStart(client=True)
        record_layer.version = (3, 3)

        client_hello = ClientHello()
        client_hello = client_hello.create(
            (3, 3), bytearray(32), bytearray(0),
            [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA], None, None, False,
            False, None)

        for result in record_layer._sendMsg(client_hello):
            if result in (0, 1):
                raise Exception("blocking socket")

        for result in record_layer._getMsg(ContentType.handshake,
                                           HandshakeType.server_hello):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_hello = result
        self.assertEqual(ServerHello, type(server_hello))

        for result in record_layer._getMsg(ContentType.handshake,
                                           HandshakeType.certificate,
                                           CertificateType.x509):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_certificate = result
        self.assertEqual(Certificate, type(server_certificate))

        for result in record_layer._getMsg(ContentType.handshake,
                                           HandshakeType.server_hello_done):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_hello_done = result
        self.assertEqual(ServerHelloDone, type(server_hello_done))

        public_key = server_certificate.cert_chain.getEndEntityPublicKey()

        premasterSecret = bytearray(48)
        premasterSecret[0] = 3  # 'cause we negotiatied TLSv1.2
        premasterSecret[1] = 3

        encryptedPreMasterSecret = public_key.encrypt(premasterSecret)

        client_key_exchange = ClientKeyExchange(
            CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, (3, 3))
        client_key_exchange.createRSA(encryptedPreMasterSecret)

        for result in record_layer._sendMsg(client_key_exchange):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        master_secret = calcMasterSecret(
            (3, 3), CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, premasterSecret,
            client_hello.random, server_hello.random)

        record_layer._calcPendingStates(
            CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, master_secret,
            client_hello.random, server_hello.random, None)

        for result in record_layer._sendMsg(ChangeCipherSpec()):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        record_layer._changeWriteState()

        handshake_hashes = record_layer._handshake_hash.digest('sha256')
        verify_data = PRF_1_2(master_secret, b'client finished',
                              handshake_hashes, 12)

        finished = Finished((3, 3)).create(verify_data)
        for result in record_layer._sendMsg(finished):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        for result in record_layer._getMsg(ContentType.change_cipher_spec):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        change_cipher_spec = result
        self.assertEqual(ChangeCipherSpec, type(change_cipher_spec))

        record_layer._changeReadState()

        handshake_hashes = record_layer._handshake_hash.digest('sha256')
        server_verify_data = PRF_1_2(master_secret, b'server finished',
                                     handshake_hashes, 12)

        for result in record_layer._getMsg(ContentType.handshake,
                                           HandshakeType.finished):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_finished = result
        self.assertEqual(Finished, type(server_finished))
        self.assertEqual(server_verify_data, server_finished.verify_data)

        record_layer._handshakeDone(resumed=False)

        record_layer.write(bytearray(b'text\n'))

        record_layer.close()
Esempio n. 11
0
    def test_full_connection_with_RSA_kex(self):

        clnt_sock, srv_sock = socket.socketpair()

        #
        # client part
        #
        record_layer = TLSRecordLayer(clnt_sock)

        record_layer._handshakeStart(client=True)
        record_layer.version = (3, 3)

        client_hello = ClientHello()
        client_hello = client_hello.create(
            (3, 3), bytearray(32), bytearray(0),
            [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA], None, None, False,
            False, None)

        for result in record_layer._sendMsg(client_hello):
            if result in (0, 1):
                raise Exception("blocking socket")

        #
        # server part
        #

        srv_record_layer = TLSRecordLayer(srv_sock)

        srv_raw_certificate = str(
            "-----BEGIN CERTIFICATE-----\n"\
            "MIIB9jCCAV+gAwIBAgIJAMyn9DpsTG55MA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV\n"\
            "BAMMCWxvY2FsaG9zdDAeFw0xNTAxMjExNDQzMDFaFw0xNTAyMjAxNDQzMDFaMBQx\n"\
            "EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA\n"\
            "0QkEeakSyV/LMtTeARdRtX5pdbzVuUuqOIdz3lg7YOyRJ/oyLTPzWXpKxr//t4FP\n"\
            "QvYsSJiVOlPk895FNu6sNF/uJQyQGfFWYKkE6fzFifQ6s9kssskFlL1DVI/dD/Zn\n"\
            "7sgzua2P1SyLJHQTTs1MtMb170/fX2EBPkDz+2kYKN0CAwEAAaNQME4wHQYDVR0O\n"\
            "BBYEFJtvXbRmxRFXYVMOPH/29pXCpGmLMB8GA1UdIwQYMBaAFJtvXbRmxRFXYVMO\n"\
            "PH/29pXCpGmLMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAkOgC7LP/\n"\
            "Rd6uJXY28HlD2K+/hMh1C3SRT855ggiCMiwstTHACGgNM+AZNqt6k8nSfXc6k1gw\n"\
            "5a7SGjzkWzMaZC3ChBeCzt/vIAGlMyXeqTRhjTCdc/ygRv3NPrhUKKsxUYyXRk5v\n"\
            "g/g6MwxzXfQP3IyFu3a9Jia/P89Z1rQCNRY=\n"\
            "-----END CERTIFICATE-----\n"\
            )

        srv_raw_key = str(
            "-----BEGIN RSA PRIVATE KEY-----\n"\
            "MIICXQIBAAKBgQDRCQR5qRLJX8sy1N4BF1G1fml1vNW5S6o4h3PeWDtg7JEn+jIt\n"\
            "M/NZekrGv/+3gU9C9ixImJU6U+Tz3kU27qw0X+4lDJAZ8VZgqQTp/MWJ9Dqz2Syy\n"\
            "yQWUvUNUj90P9mfuyDO5rY/VLIskdBNOzUy0xvXvT99fYQE+QPP7aRgo3QIDAQAB\n"\
            "AoGAVSLbE8HsyN+fHwDbuo4I1Wa7BRz33xQWLBfe9TvyUzOGm0WnkgmKn3LTacdh\n"\
            "GxgrdBZXSun6PVtV8I0im5DxyVaNdi33sp+PIkZU386f1VUqcnYnmgsnsUQEBJQu\n"\
            "fUZmgNM+bfR+Rfli4Mew8lQ0sorZ+d2/5fsM0g80Qhi5M3ECQQDvXeCyrcy0u/HZ\n"\
            "FNjIloyXaAIvavZ6Lc6gfznCSfHc5YwplOY7dIWp8FRRJcyXkA370l5dJ0EXj5Gx\n"\
            "udV9QQ43AkEA34+RxjRk4DT7Zo+tbM/Fkoi7jh1/0hFkU5NDHweJeH/mJseiHtsH\n"\
            "KOcPGtEGBBqT2KNPWVz4Fj19LiUmmjWXiwJBAIBs49O5/+ywMdAAqVblv0S0nweF\n"\
            "4fwne4cM+5ZMSiH0XsEojGY13EkTEon/N8fRmE8VzV85YmkbtFWgmPR85P0CQQCs\n"\
            "elWbN10EZZv3+q1wH7RsYzVgZX3yEhz3JcxJKkVzRCnKjYaUi6MweWN76vvbOq4K\n"\
            "G6Tiawm0Duh/K4ZmvyYVAkBppE5RRQqXiv1KF9bArcAJHvLm0vnHPpf1yIQr5bW6\n"\
            "njBuL4qcxlaKJVGRXT7yFtj2fj0gv3914jY2suWqp8XJ\n"\
            "-----END RSA PRIVATE KEY-----\n"\
            )

        srv_private_key = parsePEMKey(srv_raw_key, private=True)
        srv_cert_chain = X509CertChain([X509().parse(srv_raw_certificate)])

        srv_record_layer._handshakeStart(client=False)

        srv_record_layer.version = (3, 3)

        for result in srv_record_layer._getMsg(ContentType.handshake,
                                               HandshakeType.client_hello):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        srv_client_hello = result
        self.assertEqual(ClientHello, type(srv_client_hello))

        srv_cipher_suite = CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA
        srv_session_id = bytearray(0)

        srv_server_hello = ServerHello().create(
            (3, 3), bytearray(32), srv_session_id, srv_cipher_suite,
            CertificateType.x509, None, None)

        srv_msgs = []
        srv_msgs.append(srv_server_hello)
        srv_msgs.append(
            Certificate(CertificateType.x509).create(srv_cert_chain))
        srv_msgs.append(ServerHelloDone())
        for result in srv_record_layer._sendMsgs(srv_msgs):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break
        srv_record_layer._versionCheck = True

        #
        # client part
        #

        for result in record_layer._getMsg(ContentType.handshake,
                                           HandshakeType.server_hello):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_hello = result
        self.assertEqual(ServerHello, type(server_hello))

        for result in record_layer._getMsg(ContentType.handshake,
                                           HandshakeType.certificate,
                                           CertificateType.x509):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_certificate = result
        self.assertEqual(Certificate, type(server_certificate))

        for result in record_layer._getMsg(ContentType.handshake,
                                           HandshakeType.server_hello_done):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_hello_done = result
        self.assertEqual(ServerHelloDone, type(server_hello_done))

        public_key = server_certificate.cert_chain.getEndEntityPublicKey()

        premasterSecret = bytearray(48)
        premasterSecret[0] = 3  # 'cause we negotiatied TLSv1.2
        premasterSecret[1] = 3

        encryptedPreMasterSecret = public_key.encrypt(premasterSecret)

        client_key_exchange = ClientKeyExchange(
            CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, (3, 3))
        client_key_exchange.createRSA(encryptedPreMasterSecret)

        for result in record_layer._sendMsg(client_key_exchange):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        master_secret = calcMasterSecret(
            (3, 3), CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, premasterSecret,
            client_hello.random, server_hello.random)

        record_layer._calcPendingStates(
            CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, master_secret,
            client_hello.random, server_hello.random, None)

        for result in record_layer._sendMsg(ChangeCipherSpec()):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        record_layer._changeWriteState()

        handshake_hashes = record_layer._handshake_hash.digest('sha256')
        verify_data = PRF_1_2(master_secret, b'client finished',
                              handshake_hashes, 12)

        finished = Finished((3, 3)).create(verify_data)
        for result in record_layer._sendMsg(finished):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        #
        # server part
        #

        for result in srv_record_layer._getMsg(
                ContentType.handshake, HandshakeType.client_key_exchange,
                srv_cipher_suite):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        srv_client_key_exchange = result

        srv_premaster_secret = srv_private_key.decrypt(
            srv_client_key_exchange.encryptedPreMasterSecret)

        self.assertEqual(bytearray(b'\x03\x03' + b'\x00' * 46),
                         srv_premaster_secret)

        srv_master_secret = calcMasterSecret(
            srv_record_layer.version, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
            srv_premaster_secret, srv_client_hello.random,
            srv_server_hello.random)

        srv_record_layer._calcPendingStates(srv_cipher_suite,
                                            srv_master_secret,
                                            srv_client_hello.random,
                                            srv_server_hello.random, None)

        for result in srv_record_layer._getMsg(ContentType.change_cipher_spec):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        srv_change_cipher_spec = result
        self.assertEqual(ChangeCipherSpec, type(srv_change_cipher_spec))

        srv_record_layer._changeReadState()

        srv_handshakeHashes = srv_record_layer._handshake_hash.digest('sha256')
        srv_verify_data = PRF_1_2(srv_master_secret, b"client finished",
                                  srv_handshakeHashes, 12)

        for result in srv_record_layer._getMsg(ContentType.handshake,
                                               HandshakeType.finished):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break
        srv_finished = result
        self.assertEqual(Finished, type(srv_finished))
        self.assertEqual(srv_verify_data, srv_finished.verify_data)

        for result in srv_record_layer._sendMsg(ChangeCipherSpec()):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        srv_record_layer._changeWriteState()

        srv_handshakeHashes = srv_record_layer._handshake_hash.digest('sha256')
        srv_verify_data = PRF_1_2(srv_master_secret, b"server finished",
                                  srv_handshakeHashes, 12)

        for result in srv_record_layer._sendMsg(
                Finished((3, 3)).create(srv_verify_data)):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        srv_record_layer._handshakeDone(resumed=False)

        #
        # client part
        #

        for result in record_layer._getMsg(ContentType.change_cipher_spec):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        change_cipher_spec = result
        self.assertEqual(ChangeCipherSpec, type(change_cipher_spec))

        record_layer._changeReadState()

        handshake_hashes = record_layer._handshake_hash.digest('sha256')
        server_verify_data = PRF_1_2(master_secret, b'server finished',
                                     handshake_hashes, 12)

        for result in record_layer._getMsg(ContentType.handshake,
                                           HandshakeType.finished):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_finished = result
        self.assertEqual(Finished, type(server_finished))
        self.assertEqual(server_verify_data, server_finished.verify_data)

        record_layer._handshakeDone(resumed=False)

        # try sending data
        record_layer.write(bytearray(b'text\n'))

        # try recieving data
        data = srv_record_layer.read(10)
        self.assertEqual(data, bytearray(b'text\n'))

        record_layer.close()
        srv_record_layer.close()
    def test_full_connection_with_external_server(self):

        # TODO test is slow (100ms) move to integration test suite
        #
        # start a regular TLS server locally before running this test
        # e.g.: openssl s_server -key localhost.key -cert localhost.crt

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect(("127.0.0.1", 4433))

        record_layer = TLSRecordLayer(sock)

        record_layer._handshakeStart(client=True)
        record_layer.version = (3, 3)

        client_hello = ClientHello()
        client_hello = client_hello.create(
            (3, 3),
            bytearray(32),
            bytearray(0),
            [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA],
            None,
            None,
            False,
            False,
            None,
        )

        for result in record_layer._sendMsg(client_hello):
            if result in (0, 1):
                raise Exception("blocking socket")

        for result in record_layer._getMsg(ContentType.handshake, HandshakeType.server_hello):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_hello = result
        self.assertEqual(ServerHello, type(server_hello))

        for result in record_layer._getMsg(ContentType.handshake, HandshakeType.certificate, CertificateType.x509):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_certificate = result
        self.assertEqual(Certificate, type(server_certificate))

        for result in record_layer._getMsg(ContentType.handshake, HandshakeType.server_hello_done):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_hello_done = result
        self.assertEqual(ServerHelloDone, type(server_hello_done))

        public_key = server_certificate.certChain.getEndEntityPublicKey()

        premasterSecret = bytearray(48)
        premasterSecret[0] = 3  # 'cause we negotiatied TLSv1.2
        premasterSecret[1] = 3

        encryptedPreMasterSecret = public_key.encrypt(premasterSecret)

        client_key_exchange = ClientKeyExchange(CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, (3, 3))
        client_key_exchange.createRSA(encryptedPreMasterSecret)

        for result in record_layer._sendMsg(client_key_exchange):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        master_secret = calcMasterSecret(
            (3, 3), CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, premasterSecret, client_hello.random, server_hello.random
        )

        record_layer._calcPendingStates(
            CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, master_secret, client_hello.random, server_hello.random, None
        )

        for result in record_layer._sendMsg(ChangeCipherSpec()):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        record_layer._changeWriteState()

        handshake_hashes = record_layer._handshake_hash.digest("sha256")
        verify_data = PRF_1_2(master_secret, b"client finished", handshake_hashes, 12)

        finished = Finished((3, 3)).create(verify_data)
        for result in record_layer._sendMsg(finished):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        for result in record_layer._getMsg(ContentType.change_cipher_spec):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        change_cipher_spec = result
        self.assertEqual(ChangeCipherSpec, type(change_cipher_spec))

        record_layer._changeReadState()

        handshake_hashes = record_layer._handshake_hash.digest("sha256")
        server_verify_data = PRF_1_2(master_secret, b"server finished", handshake_hashes, 12)

        for result in record_layer._getMsg(ContentType.handshake, HandshakeType.finished):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_finished = result
        self.assertEqual(Finished, type(server_finished))
        self.assertEqual(server_verify_data, server_finished.verify_data)

        record_layer._handshakeDone(resumed=False)

        record_layer.write(bytearray(b"text\n"))

        record_layer.close()
    def test_full_connection_with_RSA_kex(self):

        clnt_sock, srv_sock = socket.socketpair()

        #
        # client part
        #
        record_layer = TLSRecordLayer(clnt_sock)

        record_layer._handshakeStart(client=True)
        record_layer.version = (3, 3)

        client_hello = ClientHello()
        client_hello = client_hello.create(
            (3, 3),
            bytearray(32),
            bytearray(0),
            [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA],
            None,
            None,
            False,
            False,
            None,
        )

        for result in record_layer._sendMsg(client_hello):
            if result in (0, 1):
                raise Exception("blocking socket")

        #
        # server part
        #

        srv_record_layer = TLSRecordLayer(srv_sock)

        srv_raw_certificate = str(
            "-----BEGIN CERTIFICATE-----\n"
            "MIIB9jCCAV+gAwIBAgIJAMyn9DpsTG55MA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV\n"
            "BAMMCWxvY2FsaG9zdDAeFw0xNTAxMjExNDQzMDFaFw0xNTAyMjAxNDQzMDFaMBQx\n"
            "EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA\n"
            "0QkEeakSyV/LMtTeARdRtX5pdbzVuUuqOIdz3lg7YOyRJ/oyLTPzWXpKxr//t4FP\n"
            "QvYsSJiVOlPk895FNu6sNF/uJQyQGfFWYKkE6fzFifQ6s9kssskFlL1DVI/dD/Zn\n"
            "7sgzua2P1SyLJHQTTs1MtMb170/fX2EBPkDz+2kYKN0CAwEAAaNQME4wHQYDVR0O\n"
            "BBYEFJtvXbRmxRFXYVMOPH/29pXCpGmLMB8GA1UdIwQYMBaAFJtvXbRmxRFXYVMO\n"
            "PH/29pXCpGmLMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAkOgC7LP/\n"
            "Rd6uJXY28HlD2K+/hMh1C3SRT855ggiCMiwstTHACGgNM+AZNqt6k8nSfXc6k1gw\n"
            "5a7SGjzkWzMaZC3ChBeCzt/vIAGlMyXeqTRhjTCdc/ygRv3NPrhUKKsxUYyXRk5v\n"
            "g/g6MwxzXfQP3IyFu3a9Jia/P89Z1rQCNRY=\n"
            "-----END CERTIFICATE-----\n"
        )

        srv_raw_key = str(
            "-----BEGIN RSA PRIVATE KEY-----\n"
            "MIICXQIBAAKBgQDRCQR5qRLJX8sy1N4BF1G1fml1vNW5S6o4h3PeWDtg7JEn+jIt\n"
            "M/NZekrGv/+3gU9C9ixImJU6U+Tz3kU27qw0X+4lDJAZ8VZgqQTp/MWJ9Dqz2Syy\n"
            "yQWUvUNUj90P9mfuyDO5rY/VLIskdBNOzUy0xvXvT99fYQE+QPP7aRgo3QIDAQAB\n"
            "AoGAVSLbE8HsyN+fHwDbuo4I1Wa7BRz33xQWLBfe9TvyUzOGm0WnkgmKn3LTacdh\n"
            "GxgrdBZXSun6PVtV8I0im5DxyVaNdi33sp+PIkZU386f1VUqcnYnmgsnsUQEBJQu\n"
            "fUZmgNM+bfR+Rfli4Mew8lQ0sorZ+d2/5fsM0g80Qhi5M3ECQQDvXeCyrcy0u/HZ\n"
            "FNjIloyXaAIvavZ6Lc6gfznCSfHc5YwplOY7dIWp8FRRJcyXkA370l5dJ0EXj5Gx\n"
            "udV9QQ43AkEA34+RxjRk4DT7Zo+tbM/Fkoi7jh1/0hFkU5NDHweJeH/mJseiHtsH\n"
            "KOcPGtEGBBqT2KNPWVz4Fj19LiUmmjWXiwJBAIBs49O5/+ywMdAAqVblv0S0nweF\n"
            "4fwne4cM+5ZMSiH0XsEojGY13EkTEon/N8fRmE8VzV85YmkbtFWgmPR85P0CQQCs\n"
            "elWbN10EZZv3+q1wH7RsYzVgZX3yEhz3JcxJKkVzRCnKjYaUi6MweWN76vvbOq4K\n"
            "G6Tiawm0Duh/K4ZmvyYVAkBppE5RRQqXiv1KF9bArcAJHvLm0vnHPpf1yIQr5bW6\n"
            "njBuL4qcxlaKJVGRXT7yFtj2fj0gv3914jY2suWqp8XJ\n"
            "-----END RSA PRIVATE KEY-----\n"
        )

        srv_private_key = parsePEMKey(srv_raw_key, private=True)
        srv_cert_chain = X509CertChain([X509().parse(srv_raw_certificate)])

        srv_record_layer._handshakeStart(client=False)

        srv_record_layer.version = (3, 3)

        for result in srv_record_layer._getMsg(ContentType.handshake, HandshakeType.client_hello):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        srv_client_hello = result
        self.assertEqual(ClientHello, type(srv_client_hello))

        srv_cipher_suite = CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA
        srv_session_id = bytearray(0)

        srv_server_hello = ServerHello().create(
            (3, 3), bytearray(32), srv_session_id, srv_cipher_suite, CertificateType.x509, None, None
        )

        srv_msgs = []
        srv_msgs.append(srv_server_hello)
        srv_msgs.append(Certificate(CertificateType.x509).create(srv_cert_chain))
        srv_msgs.append(ServerHelloDone())
        for result in srv_record_layer._sendMsgs(srv_msgs):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break
        srv_record_layer._versionCheck = True

        #
        # client part
        #

        for result in record_layer._getMsg(ContentType.handshake, HandshakeType.server_hello):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_hello = result
        self.assertEqual(ServerHello, type(server_hello))

        for result in record_layer._getMsg(ContentType.handshake, HandshakeType.certificate, CertificateType.x509):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_certificate = result
        self.assertEqual(Certificate, type(server_certificate))

        for result in record_layer._getMsg(ContentType.handshake, HandshakeType.server_hello_done):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_hello_done = result
        self.assertEqual(ServerHelloDone, type(server_hello_done))

        public_key = server_certificate.certChain.getEndEntityPublicKey()

        premasterSecret = bytearray(48)
        premasterSecret[0] = 3  # 'cause we negotiatied TLSv1.2
        premasterSecret[1] = 3

        encryptedPreMasterSecret = public_key.encrypt(premasterSecret)

        client_key_exchange = ClientKeyExchange(CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, (3, 3))
        client_key_exchange.createRSA(encryptedPreMasterSecret)

        for result in record_layer._sendMsg(client_key_exchange):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        master_secret = calcMasterSecret(
            (3, 3), CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, premasterSecret, client_hello.random, server_hello.random
        )

        record_layer._calcPendingStates(
            CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, master_secret, client_hello.random, server_hello.random, None
        )

        for result in record_layer._sendMsg(ChangeCipherSpec()):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        record_layer._changeWriteState()

        handshake_hashes = record_layer._handshake_hash.digest("sha256")
        verify_data = PRF_1_2(master_secret, b"client finished", handshake_hashes, 12)

        finished = Finished((3, 3)).create(verify_data)
        for result in record_layer._sendMsg(finished):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        #
        # server part
        #

        for result in srv_record_layer._getMsg(
            ContentType.handshake, HandshakeType.client_key_exchange, srv_cipher_suite
        ):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        srv_client_key_exchange = result

        srv_premaster_secret = srv_private_key.decrypt(srv_client_key_exchange.encryptedPreMasterSecret)

        self.assertEqual(bytearray(b"\x03\x03" + b"\x00" * 46), srv_premaster_secret)

        srv_master_secret = calcMasterSecret(
            srv_record_layer.version,
            CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
            srv_premaster_secret,
            srv_client_hello.random,
            srv_server_hello.random,
        )

        srv_record_layer._calcPendingStates(
            srv_cipher_suite, srv_master_secret, srv_client_hello.random, srv_server_hello.random, None
        )

        for result in srv_record_layer._getMsg(ContentType.change_cipher_spec):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        srv_change_cipher_spec = result
        self.assertEqual(ChangeCipherSpec, type(srv_change_cipher_spec))

        srv_record_layer._changeReadState()

        srv_handshakeHashes = srv_record_layer._handshake_hash.digest("sha256")
        srv_verify_data = PRF_1_2(srv_master_secret, b"client finished", srv_handshakeHashes, 12)

        for result in srv_record_layer._getMsg(ContentType.handshake, HandshakeType.finished):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break
        srv_finished = result
        self.assertEqual(Finished, type(srv_finished))
        self.assertEqual(srv_verify_data, srv_finished.verify_data)

        for result in srv_record_layer._sendMsg(ChangeCipherSpec()):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        srv_record_layer._changeWriteState()

        srv_handshakeHashes = srv_record_layer._handshake_hash.digest("sha256")
        srv_verify_data = PRF_1_2(srv_master_secret, b"server finished", srv_handshakeHashes, 12)

        for result in srv_record_layer._sendMsg(Finished((3, 3)).create(srv_verify_data)):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        srv_record_layer._handshakeDone(resumed=False)

        #
        # client part
        #

        for result in record_layer._getMsg(ContentType.change_cipher_spec):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        change_cipher_spec = result
        self.assertEqual(ChangeCipherSpec, type(change_cipher_spec))

        record_layer._changeReadState()

        handshake_hashes = record_layer._handshake_hash.digest("sha256")
        server_verify_data = PRF_1_2(master_secret, b"server finished", handshake_hashes, 12)

        for result in record_layer._getMsg(ContentType.handshake, HandshakeType.finished):
            if result in (0, 1):
                raise Exception("blocking socket")
            else:
                break

        server_finished = result
        self.assertEqual(Finished, type(server_finished))
        self.assertEqual(server_verify_data, server_finished.verify_data)

        record_layer._handshakeDone(resumed=False)

        # try sending data
        record_layer.write(bytearray(b"text\n"))

        # try recieving data
        data = srv_record_layer.read(10)
        self.assertEqual(data, bytearray(b"text\n"))

        record_layer.close()
        srv_record_layer.close()
Esempio n. 14
0
def handshakeProxy(c_conn, s_conn, oracle):
    s_conn._handshakeStart(client=False)
    c_conn._handshakeStart(client=True)

    s_settings = HandshakeSettings()
    c_settings = HandshakeSettings()


    # CLIENT HELLO          C -> S
    for result in s_conn._getMsg(ContentType.handshake,
                           HandshakeType.client_hello):
        if result in (0,1): yield result
        else: break
    clientHello = result

    c_conn.version = (3, 1) # Hardcoded version

    for result in c_conn._sendMsg(clientHello):
        yield result


    # Send Server Hello, Certificate and Server Hello Done in one packet
    s_conn.sock.buffer_writes = True

    # SERVER HELLO           S -> C
    for result in c_conn._getMsg(ContentType.handshake,
                           HandshakeType.server_hello):
        if result in (0,1): yield result
        else: break
    serverHello = result

    s_conn.version = serverHello.server_version
    cipherSuite = serverHello.cipher_suite

    for result in s_conn._sendMsg(serverHello):
        yield result


    # CERTIFICATE           S -> C
    for result in c_conn._getMsg(ContentType.handshake,
                           HandshakeType.certificate,
                           serverHello.certificate_type): # FIXME : we should only allow RSA
        if result in (0,1): yield result
        else: break
    serverCertificate = result

    for result in s_conn._sendMsg(serverCertificate):
        yield result


    # CERTIFICATE REQUEST   S -> C
    if 0:
        for result in c_conn._getMsg(ContentType.handshake,
                               HandshakeType.certificate_request):
            if result in (0,1): yield result
            else: break
        certificate_request = result

        for result in s_conn._sendMsg(certificate_request):
            yield result


    # SERVER HELLO DONE     S -> C
    for result in c_conn._getMsg(ContentType.handshake,
                           HandshakeType.server_hello_done):
        if result in (0,1): yield result
        else: break
    serverHelloDone = result

    for result in s_conn._sendMsg(serverHelloDone):
        yield result


    s_conn.sock.flush()
    s_conn.sock.buffer_writes = False


    # Send Client Key Exchange, Change Cipher Spec, Finished in one message
    c_conn.sock.buffer_writes = True

    # CERTIFICATE           C -> S
    if 0:
        for result in s_conn._getMsg(ContentType.handshake,
                               HandshakeType.certificate,
                               serverHello.certificate_type): # FIXME : we should allow anything ?
            if result in (0,1): yield result
            else: break
        clientCertificate = result

        for result in c_conn._sendMsg(clientCertificate):
            yield result


    # CLIENT KEY EXCHANGE   C -> S
    for result in s_conn._getMsg(ContentType.handshake,
                           HandshakeType.client_key_exchange,
                           cipherSuite):
        if result in (0,1): yield result
        else: break
    clientKeyExchange = result

    # Ask the oracle if we continue
    epms = clientKeyExchange.encryptedPreMasterSecret
    if not oracle(epms):
        # YOU SHALL NOT PASS !
        print("Shall not pass")
        return

    print("Decoding phase")

    # Decrypt master key
    dec = subprocess.Popen(['./decrypt', '{}:{}'.format(*oracleaddr), cert], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    dec.stdin.write(hexlify(epms) + b'\n')
    dec.stdin.close()
    res = dec.stdout.readline().strip().split()[-1]
    dec.stdout.close()
    print(res)
    premasterSecret = unhexlify(res)


    # If it's ok, continue
    for result in c_conn._sendMsg(clientKeyExchange):
        yield result


    settings = HandshakeSettings()


    masterSecret = calcMasterSecret(c_conn.version,
                                    cipherSuite,
                                    premasterSecret,
                                    clientHello.random,
                                    serverHello.random)

    print(masterSecret)

    s_conn._calcPendingStates(cipherSuite, masterSecret, 
                              clientHello.random, serverHello.random, 
                              settings.cipherImplementations)
    c_conn._calcPendingStates(cipherSuite, masterSecret, 
                              clientHello.random, serverHello.random, 
                              settings.cipherImplementations)

    print('foobar')

    # CHANGE-CIPHER-SPEC   C -> S
    for result in s_conn._getMsg(ContentType.change_cipher_spec):
        if result in (0,1):
            yield result
    s_changeCipherSpec = result
    for result in c_conn._sendMsg(s_changeCipherSpec):
        yield result

    s_conn._changeReadState()
    c_conn._changeWriteState()

    # SERVER-FINISHED   C -> S
    for result in s_conn._getMsg(ContentType.handshake, HandshakeType.finished):
        if result in (0,1):
            yield result
    server_finished = result
    for result in c_conn._sendMsg(server_finished):
        yield result

    c_conn.sock.flush()
    c_conn.sock.buffer_writes = False



    # Send New Session Ticket, Change Cipher Spec, Finished in one message
    s_conn.sock.buffer_writes = True

    # NEW-SESSION-TICKET
    for result in c_conn._getMsg(ContentType.handshake, HandshakeType.new_session_ticket):
        if result in (0,1):
            yield result
    newSessionTicket = result
    for result in s_conn._sendMsg(newSessionTicket):
        yield result


    # CHANGE-CIPHER-SPEC
    for result in c_conn._getMsg(ContentType.change_cipher_spec):
        if result in (0,1):
            yield result
    c_changeCipherSpec = result
    for result in s_conn._sendMsg(c_changeCipherSpec):
        yield result

    c_conn._changeReadState()
    s_conn._changeWriteState()


    # SERVER-FINISHED
    for result in c_conn._getMsg(ContentType.handshake, HandshakeType.finished):
        if result in (0,1):
            yield result
    client_finished = result
    for result in s_conn._sendMsg(client_finished):
        yield result

    s_conn.sock.flush()
    s_conn.sock.buffer_writes = False

    c_conn._handshakeDone(False)
    s_conn._handshakeDone(False)


    cont = True
    while cont:
        for c_data, s_data in zip(c_conn.readAsync(), s_conn.readAsync()):
            if c_data in (0, 1):
                yield c_data
            elif not c_data:
                # End connection
                print('server ended')
                cont = False
            else:
                print('c', c_data)
                for result in s_conn.writeAsync(c_data):
                    yield result
            if s_data in (0, 1):
                yield s_data
            elif not s_data:
                # End connection
                print('client ended')
                cont = False
            else:
                print('s', s_data)
                for result in c_conn.writeAsync(s_data):
                    yield result

    c_conn.close()
    s_conn.close()

    print("The end")