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)
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
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)
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
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)
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)
def test_parse_with_bad_cert_type_extension(self): p = Parser( bytearray(b'\x00\x00\x2e' + # length - 46 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'\x00' + # compression method (none) b'\x00\x06' + # extensions length - 5 bytes b'\x00\x09' + # ext type - cert_type (9) b'\x00\x02' + # ext length - 2 bytes b'\x00\x01' # value - X.509 (0), OpenPGP (1) )) server_hello = ServerHello() with self.assertRaises(SyntaxError) as context: server_hello.parse(p)
def test_parse_with_bad_cert_type_extension(self): p = Parser(bytearray( b'\x00\x00\x2e' + # length - 46 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'\x00' + # compression method (none) b'\x00\x06' + # extensions length - 5 bytes b'\x00\x09' + # ext type - cert_type (9) b'\x00\x02' + # ext length - 2 bytes b'\x00\x01' # value - X.509 (0), OpenPGP (1) )) server_hello = ServerHello() with self.assertRaises(SyntaxError) as context: server_hello.parse(p)
def test_parse_with_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\x27' + # length - 39 bytes (one long) 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) )) server_hello = ServerHello() with self.assertRaises(SyntaxError) as context: server_hello.parse(p) # TODO the message probably could be more descriptive... self.assertIsNone(context.exception.msg)
def test_parse_with_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\x27' + # length - 39 bytes (one long) 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) )) server_hello = ServerHello() with self.assertRaises(SyntaxError) as context: server_hello.parse(p) # TODO the message probably could be more descriptive... self.assertIsNone(context.exception.msg)
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.cipher = srv_hello.cipher_suite state.version = srv_hello.server_version state.server_random = srv_hello.random # 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
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 if self.cipher is not None: assert self.cipher == srv_hello.cipher_suite 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()) # Reset value of the session-wide settings state.extended_master_secret = False state.encrypt_then_mac = False # 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) if ext is None: raise AssertionError( "Required extension {0} missing".format( ExtensionType.toStr(ext_id))) # run extension-specific checker if present if self.extensions[ext_id] is not None: if callable(self.extensions[ext_id]): self.extensions[ext_id](state, ext) elif isinstance(self.extensions[ext_id], TLSExtension): if not self.extensions[ext_id] == ext: raise AssertionError( "Expected extension " "not matched, received: {0}".format(ext)) else: raise ValueError( "Bad extension, id: {0}".format(ext_id)) continue if ext_id == ExtensionType.extended_master_secret: state.extended_master_secret = True if ext_id == ExtensionType.encrypt_then_mac: state.encrypt_then_mac = True # 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): if ext_id not in self.extensions: raise AssertionError( "unexpected extension: {0}".format( ExtensionType.toStr(ext_id)))
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) and self._extract_version(srv_hello) < (3, 4)): # TLS 1.2 resumption, TLS 1.3 is based on PSKs state.resuming = True assert state.cipher == srv_hello.cipher_suite assert state.version == self._extract_version(srv_hello) state.session_id = srv_hello.session_id if self.version is not None: assert self.version == srv_hello.server_version if self.cipher is not None: assert self.cipher == srv_hello.cipher_suite # check if server sent cipher matches what we advertised in CH cln_hello = state.get_last_message_of_type(ClientHello) if srv_hello.cipher_suite not in cln_hello.cipher_suites: cipher = srv_hello.cipher_suite if cipher in CipherSuite.ietfNames: name = "{0} ({1:#06x})".format(CipherSuite.ietfNames[cipher], cipher) else: name = "{0:#06x}".format(cipher) raise AssertionError("Server responded with cipher we did" " not advertise: {0}".format(name)) state.cipher = srv_hello.cipher_suite state.version = self._extract_version(srv_hello) # update the state of connection state.msg_sock.version = state.version state.msg_sock.tls13record = state.version > (3, 3) self._check_against_hrr(state, srv_hello) state.handshake_messages.append(srv_hello) state.handshake_hashes.update(msg.write()) # Reset value of the session-wide settings state.extended_master_secret = False state.encrypt_then_mac = False if srv_hello.extensions: self._process_extensions(state, cln_hello, srv_hello) self._compare_extensions(srv_hello) if state.version > (3, 3): self._setup_tls13_handshake_keys(state) return srv_hello
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()) # Reset value of the session-wide settings state.extended_master_secret = False # 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) if ext_id == ExtensionType.extended_master_secret: state.extended_master_secret = True # 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