Пример #1
0
    def test_ECDHE_key_exchange(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha1')

        KeyExchange.verifyServerKeyExchange(srv_key_ex,
                                            self.srv_pub_key,
                                            self.client_hello.random,
                                            self.server_hello.random,
                                            [(HashAlgorithm.sha1,
                                              SignatureAlgorithm.rsa)])

        curveName = GroupName.toStr(srv_key_ex.named_curve)
        curve = getCurveByName(curveName)
        generator = curve.generator
        cln_Xc = ecdsa.util.randrange(generator.order())
        cln_Ys = decodeX962Point(srv_key_ex.ecdh_Ys, curve)
        cln_Yc = encodeX962Point(generator * cln_Xc)

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3))
        cln_key_ex.createECDH(cln_Yc)

        cln_S = cln_Ys * cln_Xc
        cln_premaster = numberToByteArray(cln_S.x(),
                                          getPointByteSize(cln_S))

        srv_premaster = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_premaster, srv_premaster)
    def test_DHE_RSA_key_exchange_with_invalid_client_key_share(self):
        clientKeyExchange = ClientKeyExchange(self.cipher_suite,
                                              (3, 3))
        clientKeyExchange.createDH(2**16000-1)

        with self.assertRaises(TLSIllegalParameterException):
            self.keyExchange.processClientKeyExchange(clientKeyExchange)
    def test_ECDHE_key_exchange(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha1')

        KeyExchange.verifyServerKeyExchange(srv_key_ex,
                                            self.srv_pub_key,
                                            self.client_hello.random,
                                            self.server_hello.random,
                                            [(HashAlgorithm.sha1,
                                              SignatureAlgorithm.rsa)])

        curveName = GroupName.toStr(srv_key_ex.named_curve)
        curve = getCurveByName(curveName)
        generator = curve.generator
        cln_Xc = ecdsa.util.randrange(generator.order())
        cln_Ys = decodeX962Point(srv_key_ex.ecdh_Ys, curve)
        cln_Yc = encodeX962Point(generator * cln_Xc)

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3))
        cln_key_ex.createECDH(cln_Yc)

        cln_S = cln_Ys * cln_Xc
        cln_premaster = numberToByteArray(cln_S.x(),
                                          getPointByteSize(cln_S))

        srv_premaster = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_premaster, srv_premaster)
Пример #4
0
    def generate(self, status):
        if self.version is None:
            self.version = status.version

        if self.cipher is None:
            self.cipher = status.cipher

        if self.client_version is None:
            self.client_version = status.client_version

        cke = ClientKeyExchange(self.cipher, self.version)
        if self.cipher in CipherSuite.certSuites:
            assert len(self.premaster_secret) > 1

            self.premaster_secret[0] = self.client_version[0]
            self.premaster_secret[1] = self.client_version[1]

            status.premaster_secret = self.premaster_secret

            public_key = status.get_server_public_key()

            cke.createRSA(public_key.encrypt(self.premaster_secret))
        elif self.cipher in CipherSuite.dheCertSuites:
            cke = status.key_exchange.makeClientKeyExchange()
        else:
            raise AssertionError("Unknown cipher/key exchange type")

        self.msg = cke

        return cke
Пример #5
0
    def generate(self, status):
        if self.version is None:
            self.version = status.version

        if self.cipher is None:
            self.cipher = status.cipher

        cke = ClientKeyExchange(self.cipher, self.version)
        premaster_secret = self.premaster_secret
        assert len(premaster_secret) > 1

        premaster_secret[0] = self.version[0]
        premaster_secret[1] = self.version[1]

        status.premaster_secret = premaster_secret

        public_key = status.get_server_public_key()

        premaster_secret = public_key.encrypt(premaster_secret)

        cke.createRSA(premaster_secret)

        self.msg = cke

        return cke
Пример #6
0
    def generate(self, status):
        if self.version is None:
            self.version = status.version

        if self.cipher is None:
            self.cipher = status.cipher

        cke = ClientKeyExchange(self.cipher, self.version)
        premaster_secret = self.premaster_secret
        assert len(premaster_secret) > 1

        premaster_secret[0] = self.version[0]
        premaster_secret[1] = self.version[1]

        status.premaster_secret = premaster_secret

        public_key = status.get_server_public_key()

        premaster_secret = public_key.encrypt(premaster_secret)

        cke.createRSA(premaster_secret)

        self.msg = cke

        return cke
Пример #7
0
    def test_SRP_key_exchange_without_signature(self):
        self.cipher_suite = CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA
        self.keyExchange.cipherSuite = self.cipher_suite
        self.server_hello.cipher_suite = self.cipher_suite

        srv_key_ex = self.keyExchange.makeServerKeyExchange()

        a = bytesToNumber(getRandomBytes(32))
        A = powMod(srv_key_ex.srp_g,
                   a,
                   srv_key_ex.srp_N)
        x = makeX(srv_key_ex.srp_s, bytearray(b'user'), bytearray(b'password'))
        v = powMod(srv_key_ex.srp_g,
                   x,
                   srv_key_ex.srp_N)
        u = makeU(srv_key_ex.srp_N,
                  A,
                  srv_key_ex.srp_B)

        k = makeK(srv_key_ex.srp_N,
                  srv_key_ex.srp_g)
        S = powMod((srv_key_ex.srp_B - (k*v)) % srv_key_ex.srp_N,
                   a+(u*x),
                   srv_key_ex.srp_N)

        cln_premaster = numberToByteArray(S)

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3)).createSRP(A)

        srv_premaster = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_premaster, srv_premaster)
Пример #8
0
    def test_SRP_key_exchange(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha256')

        KeyExchange.verifyServerKeyExchange(srv_key_ex,
                                            self.srv_pub_key,
                                            self.client_hello.random,
                                            self.server_hello.random,
                                            [(HashAlgorithm.sha256,
                                              SignatureAlgorithm.rsa)])

        a = bytesToNumber(getRandomBytes(32))
        A = powMod(srv_key_ex.srp_g,
                   a,
                   srv_key_ex.srp_N)
        x = makeX(srv_key_ex.srp_s, bytearray(b'user'), bytearray(b'password'))
        v = powMod(srv_key_ex.srp_g,
                   x,
                   srv_key_ex.srp_N)
        u = makeU(srv_key_ex.srp_N,
                  A,
                  srv_key_ex.srp_B)

        k = makeK(srv_key_ex.srp_N,
                  srv_key_ex.srp_g)
        S = powMod((srv_key_ex.srp_B - (k*v)) % srv_key_ex.srp_N,
                   a+(u*x),
                   srv_key_ex.srp_N)

        cln_premaster = numberToByteArray(S)

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3)).createSRP(A)

        srv_premaster = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_premaster, srv_premaster)
Пример #9
0
    def test_DHE_RSA_key_exchange(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha1')

        cln_X = bytesToNumber(getRandomBytes(32))
        cln_Yc = powMod(srv_key_ex.dh_g,
                        cln_X,
                        srv_key_ex.dh_p)
        cln_secret = numberToByteArray(powMod(srv_key_ex.dh_Ys,
                                              cln_X,
                                              srv_key_ex.dh_p))

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3))
        cln_key_ex.createDH(cln_Yc)

        srv_secret = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_secret, srv_secret)
    def test_DHE_RSA_key_exchange(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha1')

        cln_X = bytesToNumber(getRandomBytes(32))
        cln_Yc = powMod(srv_key_ex.dh_g,
                        cln_X,
                        srv_key_ex.dh_p)
        cln_secret = numberToByteArray(powMod(srv_key_ex.dh_Ys,
                                              cln_X,
                                              srv_key_ex.dh_p))

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3))
        cln_key_ex.createDH(cln_Yc)

        srv_secret = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_secret, srv_secret)
Пример #11
0
    def generate(self, status):
        if self.version is None:
            self.version = status.version

        if self.cipher is None:
            self.cipher = status.cipher

        if self.client_version is None:
            self.client_version = status.client_version

        cke = ClientKeyExchange(self.cipher, self.version)
        if self.cipher in CipherSuite.certSuites:
            if self.modulus_as_encrypted_premaster:
                public_key = status.get_server_public_key()
                self.encrypted_premaster = numberToByteArray(public_key.n)
            if self.encrypted_premaster:
                cke.createRSA(self.encrypted_premaster)
            else:
                assert len(self.premaster_secret) > 1
                self.premaster_secret[0] = self.client_version[0]
                self.premaster_secret[1] = self.client_version[1]

                status.premaster_secret = self.premaster_secret

                public_key = status.get_server_public_key()

                cke.createRSA(self._encrypt_with_fuzzing(public_key))
        elif self.cipher in CipherSuite.dheCertSuites:
            if self.dh_Yc is not None:
                cke = ClientKeyExchange(self.cipher,
                                        self.version).createDH(self.dh_Yc)
            else:
                cke = status.key_exchange.makeClientKeyExchange()
        elif self.cipher in CipherSuite.ecdhAllSuites:
            if self.ecdh_Yc is not None:
                cke = ClientKeyExchange(self.cipher,
                                        self.version).createECDH(self.ecdh_Yc)
            else:
                cke = status.key_exchange.makeClientKeyExchange()
        else:
            raise AssertionError("Unknown cipher/key exchange type")

        self.msg = cke

        return cke
    def test_RSA_with_wrong_version(self):

        self.assertIsNone(self.keyExchange.makeServerKeyExchange())

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 1
        clientKeyExchange = ClientKeyExchange(self.cipher_suite,
                                              (3, 2))
        clientKeyExchange.createRSA(self.srv_pub_key.encrypt(premaster_secret))

        dec_premaster = self.keyExchange.processClientKeyExchange(\
                        clientKeyExchange)

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 1
        self.assertNotEqual(dec_premaster, premaster_secret)
Пример #13
0
    def test_RSA_with_wrong_version(self):

        self.assertIsNone(self.keyExchange.makeServerKeyExchange())

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 1
        clientKeyExchange = ClientKeyExchange(self.cipher_suite,
                                              (3, 2))
        clientKeyExchange.createRSA(self.srv_pub_key.encrypt(premaster_secret))

        dec_premaster = self.keyExchange.processClientKeyExchange(\
                        clientKeyExchange)

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 1
        self.assertNotEqual(dec_premaster, premaster_secret)
Пример #14
0
    def test_SRP_with_invalid_client_key_share(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha1')

        A = srv_key_ex.srp_N

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3)).createSRP(A)

        with self.assertRaises(TLSIllegalParameterException):
            self.keyExchange.processClientKeyExchange(cln_key_ex)
    def test_RSA_with_wrong_version_in_IE(self):
        # Internet Explorer sends the version from Server Hello not Client Hello

        self.assertIsNone(self.keyExchange.makeServerKeyExchange())

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 2
        clientKeyExchange = ClientKeyExchange(self.cipher_suite,
                                              (3, 2))
        enc_premaster = self.srv_pub_key.encrypt(premaster_secret)
        clientKeyExchange.createRSA(enc_premaster)

        dec_premaster = self.keyExchange.processClientKeyExchange(\
                        clientKeyExchange)

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 2
        self.assertEqual(dec_premaster, premaster_secret)
    def test_RSA_with_invalid_encryption(self):

        self.assertIsNone(self.keyExchange.makeServerKeyExchange())

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 3
        clientKeyExchange = ClientKeyExchange(self.cipher_suite,
                                              (3, 2))
        enc_premaster = self.srv_pub_key.encrypt(premaster_secret)
        enc_premaster[-1] ^= 0x01
        clientKeyExchange.createRSA(enc_premaster)

        dec_premaster = self.keyExchange.processClientKeyExchange(\
                        clientKeyExchange)

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 3
        self.assertNotEqual(dec_premaster, premaster_secret)
Пример #17
0
    def test_RSA_with_wrong_version_in_IE(self):
        # Internet Explorer sends the version from Server Hello not Client Hello

        self.assertIsNone(self.keyExchange.makeServerKeyExchange())

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 2
        clientKeyExchange = ClientKeyExchange(self.cipher_suite,
                                              (3, 2))
        enc_premaster = self.srv_pub_key.encrypt(premaster_secret)
        clientKeyExchange.createRSA(enc_premaster)

        dec_premaster = self.keyExchange.processClientKeyExchange(\
                        clientKeyExchange)

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 2
        self.assertEqual(dec_premaster, premaster_secret)
Пример #18
0
    def test_RSA_with_invalid_encryption(self):

        self.assertIsNone(self.keyExchange.makeServerKeyExchange())

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 3
        clientKeyExchange = ClientKeyExchange(self.cipher_suite,
                                              (3, 2))
        enc_premaster = self.srv_pub_key.encrypt(premaster_secret)
        enc_premaster[-1] ^= 0x01
        clientKeyExchange.createRSA(enc_premaster)

        dec_premaster = self.keyExchange.processClientKeyExchange(\
                        clientKeyExchange)

        premaster_secret = bytearray(b'\xf0'*48)
        premaster_secret[0] = 3
        premaster_secret[1] = 3
        self.assertNotEqual(dec_premaster, premaster_secret)
Пример #19
0
    def generate(self, status):
        if self.version is None:
            self.version = status.version

        if self.cipher is None:
            self.cipher = status.cipher

        if self.client_version is None:
            self.client_version = status.client_version

        cke = ClientKeyExchange(self.cipher, self.version)
        if self.cipher in CipherSuite.certSuites:
            assert len(self.premaster_secret) > 1

            self.premaster_secret[0] = self.client_version[0]
            self.premaster_secret[1] = self.client_version[1]

            status.premaster_secret = self.premaster_secret

            public_key = status.get_server_public_key()

            cke.createRSA(public_key.encrypt(self.premaster_secret))
        elif self.cipher in CipherSuite.dheCertSuites:
            if self.dh_Yc is not None:
                cke = ClientKeyExchange(self.cipher,
                                        self.version).createDH(self.dh_Yc)
            else:
                cke = status.key_exchange.makeClientKeyExchange()
        else:
            raise AssertionError("Unknown cipher/key exchange type")

        self.msg = cke

        return cke
    def test_ECDHE_key_exchange_with_invalid_CKE(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha1')

        KeyExchange.verifyServerKeyExchange(srv_key_ex,
                                            self.srv_pub_key,
                                            self.client_hello.random,
                                            self.server_hello.random,
                                            [(HashAlgorithm.sha1,
                                              SignatureAlgorithm.rsa)])

        curveName = GroupName.toStr(srv_key_ex.named_curve)
        curve = getCurveByName(curveName)
        generator = curve.generator
        cln_Xc = ecdsa.util.randrange(generator.order())
        cln_Ys = decodeX962Point(srv_key_ex.ecdh_Ys, curve)
        cln_Yc = encodeX962Point(generator * cln_Xc)

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3))
        cln_key_ex.createECDH(cln_Yc)

        cln_key_ex.ecdh_Yc[-1] ^= 0x01

        with self.assertRaises(TLSIllegalParameterException):
            self.keyExchange.processClientKeyExchange(cln_key_ex)
    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 = calc_key((3, 3),
                                 premasterSecret,
                                 CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
                                 b"master secret",
                                 client_random=client_hello.random,
                                 server_random=server_hello.random,
                                 output_length=48)

        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()
Пример #22
0
    def generate(self, status):
        """Create a Client Key Exchange message."""
        if self.version is None:
            self.version = status.version

        if self.cipher is None:
            self.cipher = status.cipher

        if self.client_version is None:
            self.client_version = status.client_version

        cke = ClientKeyExchange(self.cipher, self.version)
        if self.cipher in CipherSuite.certSuites:
            if self.modulus_as_encrypted_premaster:
                public_key = status.get_server_public_key()
                self.encrypted_premaster = numberToByteArray(public_key.n)
            if self.encrypted_premaster:
                cke.createRSA(self.encrypted_premaster)
            else:
                assert len(self.premaster_secret) > 1
                self.premaster_secret[0] = self.client_version[0]
                self.premaster_secret[1] = self.client_version[1]

                status.premaster_secret = self.premaster_secret

                public_key = status.get_server_public_key()

                cke.createRSA(self._encrypt_with_fuzzing(public_key))
        elif self.cipher in CipherSuite.dheCertSuites:
            if self.dh_Yc is not None:
                cke = ClientKeyExchange(self.cipher,
                                        self.version).createDH(self.dh_Yc)
            elif self.p_as_share or self.p_1_as_share:
                ske = next((i for i in reversed(status.handshake_messages)
                            if isinstance(i, ServerKeyExchange)), None)
                assert ske, "No server key exchange in messages"
                if self.p_as_share:
                    cke = ClientKeyExchange(self.cipher,
                                            self.version).createDH(ske.dh_p)
                else:
                    cke = ClientKeyExchange(self.cipher,
                                            self.version).createDH(ske.dh_p-1)
            else:
                cke = status.key_exchange.makeClientKeyExchange()
        elif self.cipher in CipherSuite.ecdhAllSuites:
            if self.ecdh_Yc is not None:
                cke = ClientKeyExchange(self.cipher,
                                        self.version).createECDH(self.ecdh_Yc)
            else:
                cke = status.key_exchange.makeClientKeyExchange()
        else:
            raise AssertionError("Unknown cipher/key exchange type")

        self.msg = cke

        return cke
    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()
    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.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 = calc_key((3, 3),
                                 premasterSecret,
                                 CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
                                 b"master secret",
                                 client_random=client_hello.random,
                                 server_random=server_hello.random,
                                 output_length=48)

        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 = calc_key(srv_record_layer.version,
                                     srv_premaster_secret,
                                     CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
                                     b"master secret",
                                     client_random=srv_client_hello.random,
                                     server_random=srv_server_hello.random,
                                     output_length=48)

        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()