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 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()
def test_parse(self): parser = Parser(bytearray(b'\x02\xab\xcd')) ext = RenegotiationInfoExtension() ext.parse(parser) self.assertEqual(bytearray(b'\xab\xcd'), ext.renegotiated_connection)
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())
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_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)
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)
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)
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)
def test_parse_with_SRP_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'\x35' + # length - 53 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\x0d' + # extensions length - 13 bytes b'\x00\x0c' + # extension type - SRP (12) b'\x00\x09' + # extension length - 9 bytes b'\x08' + # length of name - 8 bytes b'username' # UTF-8 encoding of "username" :) )) 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(b'username'), client_hello.srp_username) srp = SRPExtension().create(bytearray(b'username')) self.assertEqual([srp], client_hello.extensions)
def test_parse_with_cert_type_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'\x2f' + # length - 47 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\x07' + # extensions length - 7 bytes b'\x00\x09' + # extension type - certTypes (9) b'\x00\x03' + # extension length - 3 bytes b'\x02' + # length of array - 2 bytes b'\x00' + # type - x509 (0) b'\x01' # type - opengpg (1) )) 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([0, 1], client_hello.certificate_types) certTypes = ClientCertTypeExtension().create([0, 1]) self.assertEqual([certTypes], client_hello.extensions)
def test_parse_with_SNI_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'\x3c' + # length - 60 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\x14' + # extensions length - 20 bytes b'\x00\x00' + # extension type - SNI (0) b'\x00\x10' + # extension length - 16 bytes b'\x00\x0e' + # length of array - 14 bytes 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')) 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(b'example.com'), client_hello.server_name) sni = SNIExtension().create(bytearray(b'example.com')) self.assertEqual([sni], client_hello.extensions)
def test_parse_with_missing_data(self): alert = Alert() parser = Parser(bytearray(b'\x01')) # level with self.assertRaises(SyntaxError): alert.parse(parser)
def test_parse_with_no_data(self): parser = Parser(bytearray()) ext = KeyShareExtension() ext.parse(parser) self.assertIsNone(ext.client_shares)
def tes_parse_with_invalid_data(self): server_name = SNIExtension() p = Parser(bytearray(b'\x00\x01')) with self.assertRaises(SyntaxError): server_name.parse(p)
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)
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_length_long_by_one(self): cert_type = ClientCertTypeExtension() p = Parser(bytearray(b'\x03\x01\x00')) with self.assertRaises(SyntaxError): cert_type.parse(p)
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)
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)
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): """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_parse(self): p = Parser(bytearray(3)) tack_ext = TACKExtension().parse(p) self.assertEqual([], tack_ext.tacks) self.assertEqual(0, tack_ext.activation_flags)
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)
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)
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)
def test_parse_with_invalid_data(self): parser = Parser(bytearray(b'\x00\x01\x00')) ext = SupportedGroupsExtension() with self.assertRaises(SyntaxError): ext.parse(parser)
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_parse(self): parser = Parser(bytearray(b'\x01\x00')) ext = ECPointFormatsExtension() self.assertIsNone(ext.formats) ext.parse(parser) self.assertEqual(ext.formats, [ECPointFormat.uncompressed])