11982Szelenkov@nginx.comimport socket 21982Szelenkov@nginx.com 31982Szelenkov@nginx.comimport pytest 41985Szelenkov@nginx.com 51985Szelenkov@nginx.compytest.importorskip('OpenSSL.SSL') 61982Szelenkov@nginx.comfrom OpenSSL.SSL import ( 71982Szelenkov@nginx.com TLSv1_2_METHOD, 81982Szelenkov@nginx.com Context, 91982Szelenkov@nginx.com Connection, 101982Szelenkov@nginx.com Session, 111982Szelenkov@nginx.com _lib, 121982Szelenkov@nginx.com) 131982Szelenkov@nginx.comfrom unit.applications.tls import TestApplicationTLS 141982Szelenkov@nginx.com 151982Szelenkov@nginx.com 161982Szelenkov@nginx.comclass TestTLSTicket(TestApplicationTLS): 171982Szelenkov@nginx.com prerequisites = {'modules': {'openssl': 'any'}} 181982Szelenkov@nginx.com 191982Szelenkov@nginx.com ticket = 'U1oDTh11mMxODuw12gS0EXX1E/PkZG13cJNQ6m5+6BGlfPTjNlIEw7PSVU3X1gTE' 20*2073Szelenkov@nginx.com ticket2 = '5AV0DSYIYbZWZQB7fCnTHZmMxtotb/aXjam+n2XS79lTvX3Tq9xGqpC8XKNEF2lt' 211982Szelenkov@nginx.com ticket80 = '6Pfil8lv/k8zf8MndPpfXaO5EAV6dhME6zs6CfUyq2yziynQwSywtKQMqHGnJ2HR\ 221982Szelenkov@nginx.com49TZXi/Y4/8RSIO7QPsU51/HLR1gWIMhVM2m9yh93Bw=' 231982Szelenkov@nginx.com 241982Szelenkov@nginx.com @pytest.fixture(autouse=True) 251982Szelenkov@nginx.com def setup_method_fixture(self, request): 261982Szelenkov@nginx.com self.certificate() 271982Szelenkov@nginx.com 281982Szelenkov@nginx.com listener_conf = { 291982Szelenkov@nginx.com "pass": "routes", 301982Szelenkov@nginx.com "tls": { 311982Szelenkov@nginx.com "certificate": "default", 321982Szelenkov@nginx.com "session": {"cache_size": 0, "tickets": True}, 331982Szelenkov@nginx.com }, 341982Szelenkov@nginx.com } 351982Szelenkov@nginx.com 361982Szelenkov@nginx.com assert 'success' in self.conf( 371982Szelenkov@nginx.com { 381982Szelenkov@nginx.com "listeners": { 391982Szelenkov@nginx.com "*:7080": listener_conf, 401982Szelenkov@nginx.com "*:7081": listener_conf, 411982Szelenkov@nginx.com "*:7082": listener_conf, 421982Szelenkov@nginx.com }, 431982Szelenkov@nginx.com "routes": [{"action": {"return": 200}}], 441982Szelenkov@nginx.com "applications": {}, 451982Szelenkov@nginx.com } 461982Szelenkov@nginx.com ), 'load application configuration' 471982Szelenkov@nginx.com 481982Szelenkov@nginx.com def set_tickets(self, tickets=True, port=7080): 491982Szelenkov@nginx.com assert 'success' in self.conf( 501982Szelenkov@nginx.com {"cache_size": 0, "tickets": tickets}, 511982Szelenkov@nginx.com 'listeners/*:' + str(port) + '/tls/session', 521982Szelenkov@nginx.com ) 531982Szelenkov@nginx.com 541982Szelenkov@nginx.com def connect(self, ctx=None, session=None, port=7080): 551982Szelenkov@nginx.com sock = socket.create_connection(('127.0.0.1', port)) 561982Szelenkov@nginx.com 571982Szelenkov@nginx.com if ctx is None: 581982Szelenkov@nginx.com ctx = Context(TLSv1_2_METHOD) 591982Szelenkov@nginx.com 601982Szelenkov@nginx.com client = Connection(ctx, sock) 611982Szelenkov@nginx.com client.set_connect_state() 621982Szelenkov@nginx.com 631982Szelenkov@nginx.com if session is not None: 641982Szelenkov@nginx.com client.set_session(session) 651982Szelenkov@nginx.com 661982Szelenkov@nginx.com client.do_handshake() 671982Szelenkov@nginx.com client.shutdown() 681982Szelenkov@nginx.com 691982Szelenkov@nginx.com return ( 701982Szelenkov@nginx.com client.get_session(), 711982Szelenkov@nginx.com ctx, 721982Szelenkov@nginx.com _lib.SSL_session_reused(client._ssl), 731982Szelenkov@nginx.com ) 741982Szelenkov@nginx.com 751982Szelenkov@nginx.com def has_ticket(self, sess): 761982Szelenkov@nginx.com return _lib.SSL_SESSION_has_ticket(sess._session) 771982Szelenkov@nginx.com 781982Szelenkov@nginx.com @pytest.mark.skipif( 791982Szelenkov@nginx.com not hasattr(_lib, 'SSL_SESSION_has_ticket'), 801982Szelenkov@nginx.com reason='ticket check is not supported', 811982Szelenkov@nginx.com ) 821982Szelenkov@nginx.com def test_tls_ticket(self): 831982Szelenkov@nginx.com sess, ctx, reused = self.connect() 841982Szelenkov@nginx.com assert self.has_ticket(sess), 'tickets True' 851982Szelenkov@nginx.com assert not reused, 'tickets True not reused' 861982Szelenkov@nginx.com 871982Szelenkov@nginx.com sess, ctx, reused = self.connect(ctx, sess) 881982Szelenkov@nginx.com assert self.has_ticket(sess), 'tickets True reconnect' 891982Szelenkov@nginx.com assert reused, 'tickets True reused' 901982Szelenkov@nginx.com 911982Szelenkov@nginx.com self.set_tickets(tickets=False) 921982Szelenkov@nginx.com 931982Szelenkov@nginx.com sess, _, _ = self.connect() 941982Szelenkov@nginx.com assert not self.has_ticket(sess), 'tickets False' 951982Szelenkov@nginx.com 961982Szelenkov@nginx.com assert 'success' in self.conf_delete( 971982Szelenkov@nginx.com 'listeners/*:7080/tls/session/tickets' 981982Szelenkov@nginx.com ), 'tickets default configure' 991982Szelenkov@nginx.com 1001982Szelenkov@nginx.com sess, _, _ = self.connect() 1011982Szelenkov@nginx.com assert not self.has_ticket(sess), 'tickets default (false)' 1021982Szelenkov@nginx.com 1031982Szelenkov@nginx.com @pytest.mark.skipif( 1041982Szelenkov@nginx.com not hasattr(_lib, 'SSL_SESSION_has_ticket'), 1051982Szelenkov@nginx.com reason='ticket check is not supported', 1061982Szelenkov@nginx.com ) 1071982Szelenkov@nginx.com def test_tls_ticket_string(self): 1081982Szelenkov@nginx.com self.set_tickets(self.ticket) 1091982Szelenkov@nginx.com sess, ctx, _ = self.connect() 1101982Szelenkov@nginx.com assert self.has_ticket(sess), 'tickets string' 1111982Szelenkov@nginx.com 1121982Szelenkov@nginx.com sess2, _, reused = self.connect(ctx, sess) 1131982Szelenkov@nginx.com assert self.has_ticket(sess2), 'tickets string reconnect' 1141982Szelenkov@nginx.com assert reused, 'tickets string reused' 1151982Szelenkov@nginx.com 1161982Szelenkov@nginx.com sess2, _, reused = self.connect(ctx, sess, port=7081) 1171982Szelenkov@nginx.com assert self.has_ticket(sess2), 'connect True' 1181982Szelenkov@nginx.com assert not reused, 'connect True not reused' 1191982Szelenkov@nginx.com 1201982Szelenkov@nginx.com self.set_tickets(self.ticket2, port=7081) 1211982Szelenkov@nginx.com 1221982Szelenkov@nginx.com sess2, _, reused = self.connect(ctx, sess, port=7081) 1231982Szelenkov@nginx.com assert self.has_ticket(sess2), 'wrong ticket' 1241982Szelenkov@nginx.com assert not reused, 'wrong ticket not reused' 1251982Szelenkov@nginx.com 1261982Szelenkov@nginx.com self.set_tickets(self.ticket80) 1271982Szelenkov@nginx.com 1281982Szelenkov@nginx.com sess, ctx, _ = self.connect() 1291982Szelenkov@nginx.com assert self.has_ticket(sess), 'tickets string 80' 1301982Szelenkov@nginx.com 1311982Szelenkov@nginx.com sess2, _, reused = self.connect(ctx, sess) 1321982Szelenkov@nginx.com assert self.has_ticket(sess2), 'tickets string 80 reconnect' 1331982Szelenkov@nginx.com assert reused, 'tickets string 80 reused' 1341982Szelenkov@nginx.com 1351982Szelenkov@nginx.com sess2, _, reused = self.connect(ctx, sess, port=7081) 1361982Szelenkov@nginx.com assert self.has_ticket(sess2), 'wrong ticket 80' 1371982Szelenkov@nginx.com assert not reused, 'wrong ticket 80 not reused' 1381982Szelenkov@nginx.com 1391982Szelenkov@nginx.com @pytest.mark.skipif( 1401982Szelenkov@nginx.com not hasattr(_lib, 'SSL_SESSION_has_ticket'), 1411982Szelenkov@nginx.com reason='ticket check is not supported', 1421982Szelenkov@nginx.com ) 1431982Szelenkov@nginx.com def test_tls_ticket_array(self): 1441982Szelenkov@nginx.com self.set_tickets([]) 1451982Szelenkov@nginx.com 1461982Szelenkov@nginx.com sess, ctx, _ = self.connect() 1471982Szelenkov@nginx.com assert not self.has_ticket(sess), 'tickets array empty' 1481982Szelenkov@nginx.com 1491982Szelenkov@nginx.com self.set_tickets([self.ticket, self.ticket2]) 1501982Szelenkov@nginx.com self.set_tickets(self.ticket, port=7081) 1511982Szelenkov@nginx.com self.set_tickets(self.ticket2, port=7082) 1521982Szelenkov@nginx.com 1531982Szelenkov@nginx.com sess, ctx, _ = self.connect() 1541982Szelenkov@nginx.com _, _, reused = self.connect(ctx, sess, port=7081) 1551982Szelenkov@nginx.com assert not reused, 'not last ticket' 1561982Szelenkov@nginx.com _, _, reused = self.connect(ctx, sess, port=7082) 1571982Szelenkov@nginx.com assert reused, 'last ticket' 1581982Szelenkov@nginx.com 1591982Szelenkov@nginx.com sess, ctx, _ = self.connect(port=7081) 1601982Szelenkov@nginx.com _, _, reused = self.connect(ctx, sess) 1611982Szelenkov@nginx.com assert reused, 'first ticket' 1621982Szelenkov@nginx.com 1631982Szelenkov@nginx.com sess, ctx, _ = self.connect(port=7082) 1641982Szelenkov@nginx.com _, _, reused = self.connect(ctx, sess) 1651982Szelenkov@nginx.com assert reused, 'second ticket' 1661982Szelenkov@nginx.com 1671982Szelenkov@nginx.com assert 'success' in self.conf_delete( 1681982Szelenkov@nginx.com 'listeners/*:7080/tls/session/tickets/0' 1691982Szelenkov@nginx.com ), 'removed first ticket' 1701982Szelenkov@nginx.com assert 'success' in self.conf_post( 1711982Szelenkov@nginx.com '"' + self.ticket + '"', 'listeners/*:7080/tls/session/tickets' 1721982Szelenkov@nginx.com ), 'add new ticket to the end of array' 1731982Szelenkov@nginx.com 1741982Szelenkov@nginx.com sess, ctx, _ = self.connect() 1751982Szelenkov@nginx.com _, _, reused = self.connect(ctx, sess, port=7082) 1761982Szelenkov@nginx.com assert not reused, 'not last ticket 2' 1771982Szelenkov@nginx.com _, _, reused = self.connect(ctx, sess, port=7081) 1781982Szelenkov@nginx.com assert reused, 'last ticket 2' 1791982Szelenkov@nginx.com 1801982Szelenkov@nginx.com def test_tls_ticket_invalid(self): 1811982Szelenkov@nginx.com def check_tickets(tickets): 1821982Szelenkov@nginx.com assert 'error' in self.conf( 183*2073Szelenkov@nginx.com {"tickets": tickets}, 184*2073Szelenkov@nginx.com 'listeners/*:7080/tls/session', 1851982Szelenkov@nginx.com ) 1861982Szelenkov@nginx.com 1871982Szelenkov@nginx.com check_tickets({}) 1881982Szelenkov@nginx.com check_tickets('!?&^' * 16) 1891982Szelenkov@nginx.com check_tickets(self.ticket[:-2] + '!' + self.ticket[3:]) 1901982Szelenkov@nginx.com check_tickets(self.ticket[:-1]) 1911982Szelenkov@nginx.com check_tickets(self.ticket + 'b') 1921982Szelenkov@nginx.com check_tickets(self.ticket + 'blah') 1931982Szelenkov@nginx.com check_tickets([True, self.ticket, self.ticket2]) 1941982Szelenkov@nginx.com check_tickets([self.ticket, 'blah', self.ticket2]) 1951982Szelenkov@nginx.com check_tickets([self.ticket, self.ticket2, []]) 196