xref: /unit/test/test_tls_tickets.py (revision 2073:bc6ad31ce286)
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