def post_send(self, status): cipher_suite = status.cipher if self.extended_master_secret is None: self.extended_master_secret = status.extended_master_secret if not status.resuming: if self.extended_master_secret: master_secret = \ calcExtendedMasterSecret(status.version, cipher_suite, status.premaster_secret, status.handshake_hashes) else: master_secret = calcMasterSecret(status.version, cipher_suite, status.premaster_secret, status.client_random, status.server_random) status.master_secret = master_secret # in case of resumption, the pending states are generated # during receive of server sent CCS calc_pending_states(status) status.msg_sock.changeWriteState()
def to_bytes(self): [client_hello] = [ msg.body for msg in self.handshake_messages if msg.handshake_type == HandshakeType.client_hello ] [server_hello] = [ msg.body for msg in self.handshake_messages if msg.handshake_type == HandshakeType.server_hello ] negotiated_version = server_hello.version negotiated_version = negotiated_version.to_bytes(2, byteorder="big") negotiated_version = (negotiated_version[0], negotiated_version[1]) negotiated_cipher_suite = server_hello.cipher_suite handshake_messages = EMPTY_BYTES.join( [m.to_bytes() for m in self.handshake_messages]) master_secret = calcMasterSecret( negotiated_version, negotiated_cipher_suite, self.pre_master_secret, client_hello.random_bytes, server_hello.random_bytes, ) finished = PRF( master_secret, self.FINISHED_LABEL, MD5(handshake_messages) + SHA1(handshake_messages), 12, ) return bytes.fromhex("00" * 48) # doesn't matter
def post_send(self, status): """Generate new encryption keys for connection.""" cipher_suite = status.cipher status.msg_sock.encryptThenMAC = status.encrypt_then_mac if self.extended_master_secret is None: self.extended_master_secret = status.extended_master_secret if not status.resuming: if self.extended_master_secret: # in case client certificates are used, we need to omit # certificate verify message hh = status.certificate_verify_handshake_hashes if not hh: hh = status.handshake_hashes master_secret = \ calcExtendedMasterSecret(status.version, cipher_suite, status.premaster_secret, hh) else: master_secret = calcMasterSecret(status.version, cipher_suite, status.premaster_secret, status.client_random, status.server_random) status.master_secret = master_secret # in case of resumption, the pending states are generated # during receive of server sent CCS calc_pending_states(status) status.msg_sock.changeWriteState()
def test_with_empty_values(self): ret = calcMasterSecret((3, 3), 0, bytearray(48), bytearray(32), bytearray(32)) self.assertEqual(bytearray( b'I\xcf\xae\xe5[\x86\x92\xd3\xbbm\xd6\xeekSo/' + b'\x17\xaf\xbc\x84\x18\tGc\xbc\xb5\xbe\xd6\xb0\x05\xad\xf8' + b'\x88\xd0`\xe4\x8c^\xb2&ls\xcb\x1a=-Kh' ), ret) self.assertEqual(48, len(ret))
def test_with_empty_values(self): ret = calcMasterSecret((3, 3), 0, bytearray(48), bytearray(32), bytearray(32)) self.assertEqual( bytearray( b'I\xcf\xae\xe5[\x86\x92\xd3\xbbm\xd6\xeekSo/' + b'\x17\xaf\xbc\x84\x18\tGc\xbc\xb5\xbe\xd6\xb0\x05\xad\xf8' + b'\x88\xd0`\xe4\x8c^\xb2&ls\xcb\x1a=-Kh'), ret) self.assertEqual(48, len(ret))
def post_send(self, status): cipher_suite = status.cipher master_secret = calcMasterSecret(status.version, cipher_suite, status.premaster_secret, status.client_random, status.server_random) status.master_secret = master_secret status.msg_sock.calcPendingStates(cipher_suite, master_secret, status.client_random, status.server_random, None) status.msg_sock.changeWriteState()
def post_send(self, status): cipher_suite = status.cipher if not status.resuming: master_secret = calcMasterSecret(status.version, cipher_suite, status.premaster_secret, status.client_random, status.server_random) status.master_secret = master_secret # in case of resumption, the pending states are generated # during receive of server sent CCS status.msg_sock.calcPendingStates(cipher_suite, master_secret, status.client_random, status.server_random, None) status.msg_sock.changeWriteState()
def handshakeProxy(c_conn, s_conn, oracle): s_conn._handshakeStart(client=False) c_conn._handshakeStart(client=True) s_settings = HandshakeSettings() c_settings = HandshakeSettings() # CLIENT HELLO C -> S for result in s_conn._getMsg(ContentType.handshake, HandshakeType.client_hello): if result in (0, 1): yield result else: break clientHello = result c_conn.version = (3, 1) # Hardcoded version for result in c_conn._sendMsg(clientHello): yield result # Send Server Hello, Certificate and Server Hello Done in one packet s_conn.sock.buffer_writes = True # SERVER HELLO S -> C for result in c_conn._getMsg(ContentType.handshake, HandshakeType.server_hello): if result in (0, 1): yield result else: break serverHello = result s_conn.version = serverHello.server_version cipherSuite = serverHello.cipher_suite for result in s_conn._sendMsg(serverHello): yield result # CERTIFICATE S -> C for result in c_conn._getMsg( ContentType.handshake, HandshakeType.certificate, serverHello.certificate_type): # FIXME : we should only allow RSA if result in (0, 1): yield result else: break serverCertificate = result for result in s_conn._sendMsg(serverCertificate): yield result # CERTIFICATE REQUEST S -> C if 0: for result in c_conn._getMsg(ContentType.handshake, HandshakeType.certificate_request): if result in (0, 1): yield result else: break certificate_request = result for result in s_conn._sendMsg(certificate_request): yield result # SERVER HELLO DONE S -> C for result in c_conn._getMsg(ContentType.handshake, HandshakeType.server_hello_done): if result in (0, 1): yield result else: break serverHelloDone = result for result in s_conn._sendMsg(serverHelloDone): yield result s_conn.sock.flush() s_conn.sock.buffer_writes = False # Send Client Key Exchange, Change Cipher Spec, Finished in one message c_conn.sock.buffer_writes = True # CERTIFICATE C -> S if 0: for result in s_conn._getMsg(ContentType.handshake, HandshakeType.certificate, serverHello.certificate_type ): # FIXME : we should allow anything ? if result in (0, 1): yield result else: break clientCertificate = result for result in c_conn._sendMsg(clientCertificate): yield result # CLIENT KEY EXCHANGE C -> S for result in s_conn._getMsg(ContentType.handshake, HandshakeType.client_key_exchange, cipherSuite): if result in (0, 1): yield result else: break clientKeyExchange = result # Ask the oracle if we continue epms = clientKeyExchange.encryptedPreMasterSecret if not oracle(epms): # YOU SHALL NOT PASS ! print("Shall not pass") return print("Decoding phase") # Decrypt master key dec = subprocess.Popen(['./decrypt', '{}:{}'.format(*oracleaddr), cert], stdin=subprocess.PIPE, stdout=subprocess.PIPE) dec.stdin.write(hexlify(epms) + b'\n') dec.stdin.close() res = dec.stdout.readline().strip().split()[-1] dec.stdout.close() print(res) premasterSecret = unhexlify(res) # If it's ok, continue for result in c_conn._sendMsg(clientKeyExchange): yield result settings = HandshakeSettings() masterSecret = calcMasterSecret(c_conn.version, cipherSuite, premasterSecret, clientHello.random, serverHello.random) print(masterSecret) s_conn._calcPendingStates(cipherSuite, masterSecret, clientHello.random, serverHello.random, settings.cipherImplementations) c_conn._calcPendingStates(cipherSuite, masterSecret, clientHello.random, serverHello.random, settings.cipherImplementations) print('foobar') # CHANGE-CIPHER-SPEC C -> S for result in s_conn._getMsg(ContentType.change_cipher_spec): if result in (0, 1): yield result s_changeCipherSpec = result for result in c_conn._sendMsg(s_changeCipherSpec): yield result s_conn._changeReadState() c_conn._changeWriteState() # SERVER-FINISHED C -> S for result in s_conn._getMsg(ContentType.handshake, HandshakeType.finished): if result in (0, 1): yield result server_finished = result for result in c_conn._sendMsg(server_finished): yield result c_conn.sock.flush() c_conn.sock.buffer_writes = False # Send New Session Ticket, Change Cipher Spec, Finished in one message s_conn.sock.buffer_writes = True # NEW-SESSION-TICKET for result in c_conn._getMsg(ContentType.handshake, HandshakeType.new_session_ticket): if result in (0, 1): yield result newSessionTicket = result for result in s_conn._sendMsg(newSessionTicket): yield result # CHANGE-CIPHER-SPEC for result in c_conn._getMsg(ContentType.change_cipher_spec): if result in (0, 1): yield result c_changeCipherSpec = result for result in s_conn._sendMsg(c_changeCipherSpec): yield result c_conn._changeReadState() s_conn._changeWriteState() # SERVER-FINISHED for result in c_conn._getMsg(ContentType.handshake, HandshakeType.finished): if result in (0, 1): yield result client_finished = result for result in s_conn._sendMsg(client_finished): yield result s_conn.sock.flush() s_conn.sock.buffer_writes = False c_conn._handshakeDone(False) s_conn._handshakeDone(False) cont = True while cont: for c_data, s_data in zip(c_conn.readAsync(), s_conn.readAsync()): if c_data in (0, 1): yield c_data elif not c_data: # End connection print('server ended') cont = False else: print('c', c_data) for result in s_conn.writeAsync(c_data): yield result if s_data in (0, 1): yield s_data elif not s_data: # End connection print('client ended') cont = False else: print('s', s_data) for result in c_conn.writeAsync(s_data): yield result c_conn.close() s_conn.close() print("The end")
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 = 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 = 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.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 handshakeProxy(c_conn, s_conn, oracle): s_conn._handshakeStart(client=False) c_conn._handshakeStart(client=True) s_settings = HandshakeSettings() c_settings = HandshakeSettings() # CLIENT HELLO C -> S for result in s_conn._getMsg(ContentType.handshake, HandshakeType.client_hello): if result in (0,1): yield result else: break clientHello = result c_conn.version = (3, 1) # Hardcoded version for result in c_conn._sendMsg(clientHello): yield result # Send Server Hello, Certificate and Server Hello Done in one packet s_conn.sock.buffer_writes = True # SERVER HELLO S -> C for result in c_conn._getMsg(ContentType.handshake, HandshakeType.server_hello): if result in (0,1): yield result else: break serverHello = result s_conn.version = serverHello.server_version cipherSuite = serverHello.cipher_suite for result in s_conn._sendMsg(serverHello): yield result # CERTIFICATE S -> C for result in c_conn._getMsg(ContentType.handshake, HandshakeType.certificate, serverHello.certificate_type): # FIXME : we should only allow RSA if result in (0,1): yield result else: break serverCertificate = result for result in s_conn._sendMsg(serverCertificate): yield result # CERTIFICATE REQUEST S -> C if 0: for result in c_conn._getMsg(ContentType.handshake, HandshakeType.certificate_request): if result in (0,1): yield result else: break certificate_request = result for result in s_conn._sendMsg(certificate_request): yield result # SERVER HELLO DONE S -> C for result in c_conn._getMsg(ContentType.handshake, HandshakeType.server_hello_done): if result in (0,1): yield result else: break serverHelloDone = result for result in s_conn._sendMsg(serverHelloDone): yield result s_conn.sock.flush() s_conn.sock.buffer_writes = False # Send Client Key Exchange, Change Cipher Spec, Finished in one message c_conn.sock.buffer_writes = True # CERTIFICATE C -> S if 0: for result in s_conn._getMsg(ContentType.handshake, HandshakeType.certificate, serverHello.certificate_type): # FIXME : we should allow anything ? if result in (0,1): yield result else: break clientCertificate = result for result in c_conn._sendMsg(clientCertificate): yield result # CLIENT KEY EXCHANGE C -> S for result in s_conn._getMsg(ContentType.handshake, HandshakeType.client_key_exchange, cipherSuite): if result in (0,1): yield result else: break clientKeyExchange = result # Ask the oracle if we continue epms = clientKeyExchange.encryptedPreMasterSecret if not oracle(epms): # YOU SHALL NOT PASS ! print("Shall not pass") return print("Decoding phase") # Decrypt master key dec = subprocess.Popen(['./decrypt', '{}:{}'.format(*oracleaddr), cert], stdin=subprocess.PIPE, stdout=subprocess.PIPE) dec.stdin.write(hexlify(epms) + b'\n') dec.stdin.close() res = dec.stdout.readline().strip().split()[-1] dec.stdout.close() print(res) premasterSecret = unhexlify(res) # If it's ok, continue for result in c_conn._sendMsg(clientKeyExchange): yield result settings = HandshakeSettings() masterSecret = calcMasterSecret(c_conn.version, cipherSuite, premasterSecret, clientHello.random, serverHello.random) print(masterSecret) s_conn._calcPendingStates(cipherSuite, masterSecret, clientHello.random, serverHello.random, settings.cipherImplementations) c_conn._calcPendingStates(cipherSuite, masterSecret, clientHello.random, serverHello.random, settings.cipherImplementations) print('foobar') # CHANGE-CIPHER-SPEC C -> S for result in s_conn._getMsg(ContentType.change_cipher_spec): if result in (0,1): yield result s_changeCipherSpec = result for result in c_conn._sendMsg(s_changeCipherSpec): yield result s_conn._changeReadState() c_conn._changeWriteState() # SERVER-FINISHED C -> S for result in s_conn._getMsg(ContentType.handshake, HandshakeType.finished): if result in (0,1): yield result server_finished = result for result in c_conn._sendMsg(server_finished): yield result c_conn.sock.flush() c_conn.sock.buffer_writes = False # Send New Session Ticket, Change Cipher Spec, Finished in one message s_conn.sock.buffer_writes = True # NEW-SESSION-TICKET for result in c_conn._getMsg(ContentType.handshake, HandshakeType.new_session_ticket): if result in (0,1): yield result newSessionTicket = result for result in s_conn._sendMsg(newSessionTicket): yield result # CHANGE-CIPHER-SPEC for result in c_conn._getMsg(ContentType.change_cipher_spec): if result in (0,1): yield result c_changeCipherSpec = result for result in s_conn._sendMsg(c_changeCipherSpec): yield result c_conn._changeReadState() s_conn._changeWriteState() # SERVER-FINISHED for result in c_conn._getMsg(ContentType.handshake, HandshakeType.finished): if result in (0,1): yield result client_finished = result for result in s_conn._sendMsg(client_finished): yield result s_conn.sock.flush() s_conn.sock.buffer_writes = False c_conn._handshakeDone(False) s_conn._handshakeDone(False) cont = True while cont: for c_data, s_data in zip(c_conn.readAsync(), s_conn.readAsync()): if c_data in (0, 1): yield c_data elif not c_data: # End connection print('server ended') cont = False else: print('c', c_data) for result in s_conn.writeAsync(c_data): yield result if s_data in (0, 1): yield s_data elif not s_data: # End connection print('client ended') cont = False else: print('s', s_data) for result in c_conn.writeAsync(s_data): yield result c_conn.close() s_conn.close() print("The end")