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