Mercurial > hg > nginx-tests
comparison ssl_sni_sessions.t @ 751:f17f83b3d8c9
Tests: session resumption with SNI.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 23 Oct 2015 23:00:09 +0300 |
parents | |
children | 80e17d44088c |
comparison
equal
deleted
inserted
replaced
750:71dfce15bbba | 751:f17f83b3d8c9 |
---|---|
1 #!/usr/bin/perl | |
2 | |
3 # (C) Maxim Dounin | |
4 | |
5 # Tests for SSL session resumption with SNI. | |
6 | |
7 ############################################################################### | |
8 | |
9 use warnings; | |
10 use strict; | |
11 | |
12 use Test::More; | |
13 | |
14 BEGIN { use FindBin; chdir($FindBin::Bin); } | |
15 | |
16 use lib 'lib'; | |
17 use Test::Nginx; | |
18 | |
19 ############################################################################### | |
20 | |
21 select STDERR; $| = 1; | |
22 select STDOUT; $| = 1; | |
23 | |
24 my $t = Test::Nginx->new()->has(qw/http http_ssl sni rewrite/) | |
25 ->has_daemon('openssl') | |
26 ->write_file_expand('nginx.conf', <<'EOF'); | |
27 | |
28 %%TEST_GLOBALS%% | |
29 | |
30 daemon off; | |
31 | |
32 events { | |
33 } | |
34 | |
35 http { | |
36 %%TEST_GLOBALS_HTTP%% | |
37 | |
38 ssl_certificate_key localhost.key; | |
39 ssl_certificate localhost.crt; | |
40 | |
41 server { | |
42 listen 127.0.0.1:8443 ssl; | |
43 server_name default; | |
44 | |
45 ssl_session_tickets off; | |
46 ssl_session_cache shared:cache1:1m; | |
47 | |
48 location / { | |
49 return 200 $ssl_server_name:$ssl_session_reused; | |
50 } | |
51 } | |
52 | |
53 server { | |
54 listen 127.0.0.1:8443; | |
55 server_name nocache; | |
56 | |
57 ssl_session_tickets off; | |
58 ssl_session_cache shared:cache2:1m; | |
59 | |
60 location / { | |
61 return 200 $ssl_server_name:$ssl_session_reused; | |
62 } | |
63 } | |
64 | |
65 server { | |
66 listen 127.0.0.1:8444 ssl; | |
67 server_name default; | |
68 | |
69 ssl_session_ticket_key ticket1.key; | |
70 | |
71 location / { | |
72 return 200 $ssl_server_name:$ssl_session_reused; | |
73 } | |
74 } | |
75 | |
76 server { | |
77 listen 127.0.0.1:8444; | |
78 server_name tickets; | |
79 | |
80 ssl_session_ticket_key ticket2.key; | |
81 | |
82 location / { | |
83 return 200 $ssl_server_name:$ssl_session_reused; | |
84 } | |
85 } | |
86 } | |
87 | |
88 EOF | |
89 | |
90 eval { require IO::Socket::SSL; die if $IO::Socket::SSL::VERSION < 1.56; }; | |
91 plan(skip_all => 'IO::Socket::SSL version >= 1.56 required') if $@; | |
92 | |
93 eval { | |
94 if (IO::Socket::SSL->can('can_client_sni')) { | |
95 IO::Socket::SSL->can_client_sni() or die; | |
96 } | |
97 }; | |
98 plan(skip_all => 'IO::Socket::SSL with OpenSSL SNI support required') if $@; | |
99 | |
100 eval { | |
101 my $ctx = Net::SSLeay::CTX_new() or die; | |
102 my $ssl = Net::SSLeay::new($ctx) or die; | |
103 Net::SSLeay::set_tlsext_host_name($ssl, 'example.org') == 1 or die; | |
104 }; | |
105 plan(skip_all => 'Net::SSLeay with OpenSSL SNI support required') if $@; | |
106 | |
107 $t->plan(6); | |
108 | |
109 $t->write_file('openssl.conf', <<EOF); | |
110 [ req ] | |
111 default_bits = 2048 | |
112 encrypt_key = no | |
113 distinguished_name = req_distinguished_name | |
114 [ req_distinguished_name ] | |
115 EOF | |
116 | |
117 my $d = $t->testdir(); | |
118 | |
119 foreach my $name ('localhost') { | |
120 system('openssl req -x509 -new ' | |
121 . "-config '$d/openssl.conf' -subj '/CN=$name/' " | |
122 . "-out '$d/$name.crt' -keyout '$d/$name.key' " | |
123 . ">>$d/openssl.out 2>&1") == 0 | |
124 or die "Can't create certificate for $name: $!\n"; | |
125 } | |
126 | |
127 $t->write_file('ticket1.key', '1' x 48); | |
128 $t->write_file('ticket2.key', '2' x 48); | |
129 | |
130 $t->run(); | |
131 | |
132 ############################################################################### | |
133 | |
134 my $ctx = IO::Socket::SSL::SSL_Context->new( | |
135 SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE(), | |
136 SSL_session_cache_size => 100 | |
137 ); | |
138 | |
139 # check that everything works fine with default server | |
140 | |
141 like(get('default', 8443, $ctx), qr!default:\.!, 'default server'); | |
142 like(get('default', 8443, $ctx), qr!default:r!, 'default server reused'); | |
143 | |
144 TODO: { | |
145 local $TODO = 'not yet' unless $t->has_version('1.9.6'); | |
146 | |
147 # check that sessions are still properly saved and restored | |
148 # when using an SNI-based virtual server with different session cache; | |
149 # as session resumption happens before SNI, only default server | |
150 # settings are expected to matter | |
151 | |
152 # this didn't work before nginx 1.9.6 (and caused segfaults if no session | |
153 # cache was configured the SNI-based virtual server), because OpenSSL, when | |
154 # creating new sessions, uses callbacks from the default server context, but | |
155 # provides access to the SNI-selected server context only (ticket #235) | |
156 | |
157 like(get('nocache', 8443, $ctx), qr!nocache:\.!, 'without cache'); | |
158 like(get('nocache', 8443, $ctx), qr!nocache:r!, 'without cache reused'); | |
159 | |
160 # make sure tickets can be used if an SNI-based virtual server | |
161 # uses a different set of session ticket keys explicitly set | |
162 | |
163 like(get('tickets', 8444, $ctx), qr!tickets:\.!, 'tickets'); | |
164 like(get('tickets', 8444, $ctx), qr!tickets:r!, 'tickets reused'); | |
165 | |
166 } | |
167 | |
168 ############################################################################### | |
169 | |
170 sub get_ssl_socket { | |
171 my ($host, $port, $ctx) = @_; | |
172 my $s; | |
173 | |
174 eval { | |
175 local $SIG{ALRM} = sub { die "timeout\n" }; | |
176 local $SIG{PIPE} = sub { die "sigpipe\n" }; | |
177 alarm(2); | |
178 $s = IO::Socket::SSL->new( | |
179 Proto => 'tcp', | |
180 PeerAddr => '127.0.0.1', | |
181 PeerPort => $port, | |
182 SSL_hostname => $host, | |
183 SSL_session_key => "$host:$port", | |
184 SSL_reuse_ctx => $ctx, | |
185 SSL_error_trap => sub { die $_[1] } | |
186 ); | |
187 alarm(0); | |
188 }; | |
189 alarm(0); | |
190 | |
191 if ($@) { | |
192 log_in("died: $@"); | |
193 return undef; | |
194 } | |
195 | |
196 return $s; | |
197 } | |
198 | |
199 sub get { | |
200 my ($host, $port, $ctx) = @_; | |
201 | |
202 return http(<<EOF, socket => get_ssl_socket($host, $port, $ctx)); | |
203 GET / HTTP/1.0 | |
204 Host: $host | |
205 | |
206 EOF | |
207 } | |
208 | |
209 ############################################################################### |