def test_tls_1_3_write_early_data_fail_when_trying_to_send_more_than_max_early_data(self): # Given a server that supports TLS 1.3 and early data with ModernOpenSslServer(max_early_data=1) as server: # That has a previous TLS 1.3 session with the server session = self._create_tls_1_3_session(server.hostname, server.port) assert session # And the server only accepts 1 byte of early data max_early = session.get_max_early_data() assert 1 == max_early # When creating a new connection sock_early_data = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock_early_data.settimeout(5) sock_early_data.connect((server.hostname, server.port)) ssl_client_early_data = SslClient( ssl_version=OpenSslVersionEnum.TLSV1_3, underlying_socket=sock_early_data, ssl_verify=OpenSslVerifyEnum.NONE ) # That re-uses the previous TLS 1.3 session ssl_client_early_data.set_session(session) assert OpenSslEarlyDataStatusEnum.NOT_SENT == ssl_client_early_data.get_early_data_status() # When sending too much early data # It fails with pytest.raises(OpenSSLError, match='too much early data'): ssl_client_early_data.write_early_data( 'GET / HTTP/1.1\r\nData: {}\r\n\r\n'.format('*' * max_early).encode('ascii') ) ssl_client_early_data.shutdown()
def test_tls_1_3_write_early_data_does_not_finish_handshake(self): # Given a server that supports TLS 1.3 and early data with ModernOpenSslServer(max_early_data=512) as server: # That has a previous TLS 1.3 session with the server session = self._create_tls_1_3_session(server.hostname, server.port) assert session # And the server accepts early data max_early = session.get_max_early_data() assert max_early > 0 # When creating a new connection sock_early_data = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock_early_data.settimeout(5) sock_early_data.connect((server.hostname, server.port)) ssl_client_early_data = SslClient( ssl_version=OpenSslVersionEnum.TLSV1_3, underlying_socket=sock_early_data, ssl_verify=OpenSslVerifyEnum.NONE, ) # That re-uses the previous TLS 1.3 session ssl_client_early_data.set_session(session) assert OpenSslEarlyDataStatusEnum.NOT_SENT == ssl_client_early_data.get_early_data_status( ) # When sending early data ssl_client_early_data.write_early_data(b"EARLY DATA") # It succeeds assert not ssl_client_early_data.is_handshake_completed() assert OpenSslEarlyDataStatusEnum.REJECTED == ssl_client_early_data.get_early_data_status( ) # And after completing the handshake, the early data was accepted ssl_client_early_data.do_handshake() assert OpenSslEarlyDataStatusEnum.ACCEPTED == ssl_client_early_data.get_early_data_status( ) ssl_client_early_data.shutdown()
def test_tls_1_3_write_early_data_does_not_finish_handshake(self): # Given a server that supports TLS 1.3 and early data with ModernOpenSslServer(max_early_data=512) as server: # That has a previous TLS 1.3 session with the server session = self._create_tls_1_3_session(server.hostname, server.port) assert session # And the server accepts early data max_early = session.get_max_early_data() assert max_early > 0 # When creating a new connection sock_early_data = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock_early_data.settimeout(5) sock_early_data.connect((server.hostname, server.port)) ssl_client_early_data = SslClient( ssl_version=OpenSslVersionEnum.TLSV1_3, underlying_socket=sock_early_data, ssl_verify=OpenSslVerifyEnum.NONE ) # That re-uses the previous TLS 1.3 session ssl_client_early_data.set_session(session) assert OpenSslEarlyDataStatusEnum.NOT_SENT == ssl_client_early_data.get_early_data_status() # When sending early data ssl_client_early_data.write_early_data(b'EARLY DATA') # It succeeds assert not ssl_client_early_data.is_handshake_completed() assert OpenSslEarlyDataStatusEnum.REJECTED == ssl_client_early_data.get_early_data_status() # And after completing the handshake, the early data was accepted ssl_client_early_data.do_handshake() assert OpenSslEarlyDataStatusEnum.ACCEPTED == ssl_client_early_data.get_early_data_status() ssl_client_early_data.shutdown()
def test_tls_1_3_write_early_data_fail_when_trying_to_send_more_than_max_early_data( self): # Given a server that supports TLS 1.3 with ModernOpenSslServer(max_early_data=1) as server: # That has a previous TLS 1.3 session with the server session = self._create_tls_1_3_session(server.hostname, server.port) self.assertTrue(session) # And the server only accepts 1 byte of early data max_early = session.get_max_early_data() self.assertEqual(1, max_early) # When creating a new connection with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock_early_data: sock_early_data.settimeout(5) sock_early_data.connect((server.hostname, server.port)) ssl_client_early_data = SslClient( ssl_version=OpenSslVersionEnum.TLSV1_3, underlying_socket=sock_early_data, ssl_verify=OpenSslVerifyEnum.NONE) # That re-uses the previous TLS 1.3 session ssl_client_early_data.set_session(session) self.assertEqual(OpenSslEarlyDataStatusEnum.NOT_SENT, ssl_client_early_data.get_early_data_status()) # When sending too much early data # It fails self.assertRaisesRegex( OpenSSLError, 'too much early data', ssl_client_early_data.write_early_data, 'GET / HTTP/1.1\r\nData: {}\r\n\r\n'.format('*' * max_early))
class EarlyDataClient(): def __init__(self, **kw): self.socket = None self.session = None self.client = None self.dest = kw.get('dest', 'localhost') self.port = kw.get('port', 443) self.socket_timeout = kw.get('socket_timeout', 5) self.regular_data = kw.get('regular_data', b'XXX-REGULAR-DATA-XXX') self.early_data = kw.get('early_data', b'XXX-EARLY-DATA-XXX') self.read_size = kw.get('read_size', 2048) def _init(self, dest='localhost', port=443, timeout=5): self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.settimeout(timeout) self.socket.connect((dest, port)) self.client = SslClient(ssl_version=OpenSslVersionEnum.TLSV1_3, underlying_socket=self.socket, ssl_verify_locations=u'mozilla.pem') def _finish_handshake(self): if not self.client.is_handshake_completed(): self.client.do_handshake() print('\tCipher suite:', self.client.get_current_cipher_name()) def _close(self): self.client.shutdown() self.socket.close() print('\n') def _write_read_close(self, data_to_send=b'XXX-REGULAR-DATA-XXX', read_size=2048): try: self.client.write(data_to_send) self.client.read(2048) self.session = self.client.get_session() except socket.timeout as e: print('\n\tSocket was timed out. Closing...') finally: self._close() def _send_early_data(self, early_data_to_send=b'XXX-EARLY-DATA-XXX'): self.client.set_session(self.session) self.client.write_early_data(early_data_to_send) self._finish_handshake() print('\t', self.client.get_early_data_status()) self._close() def test_early(self, early_data_to_send=b'XXX-EARLY-DATA-XXX'): print('First Session:') self._init(dest=self.dest, port=self.port) self._finish_handshake() self._write_read_close(data_to_send=self.regular_data) if self.session: print('Reused Session:') self._init(dest=self.dest, port=self.port) if self.session.get_max_early_data() > 0: self._send_early_data() else: print('\n\tServer does not support Early-Data. Closing...') self._close else: print('\nPrevious session failed, can`t send early data. Closing...') print('='*80, '\n')