xref: /unit/test/test_tls_session.py (revision 1981)
1*1981Szelenkov@nginx.comimport socket
2*1981Szelenkov@nginx.comimport time
3*1981Szelenkov@nginx.com
4*1981Szelenkov@nginx.comimport pytest
5*1981Szelenkov@nginx.comfrom OpenSSL.SSL import (
6*1981Szelenkov@nginx.com    TLSv1_2_METHOD,
7*1981Szelenkov@nginx.com    SESS_CACHE_CLIENT,
8*1981Szelenkov@nginx.com    OP_NO_TICKET,
9*1981Szelenkov@nginx.com    Context,
10*1981Szelenkov@nginx.com    Connection,
11*1981Szelenkov@nginx.com    _lib,
12*1981Szelenkov@nginx.com)
13*1981Szelenkov@nginx.comfrom unit.applications.tls import TestApplicationTLS
14*1981Szelenkov@nginx.comfrom unit.option import option
15*1981Szelenkov@nginx.com
16*1981Szelenkov@nginx.com
17*1981Szelenkov@nginx.comclass TestTLSSession(TestApplicationTLS):
18*1981Szelenkov@nginx.com    prerequisites = {'modules': {'openssl': 'any'}}
19*1981Szelenkov@nginx.com
20*1981Szelenkov@nginx.com    @pytest.fixture(autouse=True)
21*1981Szelenkov@nginx.com    def setup_method_fixture(self, request):
22*1981Szelenkov@nginx.com        self.certificate()
23*1981Szelenkov@nginx.com
24*1981Szelenkov@nginx.com        assert 'success' in self.conf(
25*1981Szelenkov@nginx.com            {
26*1981Szelenkov@nginx.com                "listeners": {
27*1981Szelenkov@nginx.com                    "*:7080": {
28*1981Szelenkov@nginx.com                        "pass": "routes",
29*1981Szelenkov@nginx.com                        "tls": {"certificate": "default", "session": {}},
30*1981Szelenkov@nginx.com                    }
31*1981Szelenkov@nginx.com                },
32*1981Szelenkov@nginx.com                "routes": [{"action": {"return": 200}}],
33*1981Szelenkov@nginx.com                "applications": {},
34*1981Szelenkov@nginx.com            }
35*1981Szelenkov@nginx.com        ), 'load application configuration'
36*1981Szelenkov@nginx.com
37*1981Szelenkov@nginx.com    def add_session(self, cache_size=None, timeout=None):
38*1981Szelenkov@nginx.com        session = {}
39*1981Szelenkov@nginx.com
40*1981Szelenkov@nginx.com        if cache_size is not None:
41*1981Szelenkov@nginx.com            session['cache_size'] = cache_size
42*1981Szelenkov@nginx.com        if timeout is not None:
43*1981Szelenkov@nginx.com            session['timeout'] = timeout
44*1981Szelenkov@nginx.com
45*1981Szelenkov@nginx.com        return self.conf(session, 'listeners/*:7080/tls/session')
46*1981Szelenkov@nginx.com
47*1981Szelenkov@nginx.com    def connect(self, ctx=None, session=None):
48*1981Szelenkov@nginx.com        sock = socket.create_connection(('127.0.0.1', 7080))
49*1981Szelenkov@nginx.com
50*1981Szelenkov@nginx.com        if ctx is None:
51*1981Szelenkov@nginx.com            ctx = Context(TLSv1_2_METHOD)
52*1981Szelenkov@nginx.com            ctx.set_session_cache_mode(SESS_CACHE_CLIENT)
53*1981Szelenkov@nginx.com            ctx.set_options(OP_NO_TICKET)
54*1981Szelenkov@nginx.com
55*1981Szelenkov@nginx.com        client = Connection(ctx, sock)
56*1981Szelenkov@nginx.com        client.set_connect_state()
57*1981Szelenkov@nginx.com
58*1981Szelenkov@nginx.com        if session is not None:
59*1981Szelenkov@nginx.com            client.set_session(session)
60*1981Szelenkov@nginx.com
61*1981Szelenkov@nginx.com        client.do_handshake()
62*1981Szelenkov@nginx.com        client.shutdown()
63*1981Szelenkov@nginx.com
64*1981Szelenkov@nginx.com        return (
65*1981Szelenkov@nginx.com            client,
66*1981Szelenkov@nginx.com            client.get_session(),
67*1981Szelenkov@nginx.com            ctx,
68*1981Szelenkov@nginx.com            _lib.SSL_session_reused(client._ssl),
69*1981Szelenkov@nginx.com        )
70*1981Szelenkov@nginx.com
71*1981Szelenkov@nginx.com    def test_tls_session(self):
72*1981Szelenkov@nginx.com        client, sess, ctx, reused = self.connect()
73*1981Szelenkov@nginx.com        assert not reused, 'new connection'
74*1981Szelenkov@nginx.com
75*1981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
76*1981Szelenkov@nginx.com        assert not reused, 'no cache'
77*1981Szelenkov@nginx.com
78*1981Szelenkov@nginx.com        assert 'success' in self.add_session(cache_size=1)
79*1981Szelenkov@nginx.com
80*1981Szelenkov@nginx.com        client, sess, ctx, reused = self.connect()
81*1981Szelenkov@nginx.com        assert not reused, 'new connection cache'
82*1981Szelenkov@nginx.com
83*1981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
84*1981Szelenkov@nginx.com        assert reused, 'cache'
85*1981Szelenkov@nginx.com
86*1981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
87*1981Szelenkov@nginx.com        assert reused, 'cache 2'
88*1981Szelenkov@nginx.com
89*1981Szelenkov@nginx.com        # check that at least one session of two is not reused
90*1981Szelenkov@nginx.com
91*1981Szelenkov@nginx.com        client, sess, ctx, reused = self.connect()
92*1981Szelenkov@nginx.com        client2, sess2, ctx2, reused2 = self.connect()
93*1981Szelenkov@nginx.com        assert True not in [reused, reused2], 'new connection cache small'
94*1981Szelenkov@nginx.com
95*1981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
96*1981Szelenkov@nginx.com        client2, _, _, reused2 = self.connect(ctx2, sess2)
97*1981Szelenkov@nginx.com        assert False in [reused, reused2], 'cache small'
98*1981Szelenkov@nginx.com
99*1981Szelenkov@nginx.com        # both sessions are reused
100*1981Szelenkov@nginx.com
101*1981Szelenkov@nginx.com        assert 'success' in self.add_session(cache_size=2)
102*1981Szelenkov@nginx.com
103*1981Szelenkov@nginx.com        client, sess, ctx, reused = self.connect()
104*1981Szelenkov@nginx.com        client2, sess2, ctx2, reused2 = self.connect()
105*1981Szelenkov@nginx.com        assert True not in [reused, reused2], 'new connection cache big'
106*1981Szelenkov@nginx.com
107*1981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
108*1981Szelenkov@nginx.com        client2, _, _, reused2 = self.connect(ctx2, sess2)
109*1981Szelenkov@nginx.com        assert False not in [reused, reused2], 'cache big'
110*1981Szelenkov@nginx.com
111*1981Szelenkov@nginx.com    def test_tls_session_timeout(self):
112*1981Szelenkov@nginx.com        assert 'success' in self.add_session(cache_size=1, timeout=1)
113*1981Szelenkov@nginx.com
114*1981Szelenkov@nginx.com        client, sess, ctx, reused = self.connect()
115*1981Szelenkov@nginx.com        assert not reused, 'new connection'
116*1981Szelenkov@nginx.com
117*1981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
118*1981Szelenkov@nginx.com        assert reused, 'no timeout'
119*1981Szelenkov@nginx.com
120*1981Szelenkov@nginx.com        time.sleep(3)
121*1981Szelenkov@nginx.com
122*1981Szelenkov@nginx.com        client, _, _, reused = self.connect(ctx, sess)
123*1981Szelenkov@nginx.com        assert not reused, 'timeout'
124*1981Szelenkov@nginx.com
125*1981Szelenkov@nginx.com    def test_tls_session_invalid(self):
126*1981Szelenkov@nginx.com        assert 'error' in self.add_session(cache_size=-1)
127*1981Szelenkov@nginx.com        assert 'error' in self.add_session(cache_size={})
128*1981Szelenkov@nginx.com        assert 'error' in self.add_session(timeout=-1)
129*1981Szelenkov@nginx.com        assert 'error' in self.add_session(timeout={})
130