Mercurial > hg > nginx-tests
comparison ssl_ocsp.t @ 1847:a9704b9ed7a2
Tests: removed multiple server certificates from ssl_ocsp.t.
Multiple server certificates are not needed to test OCSP verification of
client certificates (in contrast to OCSP stapling, where server certificates
are verified, and different staples should be correctly returned with
different server certificates). And using multiple server certificates
causes issues when testing with LibreSSL due to broken sigalgs-based
server certificate selection in LibreSSL with TLSv1.3.
Accordingly, the test is simplified to do not use multiple server
certificates.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 23 Mar 2023 19:50:26 +0300 |
parents | 9d98c2ad3126 |
children | 727741cdff74 |
comparison
equal
deleted
inserted
replaced
1846:9d98c2ad3126 | 1847:a9704b9ed7a2 |
---|---|
61 ssl_ocsp leaf; | 61 ssl_ocsp leaf; |
62 ssl_verify_client on; | 62 ssl_verify_client on; |
63 ssl_verify_depth 2; | 63 ssl_verify_depth 2; |
64 ssl_client_certificate trusted.crt; | 64 ssl_client_certificate trusted.crt; |
65 | 65 |
66 ssl_ciphers DEFAULT:ECCdraft; | |
67 | |
68 ssl_certificate_key ec.key; | |
69 ssl_certificate ec.crt; | |
70 | |
71 ssl_certificate_key rsa.key; | 66 ssl_certificate_key rsa.key; |
72 ssl_certificate rsa.crt; | 67 ssl_certificate rsa.crt; |
73 | 68 |
74 ssl_session_cache shared:SSL:1m; | 69 ssl_session_cache shared:SSL:1m; |
75 ssl_session_tickets off; | 70 ssl_session_tickets off; |
271 $t->write_file('trusted.crt', | 266 $t->write_file('trusted.crt', |
272 $t->read_file('int.crt') . $t->read_file('root.crt')); | 267 $t->read_file('int.crt') . $t->read_file('root.crt')); |
273 | 268 |
274 # server cert/key | 269 # server cert/key |
275 | 270 |
276 system("openssl ecparam -genkey -out $d/ec.key -name prime256v1 " | 271 foreach my $name ('rsa') { |
277 . ">>$d/openssl.out 2>&1") == 0 or die "Can't create EC pem: $!\n"; | 272 system('openssl req -x509 -new ' |
278 system("openssl genrsa -out $d/rsa.key 2048 >>$d/openssl.out 2>&1") == 0 | |
279 or die "Can't create RSA pem: $!\n"; | |
280 | |
281 foreach my $name ('ec', 'rsa') { | |
282 system("openssl req -x509 -new -key $d/$name.key " | |
283 . "-config $d/openssl.conf -subj /CN=$name/ " | 273 . "-config $d/openssl.conf -subj /CN=$name/ " |
284 . "-out $d/$name.crt -keyout $d/$name.key " | 274 . "-out $d/$name.crt -keyout $d/$name.key " |
285 . ">>$d/openssl.out 2>&1") == 0 | 275 . ">>$d/openssl.out 2>&1") == 0 |
286 or die "Can't create certificate for $name: $!\n"; | 276 or die "Can't create certificate for $name: $!\n"; |
287 } | 277 } |
288 | 278 |
289 $t->run_daemon(\&http_daemon, $t, port(8081)); | 279 $t->run_daemon(\&http_daemon, $t, port(8081)); |
290 $t->run_daemon(\&http_daemon, $t, port(8082)); | 280 $t->run_daemon(\&http_daemon, $t, port(8082)); |
291 $t->run()->plan(14); | 281 $t->run()->plan(15); |
292 | 282 |
293 $t->waitforsocket("127.0.0.1:" . port(8081)); | 283 $t->waitforsocket("127.0.0.1:" . port(8081)); |
294 $t->waitforsocket("127.0.0.1:" . port(8082)); | 284 $t->waitforsocket("127.0.0.1:" . port(8082)); |
295 | 285 |
296 my $version = get_version(); | 286 my $version = get_version(); |
297 | 287 |
298 ############################################################################### | 288 ############################################################################### |
299 | 289 |
300 like(get('RSA', 'end'), qr/200 OK.*SUCCESS/s, 'ocsp leaf'); | 290 like(get('end'), qr/200 OK.*SUCCESS/s, 'ocsp leaf'); |
301 | 291 |
302 # demonstrate that ocsp int request is failed due to missing resolver | 292 # demonstrate that ocsp int request is failed due to missing resolver |
303 | 293 |
304 like(get('RSA', 'end', sni => 'resolver'), | 294 like(get('end', sni => 'resolver'), |
305 qr/400 Bad.*FAILED:certificate status request failed/s, | 295 qr/400 Bad.*FAILED:certificate status request failed/s, |
306 'ocsp many failed request'); | 296 'ocsp many failed request'); |
307 | 297 |
308 # demonstrate that ocsp int request is actually made by failing ocsp response | 298 # demonstrate that ocsp int request is actually made by failing ocsp response |
309 | 299 |
310 like(get('RSA', 'end', port => 8444), | 300 like(get('end', port => 8444), |
311 qr/400 Bad.*FAILED:certificate status request failed/s, | 301 qr/400 Bad.*FAILED:certificate status request failed/s, |
312 'ocsp many failed'); | 302 'ocsp many failed'); |
313 | 303 |
314 # now prepare valid ocsp int response | 304 # now prepare valid ocsp int response |
315 | 305 |
321 . "-rsigner $d/root.crt -rkey $d/root.key " | 311 . "-rsigner $d/root.crt -rkey $d/root.key " |
322 . "-reqin $d/int-req.der -respout $d/int-resp.der -ndays 1 " | 312 . "-reqin $d/int-req.der -respout $d/int-resp.der -ndays 1 " |
323 . ">>$d/openssl.out 2>&1") == 0 | 313 . ">>$d/openssl.out 2>&1") == 0 |
324 or die "Can't create OCSP response: $!\n"; | 314 or die "Can't create OCSP response: $!\n"; |
325 | 315 |
326 like(get('RSA', 'end', port => 8444), qr/200 OK.*SUCCESS/s, 'ocsp many'); | 316 like(get('end', port => 8444), qr/200 OK.*SUCCESS/s, 'ocsp many'); |
327 | 317 |
328 # store into ssl_ocsp_cache | 318 # store into ssl_ocsp_cache |
329 | 319 |
330 like(get('RSA', 'end', port => 8446), qr/200 OK.*SUCCESS/s, 'cache store'); | 320 like(get('end', port => 8446), qr/200 OK.*SUCCESS/s, 'cache store'); |
331 | 321 |
332 # revoke | 322 # revoke |
333 | 323 |
334 system("openssl ca -config $d/ca.conf -revoke $d/end.crt " | 324 system("openssl ca -config $d/ca.conf -revoke $d/end.crt " |
335 . "-keyfile $d/root.key -cert $d/root.crt " | 325 . "-keyfile $d/root.key -cert $d/root.crt " |
344 . "-rsigner $d/int.crt -rkey $d/int.key " | 334 . "-rsigner $d/int.crt -rkey $d/int.key " |
345 . "-reqin $d/req.der -respout $d/revoked.der -ndays 1 " | 335 . "-reqin $d/req.der -respout $d/revoked.der -ndays 1 " |
346 . ">>$d/openssl.out 2>&1") == 0 | 336 . ">>$d/openssl.out 2>&1") == 0 |
347 or die "Can't create OCSP response: $!\n"; | 337 or die "Can't create OCSP response: $!\n"; |
348 | 338 |
349 like(get('RSA', 'end'), qr/400 Bad.*FAILED:certificate revoked/s, 'revoked'); | 339 like(get('end'), qr/400 Bad.*FAILED:certificate revoked/s, 'revoked'); |
350 | 340 |
351 # with different responder where it's still valid | 341 # with different responder where it's still valid |
352 | 342 |
353 like(get('RSA', 'end', port => 8445), qr/200 OK.*SUCCESS/s, 'ocsp responder'); | 343 like(get('end', port => 8445), qr/200 OK.*SUCCESS/s, 'ocsp responder'); |
354 | 344 |
355 # with different context to responder where it's still valid | 345 # with different context to responder where it's still valid |
356 | 346 |
357 like(get('RSA', 'end', sni => 'sni'), qr/200 OK.*SUCCESS/s, 'ocsp context'); | 347 like(get('end', sni => 'sni'), qr/200 OK.*SUCCESS/s, 'ocsp context'); |
358 | 348 |
359 # with cached ocsp response it's still valid | 349 # with cached ocsp response it's still valid |
360 | 350 |
361 like(get('RSA', 'end', port => 8446), qr/200 OK.*SUCCESS/s, 'cache lookup'); | 351 like(get('end', port => 8446), qr/200 OK.*SUCCESS/s, 'cache lookup'); |
362 | 352 |
363 # ocsp end response signed with invalid (root) cert, expect HTTP 400 | 353 # ocsp end response signed with invalid (root) cert, expect HTTP 400 |
364 | 354 |
365 like(get('ECDSA', 'ec-end'), | 355 like(get('ec-end'), |
366 qr/400 Bad.*FAILED:certificate status request failed/s, | 356 qr/400 Bad.*FAILED:certificate status request failed/s, |
367 'root ca not trusted'); | 357 'root ca not trusted'); |
368 | 358 |
369 # now sign ocsp end response with valid int cert | 359 # now sign ocsp end response with valid int cert |
370 | 360 |
372 . "-rsigner $d/int.crt -rkey $d/int.key " | 362 . "-rsigner $d/int.crt -rkey $d/int.key " |
373 . "-reqin $d/ec-req.der -respout $d/ec-resp.der -ndays 1 " | 363 . "-reqin $d/ec-req.der -respout $d/ec-resp.der -ndays 1 " |
374 . ">>$d/openssl.out 2>&1") == 0 | 364 . ">>$d/openssl.out 2>&1") == 0 |
375 or die "Can't create EC OCSP response: $!\n"; | 365 or die "Can't create EC OCSP response: $!\n"; |
376 | 366 |
377 like(get('ECDSA', 'ec-end'), qr/200 OK.*SUCCESS/s, 'ocsp ecdsa'); | 367 like(get('ec-end'), qr/200 OK.*SUCCESS/s, 'ocsp ecdsa'); |
378 | 368 |
379 my ($s, $ssl) = get('ECDSA', 'ec-end'); | 369 my ($s, $ssl) = get('ec-end'); |
380 my $ses = Net::SSLeay::get_session($ssl); | 370 my $ses = Net::SSLeay::get_session($ssl); |
381 | 371 |
382 like(get('ECDSA', 'ec-end', ses => $ses), | 372 like(get('ec-end', ses => $ses), |
383 qr/200 OK.*SUCCESS:r/s, 'session reused'); | 373 qr/200 OK.*SUCCESS:r/s, 'session reused'); |
384 | 374 |
385 # revoke with saved session | 375 # revoke with saved session |
386 | 376 |
387 system("openssl ca -config $d/ca.conf -revoke $d/ec-end.crt " | 377 system("openssl ca -config $d/ca.conf -revoke $d/ec-end.crt " |
399 . ">>$d/openssl.out 2>&1") == 0 | 389 . ">>$d/openssl.out 2>&1") == 0 |
400 or die "Can't create OCSP response: $!\n"; | 390 or die "Can't create OCSP response: $!\n"; |
401 | 391 |
402 # reusing session with revoked certificate | 392 # reusing session with revoked certificate |
403 | 393 |
404 like(get('ECDSA', 'ec-end', ses => $ses), | 394 like(get('ec-end', ses => $ses), |
405 qr/400 Bad.*FAILED:certificate revoked:r/s, 'session reused - revoked'); | 395 qr/400 Bad.*FAILED:certificate revoked:r/s, 'session reused - revoked'); |
406 | 396 |
407 # regression test for self-signed | 397 # regression test for self-signed |
408 | 398 |
409 like(get('RSA', 'root', port => 8447), qr/200 OK.*SUCCESS/s, 'ocsp one'); | 399 like(get('root', port => 8447), qr/200 OK.*SUCCESS/s, 'ocsp one'); |
400 | |
401 # check for errors | |
402 | |
403 like(`grep -F '[crit]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no crit'); | |
410 | 404 |
411 ############################################################################### | 405 ############################################################################### |
412 | 406 |
413 sub get { | 407 sub get { |
414 my ($type, $cert, %extra) = @_; | 408 my ($cert, %extra) = @_; |
415 $type = 'PSS' if $type eq 'RSA' && $version > 0x0303; | 409 my ($s, $ssl) = get_ssl_socket($cert, %extra); |
416 my ($s, $ssl) = get_ssl_socket($type, $cert, %extra); | |
417 my $cipher = Net::SSLeay::get_cipher($ssl); | 410 my $cipher = Net::SSLeay::get_cipher($ssl); |
418 Test::Nginx::log_core('||', "cipher: $cipher"); | 411 Test::Nginx::log_core('||', "cipher: $cipher"); |
419 my $host = $extra{sni} ? $extra{sni} : 'localhost'; | 412 my $host = $extra{sni} ? $extra{sni} : 'localhost'; |
420 local $SIG{PIPE} = 'IGNORE'; | 413 local $SIG{PIPE} = 'IGNORE'; |
421 log_out("GET /serial HTTP/1.0\nHost: $host\n\n"); | 414 log_out("GET /serial HTTP/1.0\nHost: $host\n\n"); |
426 return $r unless wantarray(); | 419 return $r unless wantarray(); |
427 return ($s, $ssl); | 420 return ($s, $ssl); |
428 } | 421 } |
429 | 422 |
430 sub get_ssl_socket { | 423 sub get_ssl_socket { |
431 my ($type, $cert, %extra) = @_; | 424 my ($cert, %extra) = @_; |
432 my $ses = $extra{ses}; | 425 my $ses = $extra{ses}; |
433 my $sni = $extra{sni}; | 426 my $sni = $extra{sni}; |
434 my $port = $extra{port} || 8443; | 427 my $port = $extra{port} || 8443; |
435 my $s; | 428 my $s; |
436 | 429 |
447 log_in("died: $@"); | 440 log_in("died: $@"); |
448 return undef; | 441 return undef; |
449 } | 442 } |
450 | 443 |
451 my $ctx = Net::SSLeay::CTX_new() or die("Failed to create SSL_CTX $!"); | 444 my $ctx = Net::SSLeay::CTX_new() or die("Failed to create SSL_CTX $!"); |
452 | |
453 if (defined $type) { | |
454 my $ssleay = Net::SSLeay::SSLeay(); | |
455 if ($ssleay < 0x1000200f || $ssleay == 0x20000000) { | |
456 Net::SSLeay::CTX_set_cipher_list($ctx, $type) | |
457 or die("Failed to set cipher list"); | |
458 } else { | |
459 # SSL_CTRL_SET_SIGALGS_LIST | |
460 Net::SSLeay::CTX_ctrl($ctx, 98, 0, $type . '+SHA256') | |
461 or die("Failed to set sigalgs"); | |
462 } | |
463 } | |
464 | 445 |
465 Net::SSLeay::set_cert_and_key($ctx, "$d/$cert.crt", "$d/$cert.key") | 446 Net::SSLeay::set_cert_and_key($ctx, "$d/$cert.crt", "$d/$cert.key") |
466 or die if $cert; | 447 or die if $cert; |
467 my $ssl = Net::SSLeay::new($ctx) or die("Failed to create SSL $!"); | 448 my $ssl = Net::SSLeay::new($ctx) or die("Failed to create SSL $!"); |
468 Net::SSLeay::set_session($ssl, $ses) if defined $ses; | 449 Net::SSLeay::set_session($ssl, $ses) if defined $ses; |