xref: /unit/test/test_tls_session.py (revision 2005:28c7f6ff3832)
11981Szelenkov@nginx.comimport socket
21981Szelenkov@nginx.comimport time
31981Szelenkov@nginx.com
41981Szelenkov@nginx.comimport pytest
51985Szelenkov@nginx.com
61985Szelenkov@nginx.compytest.importorskip('OpenSSL.SSL')
71981Szelenkov@nginx.comfrom OpenSSL.SSL import (
81981Szelenkov@nginx.com    TLSv1_2_METHOD,
91981Szelenkov@nginx.com    SESS_CACHE_CLIENT,
101981Szelenkov@nginx.com    OP_NO_TICKET,
111981Szelenkov@nginx.com    Context,
121981Szelenkov@nginx.com    Connection,
131981Szelenkov@nginx.com    _lib,
141981Szelenkov@nginx.com)
151981Szelenkov@nginx.comfrom unit.applications.tls import TestApplicationTLS
161981Szelenkov@nginx.com
171981Szelenkov@nginx.com
181981Szelenkov@nginx.comclass TestTLSSession(TestApplicationTLS):
191981Szelenkov@nginx.com    prerequisites = {'modules': {'openssl': 'any'}}
201981Szelenkov@nginx.com
211981Szelenkov@nginx.com    @pytest.fixture(autouse=True)
221981Szelenkov@nginx.com    def setup_method_fixture(self, request):
231981Szelenkov@nginx.com        self.certificate()
241981Szelenkov@nginx.com
251981Szelenkov@nginx.com        assert 'success' in self.conf(
261981Szelenkov@nginx.com            {
271981Szelenkov@nginx.com                "listeners": {
281981Szelenkov@nginx.com                    "*:7080": {
291981Szelenkov@nginx.com                        "pass": "routes",
301981Szelenkov@nginx.com                        "tls": {"certificate": "default", "session": {}},
311981Szelenkov@nginx.com                    }
321981Szelenkov@nginx.com                },
331981Szelenkov@nginx.com                "routes": [{"action": {"return": 200}}],
341981Szelenkov@nginx.com                "applications": {},
351981Szelenkov@nginx.com            }
361981Szelenkov@nginx.com        ), 'load application configuration'
371981Szelenkov@nginx.com
381981Szelenkov@nginx.com    def add_session(self, cache_size=None, timeout=None):
391981Szelenkov@nginx.com        session = {}
401981Szelenkov@nginx.com
411981Szelenkov@nginx.com        if cache_size is not None:
421981Szelenkov@nginx.com            session['cache_size'] = cache_size
431981Szelenkov@nginx.com        if timeout is not None:
441981Szelenkov@nginx.com            session['timeout'] = timeout
451981Szelenkov@nginx.com
461981Szelenkov@nginx.com        return self.conf(session, 'listeners/*:7080/tls/session')
471981Szelenkov@nginx.com
481981Szelenkov@nginx.com    def connect(self, ctx=None, session=None):
491981Szelenkov@nginx.com        sock = socket.create_connection(('127.0.0.1', 7080))
501981Szelenkov@nginx.com
511981Szelenkov@nginx.com        if ctx is None:
521981Szelenkov@nginx.com            ctx = Context(TLSv1_2_METHOD)
531981Szelenkov@nginx.com            ctx.set_session_cache_mode(SESS_CACHE_CLIENT)
541981Szelenkov@nginx.com            ctx.set_options(OP_NO_TICKET)
551981Szelenkov@nginx.com
561981Szelenkov@nginx.com        client = Connection(ctx, sock)
571981Szelenkov@nginx.com        client.set_connect_state()
581981Szelenkov@nginx.com
591981Szelenkov@nginx.com        if session is not None:
601981Szelenkov@nginx.com            client.set_session(session)
611981Szelenkov@nginx.com
621981Szelenkov@nginx.com        client.do_handshake()
631981Szelenkov@nginx.com        client.shutdown()
641981Szelenkov@nginx.com
651981Szelenkov@nginx.com        return (
661981Szelenkov@nginx.com            client,
671981Szelenkov@nginx.com            client.get_session(),
681981Szelenkov@nginx.com            ctx,
691981Szelenkov@nginx.com            _lib.SSL_session_reused(client._ssl),
701981Szelenkov@nginx.com        )
711981Szelenkov@nginx.com
721981Szelenkov@nginx.com    def test_tls_session(self):
731981Szelenkov@nginx.com        client, sess, ctx, reused = self.connect()
741981Szelenkov@nginx.com        assert not reused, 'new connection'
751981Szelenkov@nginx.com
761981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
771981Szelenkov@nginx.com        assert not reused, 'no cache'
781981Szelenkov@nginx.com
79*2005Szelenkov@nginx.com        assert 'success' in self.add_session(cache_size=2)
801981Szelenkov@nginx.com
811981Szelenkov@nginx.com        client, sess, ctx, reused = self.connect()
821981Szelenkov@nginx.com        assert not reused, 'new connection cache'
831981Szelenkov@nginx.com
841981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
851981Szelenkov@nginx.com        assert reused, 'cache'
861981Szelenkov@nginx.com
871981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
881981Szelenkov@nginx.com        assert reused, 'cache 2'
891981Szelenkov@nginx.com
90*2005Szelenkov@nginx.com        # check that at least one session of four is not reused
911981Szelenkov@nginx.com
92*2005Szelenkov@nginx.com        clients = [self.connect() for _ in range(4)]
93*2005Szelenkov@nginx.com        assert True not in [c[-1] for c in clients], 'cache small all new'
941981Szelenkov@nginx.com
95*2005Szelenkov@nginx.com        clients_again = [self.connect(c[2], c[1]) for c in clients]
96*2005Szelenkov@nginx.com        assert False in [c[-1] for c in clients_again], 'cache small no reuse'
971981Szelenkov@nginx.com
98*2005Szelenkov@nginx.com        # all four sessions are reused
991981Szelenkov@nginx.com
100*2005Szelenkov@nginx.com        assert 'success' in self.add_session(cache_size=8)
1011981Szelenkov@nginx.com
102*2005Szelenkov@nginx.com        clients = [self.connect() for _ in range(4)]
103*2005Szelenkov@nginx.com        assert True not in [c[-1] for c in clients], 'cache big all new'
1041981Szelenkov@nginx.com
105*2005Szelenkov@nginx.com        clients_again = [self.connect(c[2], c[1]) for c in clients]
106*2005Szelenkov@nginx.com        assert False not in [c[-1] for c in clients_again], 'cache big reuse'
1071981Szelenkov@nginx.com
1081981Szelenkov@nginx.com    def test_tls_session_timeout(self):
109*2005Szelenkov@nginx.com        assert 'success' in self.add_session(cache_size=5, timeout=1)
1101981Szelenkov@nginx.com
1111981Szelenkov@nginx.com        client, sess, ctx, reused = self.connect()
1121981Szelenkov@nginx.com        assert not reused, 'new connection'
1131981Szelenkov@nginx.com
1141981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
1151981Szelenkov@nginx.com        assert reused, 'no timeout'
1161981Szelenkov@nginx.com
1171981Szelenkov@nginx.com        time.sleep(3)
1181981Szelenkov@nginx.com
1191981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
1201981Szelenkov@nginx.com        assert not reused, 'timeout'
1211981Szelenkov@nginx.com
1221981Szelenkov@nginx.com    def test_tls_session_invalid(self):
1231981Szelenkov@nginx.com        assert 'error' in self.add_session(cache_size=-1)
1241981Szelenkov@nginx.com        assert 'error' in self.add_session(cache_size={})
1251981Szelenkov@nginx.com        assert 'error' in self.add_session(timeout=-1)
1261981Szelenkov@nginx.com        assert 'error' in self.add_session(timeout={})
127