Пример #1
0
    def process(self, state, msg):
        """
        @type state: ConnectionState
        @type msg: Message
        """
        assert msg.contentType == ContentType.handshake
        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == self.handshake_type
        if self.version is None:
            self.version = state.version

        if self.version in ((0, 2), (2, 0)):
            finished = ServerFinished()
        else:
            finished = Finished(self.version)

        finished.parse(parser)

        if self.version in ((0, 2), (2, 0)):
            state.session_id = finished.verify_data
        else:
            verify_expected = calcFinished(state.version, state.master_secret,
                                           state.cipher,
                                           state.handshake_hashes,
                                           not state.client)

            assert finished.verify_data == verify_expected

        state.handshake_messages.append(finished)
        state.server_verify_data = finished.verify_data
        state.handshake_hashes.update(msg.write())

        if self.version in ((0, 2), (2, 0)):
            state.msg_sock.handshake_finished = True
Пример #2
0
    def test_getVarList_with_incorrect_length(self):
        p = Parser(bytearray(b'\x07' + b'\x00\x01\x00'
                             b'\x00\x00\xff'
                             b'\x00'))

        with self.assertRaises(SyntaxError):
            p.getVarList(3, 1)
    def test_getRemainingLength(self):
        p = Parser(bytearray(b"\x00\x01\x05"))

        self.assertEqual(1, p.get(2))
        self.assertEqual(1, p.getRemainingLength())
        self.assertEqual(5, p.get(1))
        self.assertEqual(0, p.getRemainingLength())
Пример #4
0
    def test_parse_with_name_length_short_by_one(self):
        server_name = SNIExtension()

        p = Parser(
            bytearray(b'\x00\x1c' +  # length of array - 28 bytes
                      b'\x0a' +  # type of entry - unassigned (10)
                      b'\x00\x0a' +  # length of name - 10 bytes (short by one)
                      # UTF-8 encoding of example.org
                      b'\x65\x78\x61\x6d\x70\x6c\x65\x2e\x6f\x72\x67' +
                      b'\x00' +  # type of entry - host_name (0)
                      b'\x00\x0b' +  # length of name - 11 bytes
                      # UTF-8 encoding of example.com
                      b'\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d'))

        with self.assertRaises(SyntaxError):
            server_name = server_name.parse(p)

        server_name = SNIExtension()

        p = Parser(
            bytearray(b'\x00\x1c' +  # length of array - 28 bytes
                      b'\x0a' +  # type of entry - unassigned (10)
                      b'\x00\x0b' +  # length of name - 11 bytes
                      # UTF-8 encoding of example.org
                      b'\x65\x78\x61\x6d\x70\x6c\x65\x2e\x6f\x72\x67' +
                      b'\x00' +  # type of entry - host_name (0)
                      b'\x00\x0a' +  # length of name - 10 bytes (short by one)
                      # UTF-8 encoding of example.com
                      b'\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d'))

        with self.assertRaises(SyntaxError):
            server_name = server_name.parse(p)
    def test_getFixBytes_with_incorrect_data(self):
        p = Parser(bytearray(
            b'\x00\x04'
            ))

        with self.assertRaises(SyntaxError):
            p.getFixBytes(10)
    def test_getVarTupleList_with_incorrect_length(self):
        p = Parser(bytearray(
            b'\x00\x03' +
            b'\x00'*3))

        with self.assertRaises(SyntaxError):
            p.getVarTupleList(1, 2, 2)
Пример #7
0
    def process(self, state, msg):
        """Check if the VERIFY message has expected value"""
        assert msg.contentType == ContentType.handshake
        parser = Parser(msg.write())

        msg_type = parser.get(1)
        assert msg_type == SSL2HandshakeType.server_verify
    def test_get_with_too_few_bytes_left(self):
        p = Parser(bytearray(b'\x02\x01'))

        p.get(1)

        with self.assertRaises(SyntaxError):
            p.get(2)
Пример #9
0
    def process(self, state, msg):
        """Check if the VERIFY message has expected value"""
        assert msg.contentType == ContentType.handshake
        parser = Parser(msg.write())

        msg_type = parser.get(1)
        assert msg_type == SSL2HandshakeType.server_verify
Пример #10
0
    def process(self, state, msg):
        """
        @type state: ConnectionState
        @type msg: Message
        """
        assert msg.contentType == ContentType.handshake
        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == HandshakeType.finished
        if self.version is None:
            self.version = state.version

        finished = Finished(self.version)
        finished.parse(parser)

        verify_expected = calcFinished(state.version,
                                       state.master_secret,
                                       state.cipher,
                                       state.handshake_hashes,
                                       not state.client)

        assert finished.verify_data == verify_expected

        state.handshake_messages.append(finished)
        state.server_verify_data = finished.verify_data
        state.handshake_hashes.update(msg.write())
    def test_getVarTupleList_with_missing_elements(self):
        p = Parser(bytearray(
            b'\x00\x02' +
            b'\x00'))

        with self.assertRaises(SyntaxError):
            p.getVarTupleList(1, 2, 2)
    def test_atLengthCheck(self):
        p = Parser(bytearray(b"\x00\x06" + b"\x05" + b"\x01\xff" + b"\x07" + b"\x01\xf0"))

        p.startLengthCheck(2)
        while not p.atLengthCheck():
            p.get(1)
            p.getVarBytes(1)
        p.stopLengthCheck()
    def test_getFixList(self):
        p = Parser(bytearray(
            b'\x00\x01' +
            b'\x00\x02' +
            b'\x00\x03'))

        self.assertEqual([1,2,3], p.getFixList(2, 3))
        self.assertEqual(6, p.index)
    def test_getVarList(self):
        p = Parser(bytearray(
            b'\x06' +
            b'\x00\x01\x00' +
            b'\x00\x00\xff'))

        self.assertEqual([256, 255], p.getVarList(3, 1))
        self.assertEqual(7, p.index)
Пример #15
0
    def test_getVarTupleList(self):
        p = Parser(
            bytearray(b'\x00\x06' +  # length of list
                      b'\x01\x00' +  # first tuple
                      b'\x01\x05' +  # second tuple
                      b'\x04\x00'  # third tuple
                      ))

        self.assertEqual(p.getVarTupleList(1, 2, 2), [(1, 0), (1, 5), (4, 0)])
Пример #16
0
    def process(self, state, msg):
        assert msg.contentType == ContentType.handshake
        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == HandshakeType.new_session_ticket

        ticket = NewSessionTicket().parse(parser)

        state.session_tickets.append(ticket)
    def test_getVarList_with_incorrect_length(self):
        p = Parser(bytearray(
            b'\x07' +
            b'\x00\x01\x00'
            b'\x00\x00\xff'
            b'\x00'))

        with self.assertRaises(SyntaxError):
            p.getVarList(3,1)
Пример #18
0
    def process(self, state, msg):
        """
        Process the message and update state accordingly

        @type state: ConnectionState
        @param state: overall state of TLS connection

        @type msg: Message
        @param msg: TLS Message read from socket
        """
        assert msg.contentType == ContentType.handshake

        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == HandshakeType.server_hello

        srv_hello = ServerHello()
        srv_hello.parse(parser)

        # extract important info
        state.server_random = srv_hello.random

        # check for session_id based session resumption
        if self.resume:
            assert state.session_id == srv_hello.session_id
        if (state.session_id == srv_hello.session_id and
                srv_hello.session_id != bytearray(0)):
            state.resuming = True
            assert state.cipher == srv_hello.cipher_suite
            assert state.version == srv_hello.server_version
        state.session_id = srv_hello.session_id

        if self.version is not None:
            assert self.version == srv_hello.server_version

        state.cipher = srv_hello.cipher_suite
        state.version = srv_hello.server_version

        # update the state of connection
        state.msg_sock.version = srv_hello.server_version

        state.handshake_messages.append(srv_hello)
        state.handshake_hashes.update(msg.write())

        # check if the message has expected values
        if self.extensions is not None:
            for ext_id in self.extensions:
                ext = srv_hello.getExtension(ext_id)
                assert ext is not None
                # run extension-specific checker if present
                if self.extensions[ext_id] is not None:
                    self.extensions[ext_id](state, ext)
            # not supporting any extensions is valid
            if srv_hello.extensions is not None:
                for ext_id in (ext.extType for ext in srv_hello.extensions):
                    assert ext_id in self.extensions
Пример #19
0
    def process(self, state, msg):
        """Analyse the error message"""
        assert msg.contentType == ContentType.handshake

        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == SSL2HandshakeType.error

        if self.error is not None:
            assert self.error == parser.get(2)
Пример #20
0
    def setUp(self):
        self.srv_cert_chain = X509CertChain([X509().parse(srv_raw_certificate)])
        self.srv_pub_key = self.srv_cert_chain.getEndEntityPublicKey()
        self.cipher_suite = CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA
        self.server_key_exchange = ServerKeyExchange(self.cipher_suite, (3, 3))\
                                   .parse(Parser(self.expected_sha1_SKE[1:]))
        self.ske_tls1_1 = ServerKeyExchange(self.cipher_suite, (3, 2))\
                                    .parse(Parser(self.expected_tls1_1_SKE[1:]))

        self.client_hello = ClientHello()
Пример #21
0
    def process(self, state, msg):
        """Analyse the error message"""
        assert msg.contentType == ContentType.handshake

        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == SSL2HandshakeType.error

        if self.error is not None:
            assert self.error == parser.get(2)
Пример #22
0
    def process(self, state, msg):
        assert msg.contentType == ContentType.handshake

        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == HandshakeType.certificate_status

        cert_status = CertificateStatus().parse(parser)

        state.handshake_messages.append(cert_status)
        state.handshake_hashes.update(msg.write())
Пример #23
0
    def process(self, state, msg):
        """Process the Server Key Exchange message"""
        assert msg.contentType == ContentType.handshake
        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == HandshakeType.server_key_exchange

        if self.version is None:
            self.version = state.version
        if self.cipher_suite is None:
            self.cipher_suite = state.cipher
        valid_sig_algs = self.valid_sig_algs

        server_key_exchange = ServerKeyExchange(self.cipher_suite,
                                                self.version)
        server_key_exchange.parse(parser)

        client_random = state.client_random
        server_random = state.server_random
        public_key = state.get_server_public_key()
        server_hello = state.get_last_message_of_type(ServerHello)
        if server_hello is None:
            server_hello = ServerHello
            server_hello.server_version = state.version
        if valid_sig_algs is None:
            # if the value was unset in script, get the advertised value from
            # Client Hello
            client_hello = state.get_last_message_of_type(ClientHello)
            if client_hello is not None:
                sig_algs_ext = client_hello.getExtension(ExtensionType.
                                                         signature_algorithms)
                if sig_algs_ext is not None:
                    valid_sig_algs = sig_algs_ext.sigalgs
            if valid_sig_algs is None:
                # no advertised means support for sha1 only
                valid_sig_algs = [(HashAlgorithm.sha1, SignatureAlgorithm.rsa)]

        KeyExchange.verifyServerKeyExchange(server_key_exchange,
                                            public_key,
                                            client_random,
                                            server_random,
                                            valid_sig_algs)

        state.key_exchange = DHE_RSAKeyExchange(self.cipher_suite,
                                                clientHello=None,
                                                serverHello=server_hello,
                                                privateKey=None)
        state.premaster_secret = state.key_exchange.\
                                 processServerKeyExchange(public_key,
                                                          server_key_exchange)

        state.handshake_messages.append(server_key_exchange)
        state.handshake_hashes.update(msg.write())
Пример #24
0
    def process(self, state, msg):
        """
        @type state: ConnectionState
        @type msg: Message
        """
        assert msg.contentType == ContentType.handshake
        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == self.handshake_type
        if self.version is None:
            self.version = state.version

        if self.version in ((0, 2), (2, 0)):
            finished = ServerFinished()
        else:
            finished = Finished(self.version, state.prf_size)

        finished.parse(parser)

        if self.version in ((0, 2), (2, 0)):
            state.session_id = finished.verify_data
        elif self.version <= (3, 3):
            verify_expected = calcFinished(state.version,
                                           state.key['master_secret'],
                                           state.cipher,
                                           state.handshake_hashes,
                                           not state.client)

            assert finished.verify_data == verify_expected
        else:  # TLS 1.3
            finished_key = HKDF_expand_label(
                state.key['server handshake traffic secret'],
                b'finished',
                b'',
                state.prf_size,
                state.prf_name)
            transcript_hash = state.handshake_hashes.digest(state.prf_name)
            verify_expected = secureHMAC(finished_key,
                                         transcript_hash,
                                         state.prf_name)
            assert finished.verify_data == verify_expected

        state.handshake_messages.append(finished)
        state.key['server_verify_data'] = finished.verify_data
        state.handshake_hashes.update(msg.write())

        if self.version in ((0, 2), (2, 0)):
            state.msg_sock.handshake_finished = True

        # in TLS 1.3 ChangeCipherSpec is a no-op, we need to attach
        # the change to some message
        if self.version > (3, 3):
            state.msg_sock.changeWriteState()
    def test_getVarTupleList(self):
        p = Parser(bytearray(
            b'\x00\x06' +       # length of list
            b'\x01\x00' +       # first tuple
            b'\x01\x05' +       # second tuple
            b'\x04\x00'         # third tuple
            ))

        self.assertEqual(p.getVarTupleList(1, 2, 2),
                [(1, 0),
                 (1, 5),
                 (4, 0)])
Пример #26
0
    def process(self, state, msg):
        assert msg.contentType == ContentType.handshake
        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == self.handshake_type

        exts = EncryptedExtensions().parse(parser)

        # TODO check if received extensions match the set extensions
        assert self.extensions is None

        state.handshake_messages.append(exts)
        state.handshake_hashes.update(msg.write())
    def test_atLengthCheck(self):
        p = Parser(bytearray(
            b'\x00\x06' +
            b'\x05' +
            b'\x01\xff' +
            b'\x07' +
            b'\x01\xf0'
            ))

        p.startLengthCheck(2)
        while not p.atLengthCheck():
            p.get(1)
            p.getVarBytes(1)
        p.stopLengthCheck()
Пример #28
0
    def process(self, state, msg):
        """
        @type state: ConnectionState
        """
        assert msg.contentType == ContentType.handshake

        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == HandshakeType.certificate

        cert = Certificate(self.cert_type)
        cert.parse(parser)

        state.handshake_messages.append(cert)
        state.handshake_hashes.update(msg.write())
Пример #29
0
    def process(self, state, msg):
        """
        @type state: ConnectionState
        """
        assert msg.contentType == ContentType.handshake

        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == HandshakeType.certificate

        cert = Certificate(self.cert_type)
        cert.parse(parser)

        state.handshake_messages.append(cert)
        state.handshake_hashes.update(msg.write())
Пример #30
0
    def test_parse(self):
        p = Parser(
            bytearray(
                # don't include type of message as it is handled by the hello
                # protocol layer
                # b'\x02' +                     # type of message - server_hello
                b'\x00\x00\x36' +  # length - 54 bytes
                b'\x03\x03' +  # version - TLS 1.2
                b'\x01' * 31 + b'\x02' +  # random
                b'\x00' +  # session id length
                b'\x00\x9d' +  # cipher suite
                b'\x01' +  # compression method (zlib)
                b'\x00\x0e' +  # extensions length - 14 bytes
                b'\xff\x01' +  # ext type - renegotiation_info
                b'\x00\x01' +  # ext length - 1 byte
                b'\x00' +  # value - supported (0)
                b'\x00\x23' +  # ext type - session ticket (35)
                b'\x00\x00' +  # ext length - 0 bytes
                b'\x00\x0f' +  # ext type - heartbeat (15)
                b'\x00\x01' +  # ext length - 1 byte
                b'\x01'))  # peer allowed to send requests (1)
        server_hello = ServerHello()
        server_hello = server_hello.parse(p)

        self.assertEqual((3, 3), server_hello.server_version)
        self.assertEqual(bytearray(b'\x01' * 31 + b'\x02'),
                         server_hello.random)
        self.assertEqual(bytearray(0), server_hello.session_id)
        self.assertEqual(157, server_hello.cipher_suite)
        # XXX not sent by server!
        self.assertEqual(CertificateType.x509, server_hello.certificate_type)
        self.assertEqual(1, server_hello.compression_method)
        self.assertEqual(None, server_hello.tackExt)
        self.assertEqual(None, server_hello.next_protos_advertised)
Пример #31
0
    def test_parse(self):
        parser = Parser(bytearray(b'\x01\x00'))

        ext = ECPointFormatsExtension()
        self.assertIsNone(ext.formats)
        ext.parse(parser)
        self.assertEqual(ext.formats, [ECPointFormat.uncompressed])
Пример #32
0
    def test_parse(self):
        p = Parser(
            bytearray(
                # we don't include the type of message as it is handled by the
                # hello protocol parser
                #b'x01' +             # type of message - client_hello
                b'\x00' * 2 + b'\x26' +  # length - 38 bytes
                b'\x01\x01' +  # protocol version - arbitrary (invalid)
                b'\x00' * 32 +  # client random
                b'\x00' +  # session ID length
                b'\x00' * 2 +  # cipher suites length
                b'\x00'  # compression methods length
            ))
        client_hello = ClientHello()
        client_hello = client_hello.parse(p)

        self.assertEqual((1, 1), client_hello.client_version)
        self.assertEqual(bytearray(32), client_hello.random)
        self.assertEqual(bytearray(0), client_hello.session_id)
        self.assertEqual([], client_hello.cipher_suites)
        self.assertEqual([], client_hello.compression_methods)
        self.assertEqual(bytearray(0), client_hello.server_name)
        # XXX not sent
        self.assertEqual([0], client_hello.certificate_types)
        self.assertEqual(False, client_hello.supports_npn)
        self.assertEqual(False, client_hello.tack)
        self.assertEqual(None, client_hello.srp_username)
        self.assertEqual(None, client_hello.extensions)
Пример #33
0
    def test_parse_with_multiple_hostNames(self):
        server_name = SNIExtension()

        p = Parser(
            bytearray(b'\x00\x1c' +  # length of array - 28 bytes
                      b'\x0a' +  # type of entry - unassigned (10)
                      b'\x00\x0b' +  # length of name - 11 bytes
                      # UTF-8 encoding of example.org
                      b'\x65\x78\x61\x6d\x70\x6c\x65\x2e\x6f\x72\x67' +
                      b'\x00' +  # type of entry - host_name (0)
                      b'\x00\x0b' +  # length of name - 11 bytes
                      # UTF-8 encoding of example.com
                      b'\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d'))

        server_name = server_name.parse(p)

        self.assertEqual(bytearray(b'example.com'), server_name.hostNames[0])
        self.assertEqual(tuple([bytearray(b'example.com')]),
                         server_name.hostNames)

        SN = SNIExtension.ServerName

        self.assertEqual([
            SN(10, bytearray(b'example.org')),
            SN(0, bytearray(b'example.com'))
        ], server_name.serverNames)
Пример #34
0
    def tes_parse_with_invalid_data(self):
        server_name = SNIExtension()

        p = Parser(bytearray(b'\x00\x01'))

        with self.assertRaises(SyntaxError):
            server_name.parse(p)
Пример #35
0
    def process(self, state, msg):
        assert msg.contentType == ContentType.alert
        parser = Parser(msg.write())

        alert = Alert()
        alert.parse(parser)

        problem_desc = ""
        if self.level is not None and alert.level != self.level:
            problem_desc += "Alert level {0} != {1}".format(
                alert.level, self.level)
        if self.description is not None:
            # allow for multiple choice for description
            if not isinstance(self.description, collections.Iterable):
                self.description = tuple([self.description])

            if alert.description not in self.description:
                if problem_desc:
                    problem_desc += ", "
                descriptions = [
                    "\"{0}\"".format(AlertDescription.toStr(i))
                    for i in self.description
                ]
                expected = ", ".join(
                    itertools.chain(
                        (i for i in descriptions[:-2]),
                        [" or ".join(i for i in descriptions[-2:])]))
                received = AlertDescription.toStr(alert.description)
                problem_desc += ("Expected alert description {0} does not "
                                 "match received \"{1}\"".format(
                                     expected, received))
        if problem_desc:
            raise AssertionError(problem_desc)
Пример #36
0
    def test_parse_with_empty_data(self):
        parser = Parser(bytearray())

        ext = SupportedGroupsExtension().parse(parser)

        self.assertEqual(ext.extType, ExtensionType.supported_groups)
        self.assertIsNone(ext.groups)
Пример #37
0
    def test_parse(self):
        p = Parser(bytearray(b'\x00'  # certificate type - X.509 (0)
                             ))

        cert_type = ServerCertTypeExtension().parse(p)

        self.assertEqual(0, cert_type.cert_type)
Пример #38
0
    def test_parse_with_length_long_by_one(self):
        cert_type = ClientCertTypeExtension()

        p = Parser(bytearray(b'\x03\x01\x00'))

        with self.assertRaises(SyntaxError):
            cert_type.parse(p)
Пример #39
0
    def process(self, state, msg):
        """
        @type state: ConnectionState
        @type msg: Message
        """
        assert msg.contentType == ContentType.handshake

        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == HandshakeType.server_hello_done

        srv_hello_done = ServerHelloDone()
        srv_hello_done.parse(parser)

        state.handshake_messages.append(srv_hello_done)
        state.handshake_hashes.update(msg.write())
Пример #40
0
    def test_parse_with_too_much_data(self):
        p = Parser(bytearray(b'\x00\x00'))

        cert_type = ServerCertTypeExtension()

        with self.assertRaises(SyntaxError):
            cert_type.parse(p)
Пример #41
0
    def process(self, state, msg):
        """
        @type state: ConnectionState
        @type msg: Message
        """
        assert msg.contentType == ContentType.handshake

        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == HandshakeType.server_hello_done

        srv_hello_done = ServerHelloDone()
        srv_hello_done.parse(parser)

        state.handshake_messages.append(srv_hello_done)
        state.handshake_hashes.update(msg.write())
Пример #42
0
    def test_parse(self):
        p = Parser(bytearray(3))

        tack_ext = TACKExtension().parse(p)

        self.assertEqual([], tack_ext.tacks)
        self.assertEqual(0, tack_ext.activation_flags)
Пример #43
0
    def test_parse(self):
        srp_extension = SRPExtension()
        p = Parser(bytearray(b'\x08' + b'username'))

        srp_extension = srp_extension.parse(p)

        self.assertEqual(bytearray(b'username'), srp_extension.identity)
Пример #44
0
    def test_parse_with_extensions_length_long_by_one(self):
        p = Parser(
            bytearray(
                # don't include type of message as it is handled by the hello
                # protocol layer
                # b'\x02' +                     # type of message - server_hello
                b'\x00\x00\x36' +  # length - 54 bytes
                b'\x03\x03' +  # version - TLS 1.2
                b'\x01' * 31 + b'\x02' +  # random
                b'\x00' +  # session id length
                b'\x00\x9d' +  # cipher suite
                b'\x01' +  # compression method (zlib)
                b'\x00\x0f' +  # extensions length - 15 bytes (!)
                b'\xff\x01' +  # ext type - renegotiation_info
                b'\x00\x01' +  # ext length - 1 byte
                b'\x00' +  # value - supported (0)
                b'\x00\x23' +  # ext type - session ticket (35)
                b'\x00\x00' +  # ext length - 0 bytes
                b'\x00\x0f' +  # ext type - heartbeat (15)
                b'\x00\x01' +  # ext length - 1 byte
                b'\x01'))  # peer allowed to send requests (1)
        server_hello = ServerHello()

        with self.assertRaises(SyntaxError) as context:
            server_hello.parse(p)

        # TODO the message could be more descriptive...
        self.assertIsNone(context.exception.msg)
Пример #45
0
    def test_parse_with_SSLv2_client_hello(self):
        parser = Parser(
            bytearray(
                # length and type is handled by hello protocol parser
                #b'\x80\x2e' +           # length - 46 bytes
                #b'\x01' +               # message type - client hello
                b'\x00\x02' +  # version - SSLv2
                b'\x00\x15' +  # cipher spec length - 21 bytes
                b'\x00\x00' +  # session ID length - 0 bytes
                b'\x00\x10' +  # challange length - 16 bytes
                b'\x07\x00\xc0' +  # cipher - SSL2_DES_192_EDE3_CBC_WITH_MD5
                b'\x05\x00\x80' +  # cipher - SSL2_IDEA_128_CBC_WITH_MD5
                b'\x03\x00\x80' +  # cipher - SSL2_RC2_CBC_128_CBC_WITH_MD5
                b'\x01\x00\x80' +  # cipher - SSL2_RC4_128_WITH_MD5
                b'\x06\x00\x40' +  # cipher - SSL2_DES_64_CBC_WITH_MD5
                b'\x04\x00\x80' +  # cipher - SSL2_RC2_CBC_128_CBC_WITH_MD5
                b'\x02\x00\x80' +  # cipher - SSL2_RC4_128_EXPORT40_WITH_MD5
                b'\x01' * 16  # challenge
            ))
        client_hello = ClientHello(ssl2=True)

        client_hello = client_hello.parse(parser)

        # XXX the value on the wire is LSB, but should be interpreted MSB for
        # SSL2
        self.assertEqual((0, 2), client_hello.client_version)
        self.assertEqual(bytearray(0), client_hello.session_id)
        self.assertEqual(
            [458944, 327808, 196736, 65664, 393280, 262272, 131200],
            client_hello.cipher_suites)
        self.assertEqual(bytearray(b'\x00' * 16 + b'\x01' * 16),
                         client_hello.random)
        self.assertEqual([0], client_hello.compression_methods)
Пример #46
0
    def test_parse_with_invalid_data(self):
        parser = Parser(bytearray(b'\x00\x01\x00'))

        ext = SupportedGroupsExtension()

        with self.assertRaises(SyntaxError):
            ext.parse(parser)
Пример #47
0
    def test_parse_with_TACK_extension(self):
        p = Parser(
            bytearray(
                # we don't include the type of message as it is handled by the
                # hello protocol parser
                #b'x01' +             # type of message - client_hello
                b'\x00' * 2 + b'\x2c' +  # length - 44 bytes
                b'\x01\x01' +  # protocol version - arbitrary (invalid)
                b'\x00' * 32 +  # client random
                b'\x00' +  # session ID length
                b'\x00' * 2 +  # cipher suites length
                b'\x00' +  # compression methods length
                b'\x00\x04' +  # extensions length - 4 bytes
                b'\xf3\x00' +  # extension type - TACK (62208)
                b'\x00\x00'  # extension length - 0 bytes
            ))
        client_hello = ClientHello()
        client_hello = client_hello.parse(p)

        self.assertEqual((1, 1), client_hello.client_version)
        self.assertEqual(bytearray(32), client_hello.random)
        self.assertEqual(bytearray(0), client_hello.session_id)
        self.assertEqual([], client_hello.cipher_suites)
        self.assertEqual([], client_hello.compression_methods)
        self.assertEqual(True, client_hello.tack)
        tack = TLSExtension().create(62208, bytearray(0))
        self.assertEqual([tack], client_hello.extensions)
Пример #48
0
    def process(state, msg):
        """
        Check received Certificate Request

        @type state: ConnectionState
        """
        assert msg.contentType == ContentType.handshake

        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == HandshakeType.certificate_request

        cert_request = CertificateRequest(state.version)
        cert_request.parse(parser)

        state.handshake_messages.append(cert_request)
        state.handshake_hashes.update(msg.write())
    def test_lengthCheck_with_incorrect_parsing(self):
        p = Parser(bytearray(b"\x06" + b"\x00\x00" + b"\x02" + b"\x01\x02" + b"\x03"))

        p.startLengthCheck(1)
        self.assertEqual([0, 0], p.getFixList(1, 2))
        self.assertEqual([1, 2], p.getVarList(1, 1))
        with self.assertRaises(SyntaxError):
            p.stopLengthCheck()
    def test_lengthCheck(self):
        p = Parser(bytearray(b"\x06" + b"\x00\x00" + b"\x03" + b"\x01\x02\x03"))

        p.startLengthCheck(1)

        self.assertEqual([0, 0], p.getFixList(1, 2))
        self.assertEqual([1, 2, 3], p.getVarList(1, 1))
        # should not raise exception
        p.stopLengthCheck()
Пример #51
0
def filter(packetNo, data, source, target):
    bytes = stringToBytes(data)
    if packetNo == 0 and 'Client2Server' in str(source):
        p = Parser(bytes[5:])
        p.get(1)
        clientHello = ClientHello()
        clientHello.parse(p)
        print bcolors.OKGREEN + "Client supports TLS version: %s" % \
            str(clientHello.client_version)
        print "Client supports ciphersuites: %s" % \
            str([CIPHER_MAP.get(i,i) for i in clientHello.cipher_suites]) \
            + bcolors.ENDC
    elif packetNo == 0 and 'Client2Server' not in str(source):
        p = Parser(bytes[5:])
        p.get(1)
        serverHello = ServerHello()
        serverHello.parse(p)
        print bcolors.OKGREEN + "Server selected TLS version: %s" % \
            str(serverHello.server_version)
        print "Server selected ciphersuite: %s" % \
            str(CIPHER_MAP.get(serverHello.cipher_suite,
                               serverHello.cipher_suite)) + bcolors.ENDC

    target.write(data)        
    return data
Пример #52
0
    def process(self, state, msg):
        """
        Process the message and update state accordingly

        @type state: ConnectionState
        @param state: overall state of TLS connection

        @type msg: Message
        @param msg: TLS Message read from socket
        """
        # the value is faked for SSLv2 protocol, but let's just check sanity
        assert msg.contentType == ContentType.handshake

        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == SSL2HandshakeType.server_hello

        server_hello = ServerHello2().parse(parser)

        state.handshake_messages.append(server_hello)
        state.handshake_hashes.update(msg.write())

        if self.version is not None:
            assert self.version == server_hello.server_version

        if server_hello.session_id_hit:
            state.resuming = True
        state.session_id = server_hello.session_id
        state.server_random = server_hello.session_id
        state.version = server_hello.server_version
        state.msg_sock.version = server_hello.server_version

        # fake a certificate message so finding the server public key works
        x509 = X509()
        x509.parseBinary(server_hello.certificate)
        cert_chain = X509CertChain([x509])
        certificate = Certificate(CertificateType.x509)
        certificate.create(cert_chain)
        state.handshake_messages.append(certificate)
    def test_setLengthCheck_with_bad_data(self):
        p = Parser(bytearray(b"\x04" + b"\x00\x01" + b"\x00\x02"))

        p.setLengthCheck(7)
        self.assertEqual([1, 2], p.getVarList(2, 1))

        with self.assertRaises(SyntaxError):
            p.stopLengthCheck()
Пример #54
0
    def process(self, state, msg):
        """
        @type state: ConnectionState
        @type msg: Message
        """
        assert msg.contentType == ContentType.handshake
        parser = Parser(msg.write())
        hs_type = parser.get(1)
        assert hs_type == self.handshake_type
        if self.version is None:
            self.version = state.version

        if self.version in ((0, 2), (2, 0)):
            finished = ServerFinished()
        else:
            finished = Finished(self.version)

        finished.parse(parser)

        if self.version in ((0, 2), (2, 0)):
            state.session_id = finished.verify_data
        else:
            verify_expected = calcFinished(state.version,
                                           state.master_secret,
                                           state.cipher,
                                           state.handshake_hashes,
                                           not state.client)

            assert finished.verify_data == verify_expected

        state.handshake_messages.append(finished)
        state.server_verify_data = finished.verify_data
        state.handshake_hashes.update(msg.write())

        if self.version in ((0, 2), (2, 0)):
            state.msg_sock.handshake_finished = True
    def test_setLengthCheck(self):
        p = Parser(bytearray(
            b'\x06' +
            b'\x00\x01' +
            b'\x00\x02' +
            b'\x00\x03'
            ))

        p.setLengthCheck(7)
        self.assertEqual([1,2,3], p.getVarList(2,1))
        p.stopLengthCheck()
    def test_getVarBytes(self):
        p = Parser(bytearray(b'\x02\x01\x00'))

        self.assertEqual(bytearray(b'\x01\x00'), p.getVarBytes(1))
        self.assertEqual(3, p.index)
    def test_getFixBytes(self):
        p = Parser(bytearray(b'\x02\x01\x00'))

        self.assertEqual(bytearray(b'\x02\x01'), p.getFixBytes(2))
        self.assertEqual(2, p.index)
    def test_get(self):
        p = Parser(bytearray(b'\x02\x01\x00'))

        self.assertEqual(2, p.get(1))
        self.assertEqual(256, p.get(2))
        self.assertEqual(3, p.index)
    def test_setLengthCheck(self):
        p = Parser(bytearray(b"\x06" + b"\x00\x01" + b"\x00\x02" + b"\x00\x03"))

        p.setLengthCheck(7)
        self.assertEqual([1, 2, 3], p.getVarList(2, 1))
        p.stopLengthCheck()