def test_encrypted_pms_is_only_available_after_server_certificate_is_presented( self): pkt = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSClientHello() tls_ctx = tlsc.TLSSessionCtx() tls_ctx.insert(pkt) with self.assertRaises(ValueError): tls_ctx.get_encrypted_pms()
def _do_kex(self, version): self.pem_priv_key = """-----BEGIN PRIVATE KEY----- MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDDLrmt4lKRpm6P 2blptwJsa1EBuxuuAayLjwNqKGvm5c1CAUEa/NtEpUMM8WYKRDwxzakUIGI/BdP3 NOEMphcs5+OekgJLhzoSdtAIrXPy8JIidENZE6FzCJ2b6fHU5O4hoNvv1Bx5yoZr HVaWJIZMRRocJJ0Nf9oMaU8IE6m6OdBzQHEwcnL2/a8Q3VxstHufzjILmaZD9WL+ 6AESlQMKZPNQ+Xd7d4nvnVkY4ZV46tA+KvADGuotgovQwG+uiyQoGRrQUms21vHF zIvd3G9OCiyCTCHSyfsE3g7tks33NZ8O8gF8xa9OmU9TQPwwAyUr6JQXz0CW77o7 Cr9LpHuNAgMBAAECggEBAJRbMbtfqc8XqDYjEfGur2Lld19Pb0yl7RbvD3NjYhDR X2DqPyhaRfg5fWubGSp4jyBz6C5qJwMsVN80DFNm83qoj7T52lC6aoOaV6og3V8t SIZzxLUyXKdpRxM5kR13HSHmeQYkPbi9HcrRM/1PqdzTMXNuyQl3wq9oZDAJchsf fmoh080htkaxhEb1bMXa2Lj7j2OIkHOsQeIu6BdbxIKRPIT+zrcklE6ocW8fTWAS Qi3IZ1FYLL+fs6TTxjx0VkC8QLaxWxY0pqTiwS7ndZiZKc3l3ARuvRk8buP+X3Jg BD86FQ18OXZC9boMbDbzv2cOLtdkq5pS3lJE4F9gjYECgYEA69ukU2pNWot2OPwK PuPwAXWNrvnvFzQgIc0qOiCmgKJU6wqunlop4Bx5XmetHExVyJVBEhaHoDr0F3Rs gt8IclKDsWGXoVcgfu3llMimiZ05hOf/XtcGTCZwZenMQ30cFh4ZRuUu7WCZ9tqO 28P8jCXB3IcaRpRnNvVvmCr5NXECgYEA09nUzRW993SlohceRW2C9fT9HZ4BaPWO 5wVlnoo5mlUfAyzl+AGT/WlKmrn/1gAHIznQJ8ZIABQvPaBXhvkANXZP5Ie0lObw jA7qFuKt7yV4GGlDnU1MOLh+acABMQBGSx8BJDaomH7glTiPEPTZjoP6wfAsd1uv Knjt7jH2ad0CgYEAx9ghknRd+rx0fbBBVix4riPW20324ihOmZVnlD0aF6B0Z3tz ncUz+irmQ7GBIpsjjIO60QK6BHAvZrhFQVaNp6B26ZORkSlr5WDZyImDYtMPa6fP 36I+OcPQNOo3I3Acnjj+ne2PJ59Ula92oIudr3pGmv72qpsQIacw2TSAWGECgYEA sdNAN+HPMn68ZaGoLDjvW8uIB6tQnay5hhvWn8yA65YV0RGH+7Q/Z9BQ6i3EnPor A5uMqUZbu4011jHYJpiuXzHvf/GVWAO92KLQReOCgqHd/Aen1MtEdrwOiG+90Ebd ukLNL3ud61tc4oS2OlJ8p48LFm2mtY3FLA6UEYPoxhUCgYEAtsfWIGnBh7XC+HwI 2higSgN92VpJHSPOyOi0aG/u5AEQ+fsCUIi3KakxzvmiGMAEvWItkKyz2Gu8smtn 2HVsGxI5UW7aLw9s3qe8kyMSfUk6pGamVhJUQmDr77+5zEzykPBxwGwDwdeR43CR xVgf/Neb/avXgIgi6drj8dp1fWA= -----END PRIVATE KEY----- """ rsa_priv_key = RSA.importKey(self.pem_priv_key) self.priv_key = PKCS1_v1_5.new(rsa_priv_key) self.pub_key = PKCS1_v1_5.new(rsa_priv_key.publickey()) self.tls_ctx = tlsc.TLSSessionCtx() self.tls_ctx.rsa_load_keys(self.pem_priv_key) # SSLv2 self.record_version = 0x0002 self.version = version # RSA_WITH_AES_128_SHA self.cipher_suite = tls.TLSCipherSuite.RSA_WITH_AES_128_CBC_SHA # DEFLATE self.comp_method = tls.TLSCompressionMethod.NULL self.client_hello = tls.TLSRecord( version=self.record_version) / tls.TLSHandshake( ) / tls.TLSClientHello(version=version, compression_methods=[self.comp_method], cipher_suites=[self.cipher_suite]) self.tls_ctx.insert(self.client_hello) self.server_hello = tls.TLSRecord( version=self.version) / tls.TLSHandshake() / tls.TLSServerHello( version=version, compression_method=self.comp_method, cipher_suite=self.cipher_suite) self.tls_ctx.insert(self.server_hello) # Build method to generate EPMS automatically in TLSSessionCtx self.client_kex = tls.TLSRecord( version=self.version) / tls.TLSHandshake( ) / tls.TLSClientKeyExchange(data=self.tls_ctx.get_encrypted_pms()) self.tls_ctx.insert(self.client_kex)
def test_encrypting_pms_fails_if_no_certificate_in_connection(self): tls_ctx = tlsc.TLSSessionCtx() pkt = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSClientHello( version=0x0301) tls_ctx.insert(pkt) with self.assertRaises(ValueError): tls_ctx.get_encrypted_pms()
def setUp(self): self.pkt = tls.TLSRecord()/ \ tls.TLSHandshake()/ \ tls.TLSClientHello(extensions=[ \ tls.TLSExtension()/ \ tls.TLSExtServerNameIndication(server_names=[tls.TLSServerName(data="www.github.com"), tls.TLSServerName(data="github.com")]), \ tls.TLSExtension()/ \ tls.TLSExtALPN(protocol_name_list=[tls.TLSALPNProtocol(data="http/1.1"), tls.TLSALPNProtocol(data="http/1.0")]), tls.TLSExtension()/ \ tls.TLSExtALPN(protocol_name_list=[tls.TLSALPNProtocol(data="http/2.0"),]), tls.TLSExtension()/ \ tls.TLSExtMaxFragmentLength(fragment_length=0x03), tls.TLSExtension()/ \ tls.TLSExtCertificateURL(certificate_urls=[tls.TLSURLAndOptionalHash(url="http://www.github.com/tintinweb")]), tls.TLSExtension()/ \ tls.TLSExtECPointsFormat(ec_point_formats=[tls.TLSEcPointFormat.ANSIX962_COMPRESSED_CHAR2]), tls.TLSExtension()/ \ tls.TLSExtEllipticCurves(elliptic_curves=[tls.TLSEllipticCurve.SECT571R1,]), tls.TLSExtension()/ \ tls.TLSExtHeartbeat(mode=tls.TLSHeartbeatMode.PEER_NOT_ALLOWED_TO_SEND), tls.TLSExtension()/ \ tls.TLSExtSessionTicketTLS(data="myticket"), tls.TLSExtension()/ \ tls.TLSExtRenegotiationInfo(data="myreneginfo"), ],) unittest.TestCase.setUp(self)
def test_fixed_crypto_data_matches_verify_data(self): client_verify_data = "e23f73911909a86be9e93fdb" server_verify_data = "c83b8eb028d3c4a8d82c1c17" tls_ctx = tlsc.TLSSessionCtx() # tls_ctx.rsa_load_keys(self.pem_priv_key) client_hello = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSClientHello(gmt_unix_time=1234, random_bytes="A" * 28) # Hello Request should be ignored in verify_data calculation tls_ctx.insert(tls.TLSHelloRequest()) tls_ctx.insert(client_hello) tls_ctx.premaster_secret = "B" * 48 epms = "C" * 256 server_hello = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSServerHello(gmt_unix_time=1234, session_id="", random_bytes="A" * 28) tls_ctx.insert(server_hello) client_kex = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSClientKeyExchange() /\ tls.TLSClientRSAParams(data=epms) tls_ctx.insert(client_kex) self.assertEqual(client_verify_data, binascii.hexlify(tls_ctx.get_verify_data())) # Make sure that client finish is included in server finish calculation tls_ctx.set_mode(server=True) client_finish = tls.TLSRecord() / tls.TLSHandshake() / tls.tls_to_raw( tls.TLSFinished(data=tls_ctx.get_verify_data()), tls_ctx) tls_ctx.insert(client_finish) self.assertEqual(server_verify_data, binascii.hexlify(tls_ctx.get_verify_data()))
def test_decrypted_pms_matches_generated_pms(self): tls_ctx = tlsc.TLSSessionCtx() tls_ctx.server_ctx.load_rsa_keys(self.pem_priv_key) pkt = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSClientHello() tls_ctx.insert(pkt) epms = tls_ctx.get_encrypted_pms() pkt = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSServerHello() tls_ctx.insert(pkt) pkt = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSClientKeyExchange() / tls.TLSClientRSAParams(data=epms) tls_ctx.insert(pkt) self.assertEqual(tls_ctx.encrypted_premaster_secret, epms) self.assertEqual(tls_ctx.premaster_secret, self.priv_key.decrypt(epms, None))
def test_keys_are_set_in_context_when_loaded(self): tls_ctx = tlsc.TLSSessionCtx() pkt = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSClientHello(version=0x0301) tls_ctx.insert(pkt) tls_ctx.server_ctx.load_rsa_keys(self.pem_priv_key) self.assertIsNotNone(tls_ctx.server_ctx.asym_keystore.private) self.assertIsNotNone(tls_ctx.server_ctx.asym_keystore.public) # Broken due to pycrypto bug: https://github.com/dlitz/pycrypto/issues/114 # Uncomment when fixed upstream # self.assertTrue(tls_ctx.crypto.server.asym_keystore.private.can_decrypt()) # self.assertTrue(tls_ctx.crypto.server.asym_keystore.public.can_decrypt()) self.assertTrue(tls_ctx.server_ctx.asym_keystore.private.can_encrypt())
def test_fixed_crypto_data_matches_verify_data(self): verify_data = "12003ac89553b7a233da64b9" tls_ctx = tlsc.TLSSessionCtx() # tls_ctx.rsa_load_keys(self.pem_priv_key) client_hello = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSClientHello(gmt_unix_time=1234, random_bytes="A" * 28) tls_ctx.insert(client_hello) tls_ctx.crypto.session.premaster_secret = "B" * 48 epms = "C" * 256 server_hello = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSServerHello(gmt_unix_time=1234, random_bytes="A" * 28) tls_ctx.insert(server_hello) client_kex = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSClientKeyExchange() /\ tls.TLSClientRSAParams(data=epms) tls_ctx.insert(client_kex) self.assertEqual(binascii.hexlify(tls_ctx.get_verify_data()), verify_data)
def _static_tls_handshake(self): # Setup static parameters, so PRF output is reproducible tls_ctx = tlsc.TLSSessionCtx() tls_ctx.crypto.session.premaster_secret = "\x03\x01" + "C" * 46 client_hello = tls.TLSRecord( version="TLS_1_0") / tls.TLSHandshake() / tls.TLSClientHello( version="TLS_1_0", gmt_unix_time=1234, random_bytes="A" * 28, session_id="", compression_methods=[0], cipher_suites=(tls.TLSCipherSuite.RSA_WITH_AES_128_CBC_SHA)) tls_ctx.insert(client_hello) server_hello = binascii.unhexlify( "160301004a02000046030155662cd45fade845839a3c8dba0e46f1abcd2fd941f4e95e75ab6d61811abcf420960ccadc00abc7043cca458d9a1df1cb877a5005b53f754ac80d392990fae3c7002f00160301047c0b0004780004750004723082046e30820356a003020102020900d1e1f53a9203251a300d06092a864886f70d0101050500308180310b3009060355040613025553311330110603550408130a536f6d652d53746174653112301006035504071309536f6d652d6369747931153013060355040a130c536f6d652d636f6d70616e793110300e060355040b1307536f6d652d4f55311f301d06035504031316736f6d652d7365727665722e736f6d652e7768657265301e170d3135303532323139313631325a170d3235303531393139313631325a308180310b3009060355040613025553311330110603550408130a536f6d652d53746174653112301006035504071309536f6d652d6369747931153013060355040a130c536f6d652d636f6d70616e793110300e060355040b1307536f6d652d4f55311f301d06035504031316736f6d652d7365727665722e736f6d652e776865726530820122300d06092a864886f70d01010105000382010f003082010a0282010100cd7b7165ee7528f107cf666edc673eedc863544ebe8cc3741346015eea182a73a9e18e26f6f1553d83843d2bdacdd4501faec7b4f5446b8790053f152e23f70d121ca7f63a22a657536ee4b50b8777568ef469905ce05211178dd9ebe223b21246cce4baf351d0b81b464830e15fb7178cf5f39e7673de7779e5dbbd7a3d2ea98589b0d6003635447693ed2ec632c3dbb632ac254e3b8cd78e1ea160982627e2cd3a369c4bb43c486141b97fbbd9d3cb014b92e0ec6ecf46ded64749bbecfb6f98d0d2f459d5cf0054a6522280af961dfcbe1650937180f43decf2f8725b94eeec10248cdc70acad63bcc3cd5370d0dc0f3cba8d369909c6b917f243e5e5bc270203010001a381e83081e5301d0603551d0e041604143cc2f7fc85dbbe4b0566b35bde744484438ae83e3081b50603551d230481ad3081aa80143cc2f7fc85dbbe4b0566b35bde744484438ae83ea18186a48183308180310b3009060355040613025553311330110603550408130a536f6d652d53746174653112301006035504071309536f6d652d6369747931153013060355040a130c536f6d652d636f6d70616e793110300e060355040b1307536f6d652d4f55311f301d06035504031316736f6d652d7365727665722e736f6d652e7768657265820900d1e1f53a9203251a300c0603551d13040530030101ff300d06092a864886f70d0101050500038201010001738e2985692d8239fb1795e6ea0718755cf106cd739f7113afd3a074add07f981b06f34b9df3e1658c153355c5061b369d60d341eb4ccefdd98d6d6790be499cde8bd5705d1a8a89bb141599f3319914f8539e294848c106386218d8679da46ba90a2ce7587265cb55d6a629569b65581ee2e88ded264b81dff1c11e2c55728efe170dfe4f76706fbbda137b02e0fa987355b0cfdb3f8637e35473e4a6eccdcbc27d55d1f956a5f2c454e937df71d42e21d45d227477e26053b8be003fa527746b163b3d4b9a585d2860e5080ed9737d4c5fa5a32eee45a4e56d8a03542349619084580cc9c6c25b1ac7f3854b501423eafdd32896af92ce8ca6923947d77c16030100040e000000" ) tls_ctx.insert(tls.TLS(server_hello)) return tls_ctx
def test_random_pms_is_generated_on_client_hello(self): tls_ctx = tlsc.TLSSessionCtx() pkt = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSClientHello( version=0x0301) tls_ctx.insert(pkt) self.assertIsNotNone(tls_ctx.crypto.session.premaster_secret)
def test_unsupported_layer_raises_error(self): pkt = tls.TLSClientHello() with self.assertRaises(KeyError): tls.to_raw(pkt, self.tls_ctx)