comparison ssl.t @ 1829:a78c32419f02

Tests: separate SSL session reuse tests. Instead of being mixed with generic SSL tests, session reuse variants are now tested in a separate file. In the generic SSL tests only basic session reuse is now tested, notably with session tickets enabled and a shared SSL session cache. This should make it possible to reuse sessions in all cases (except when it's not supported, such as with LibreSSL with TLSv1.3). Note that session reuse with tickets implies that $ssl_session_id is selected by the client and therefore is not available on the initial connection. Relevant test is modified to handle this. Further, BoringSSL does not use legacy session ID with TLSv1.3 even if it is sent by the client. In contrast, OpenSSL always generates an unique legacy session id, so it is available with TLSv1.3 even if session resumption does not work (such as with old Net::SSLeay and IO::Socket::SSL modules).
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 23 Mar 2023 19:49:47 +0300
parents 84b6bb8d74e5
children 8dec885fa3da
comparison
equal deleted inserted replaced
1828:835630547d35 1829:a78c32419f02
29 plan(skip_all => 'IO::Socket::SSL not installed') if $@; 29 plan(skip_all => 'IO::Socket::SSL not installed') if $@;
30 eval { IO::Socket::SSL::SSL_VERIFY_NONE(); }; 30 eval { IO::Socket::SSL::SSL_VERIFY_NONE(); };
31 plan(skip_all => 'IO::Socket::SSL too old') if $@; 31 plan(skip_all => 'IO::Socket::SSL too old') if $@;
32 32
33 my $t = Test::Nginx->new()->has(qw/http http_ssl rewrite proxy/) 33 my $t = Test::Nginx->new()->has(qw/http http_ssl rewrite proxy/)
34 ->has_daemon('openssl')->plan(28); 34 ->has_daemon('openssl')->plan(21);
35 35
36 $t->write_file_expand('nginx.conf', <<'EOF'); 36 $t->write_file_expand('nginx.conf', <<'EOF');
37 37
38 %%TEST_GLOBALS%% 38 %%TEST_GLOBALS%%
39 39
45 http { 45 http {
46 %%TEST_GLOBALS_HTTP%% 46 %%TEST_GLOBALS_HTTP%%
47 47
48 ssl_certificate_key localhost.key; 48 ssl_certificate_key localhost.key;
49 ssl_certificate localhost.crt; 49 ssl_certificate localhost.crt;
50 ssl_session_tickets off;
51 50
52 log_format ssl $ssl_protocol; 51 log_format ssl $ssl_protocol;
53 52
54 server { 53 server {
55 listen 127.0.0.1:8085 ssl; 54 listen 127.0.0.1:8085 ssl;
57 server_name localhost; 56 server_name localhost;
58 57
59 ssl_certificate_key inner.key; 58 ssl_certificate_key inner.key;
60 ssl_certificate inner.crt; 59 ssl_certificate inner.crt;
61 ssl_session_cache shared:SSL:1m; 60 ssl_session_cache shared:SSL:1m;
61 ssl_session_tickets on;
62 ssl_verify_client optional_no_ca; 62 ssl_verify_client optional_no_ca;
63 63
64 keepalive_requests 1000; 64 keepalive_requests 1000;
65 65
66 location / { 66 location / {
98 access_log %%TESTDIR%%/ssl.log ssl; 98 access_log %%TESTDIR%%/ssl.log ssl;
99 } 99 }
100 } 100 }
101 101
102 server { 102 server {
103 listen 127.0.0.1:8081;
104 server_name localhost;
105
106 # Special case for enabled "ssl" directive.
107
108 ssl on;
109 ssl_session_cache builtin;
110
111 location / {
112 return 200 "body $ssl_session_reused";
113 }
114 }
115
116 server {
117 listen 127.0.0.1:8082 ssl;
118 server_name localhost;
119
120 ssl_session_cache builtin:1000;
121
122 location / {
123 return 200 "body $ssl_session_reused";
124 }
125 }
126
127 server {
128 listen 127.0.0.1:8083 ssl;
129 server_name localhost;
130
131 ssl_session_cache none;
132
133 location / {
134 return 200 "body $ssl_session_reused";
135 }
136 }
137
138 server {
139 listen 127.0.0.1:8084 ssl;
140 server_name localhost;
141
142 ssl_session_cache off;
143
144 location / {
145 return 200 "body $ssl_session_reused";
146 }
147 }
148
149 server {
150 listen 127.0.0.1:8086 ssl; 103 listen 127.0.0.1:8086 ssl;
151 server_name localhost; 104 server_name localhost;
152 105
153 ssl_session_cache shared:SSL:1m; 106 ssl_session_cache shared:SSL:1m;
107 ssl_session_tickets on;
154 ssl_session_timeout 1; 108 ssl_session_timeout 1;
155 109
156 location / { 110 location / {
157 return 200 "body $ssl_session_reused"; 111 return 200 "body $ssl_session_reused";
158 } 112 }
214 . "-out $d/$name.crt -keyout $d/$name.key " 168 . "-out $d/$name.crt -keyout $d/$name.key "
215 . ">>$d/openssl.out 2>&1") == 0 169 . ">>$d/openssl.out 2>&1") == 0
216 or die "Can't create certificate for $name: $!\n"; 170 or die "Can't create certificate for $name: $!\n";
217 } 171 }
218 172
219 # suppress deprecation warning
220
221 open OLDERR, ">&", \*STDERR; close STDERR;
222 $t->run(); 173 $t->run();
223 open STDERR, ">&", \*OLDERR; 174
224 175 ###############################################################################
225 ############################################################################### 176
226 177 # ssl session reuse
227 my $ctx; 178
228 179 my $ctx = get_ssl_context();
229 SKIP: { 180
230 skip 'no TLS 1.3 sessions', 6 if get('/protocol', 8085) =~ /TLSv1.3/ 181 like(get('/', 8085, $ctx), qr/^body \.$/m, 'session');
231 && ($Net::SSLeay::VERSION < 1.88 || $IO::Socket::SSL::VERSION < 2.061); 182
232 183 TODO: {
233 $ctx = get_ssl_context(); 184 local $TODO = 'no TLSv1.3 sessions, old Net::SSLeay'
234 185 if $Net::SSLeay::VERSION < 1.88 && test_tls13();
235 like(get('/', 8085, $ctx), qr/^body \.$/m, 'cache shared'); 186 local $TODO = 'no TLSv1.3 sessions, old IO::Socket::SSL'
236 like(get('/', 8085, $ctx), qr/^body r$/m, 'cache shared reused'); 187 if $IO::Socket::SSL::VERSION < 2.061 && test_tls13();
237 188
238 $ctx = get_ssl_context(); 189 like(get('/', 8085, $ctx), qr/^body r$/m, 'session reused');
239 190
240 like(get('/', 8081, $ctx), qr/^body \.$/m, 'cache builtin'); 191 }
241 like(get('/', 8081, $ctx), qr/^body r$/m, 'cache builtin reused');
242
243 $ctx = get_ssl_context();
244
245 like(get('/', 8082, $ctx), qr/^body \.$/m, 'cache builtin size');
246 like(get('/', 8082, $ctx), qr/^body r$/m, 'cache builtin size reused');
247
248 }
249
250 $ctx = get_ssl_context();
251
252 like(get('/', 8083, $ctx), qr/^body \.$/m, 'cache none');
253 like(get('/', 8083, $ctx), qr/^body \.$/m, 'cache none not reused');
254
255 $ctx = get_ssl_context();
256
257 like(get('/', 8084, $ctx), qr/^body \.$/m, 'cache off');
258 like(get('/', 8084, $ctx), qr/^body \.$/m, 'cache off not reused');
259 192
260 # ssl certificate inheritance 193 # ssl certificate inheritance
261 194
262 my $s = get_ssl_socket(8081); 195 my $s = get_ssl_socket(8086);
263 like($s->dump_peer_certificate(), qr/CN=localhost/, 'CN'); 196 like($s->dump_peer_certificate(), qr/CN=localhost/, 'CN');
264
265 $s->close();
266 197
267 $s = get_ssl_socket(8085); 198 $s = get_ssl_socket(8085);
268 like($s->dump_peer_certificate(), qr/CN=inner/, 'CN inner'); 199 like($s->dump_peer_certificate(), qr/CN=inner/, 'CN inner');
269 200
270 $s->close();
271
272 # session timeout 201 # session timeout
273 202
274 $ctx = get_ssl_context(); 203 $ctx = get_ssl_context();
275 204
276 get('/', 8086, $ctx); 205 get('/', 8086, $ctx);
278 207
279 like(get('/', 8086, $ctx), qr/^body \.$/m, 'session timeout'); 208 like(get('/', 8086, $ctx), qr/^body \.$/m, 'session timeout');
280 209
281 # embedded variables 210 # embedded variables
282 211
283 like(get('/id', 8085), qr/^body \w{64}$/m, 'session id'); 212 $ctx = get_ssl_context();
213 like(get('/id', 8085, $ctx), qr/^body (\w{64})?$/m, 'session id');
214 like(get('/id', 8085, $ctx), qr/^body \w{64}$/m, 'session id reused');
215
284 unlike(http_get('/id'), qr/body \w/, 'session id no ssl'); 216 unlike(http_get('/id'), qr/body \w/, 'session id no ssl');
217
285 like(get('/cipher', 8085), qr/^body [\w-]+$/m, 'cipher'); 218 like(get('/cipher', 8085), qr/^body [\w-]+$/m, 'cipher');
286 219
287 SKIP: { 220 SKIP: {
288 skip 'BoringSSL', 1 if $t->has_module('BoringSSL'); 221 skip 'BoringSSL', 1 if $t->has_module('BoringSSL');
289 222
331 'log ssl variable on lingering close'); 264 'log ssl variable on lingering close');
332 265
333 like(`grep -F '[crit]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no crit'); 266 like(`grep -F '[crit]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no crit');
334 267
335 ############################################################################### 268 ###############################################################################
269
270 sub test_tls13 {
271 return get('/protocol', 8085) =~ /TLSv1.3/;
272 }
336 273
337 sub get { 274 sub get {
338 my ($uri, $port, $ctx) = @_; 275 my ($uri, $port, $ctx) = @_;
339 my $s = get_ssl_socket($port, $ctx) or return; 276 my $s = get_ssl_socket($port, $ctx) or return;
340 my $r = http_get($uri, socket => $s); 277 my $r = http_get($uri, socket => $s);