Mercurial > hg > nginx-tests
diff ssl_certificates.t @ 1865:0e1865aa9b33
Tests: reworked http SSL tests to use IO::Socket::SSL.
Relevant infrastructure is provided in Test::Nginx http() functions.
This also ensures that SSL handshake and various read and write operations
are guarded with timeouts.
The ssl_sni_reneg.t test uses IO::Socket::SSL::_get_ssl_object() to access
the Net::SSLeay object directly and trigger renegotation. While
not exactly correct, this seems to be good enough for tests.
Similarly, IO::Socket::SSL::_get_ssl_object() is used in ssl_stapling.t,
since SSL_ocsp_staple_callback is called with the socket instead of the
Net::SSLeay object.
Similarly, IO::Socket::SSL::_get_ssl_object() is used in ssl_verify_client.t,
since there seems to be no way to obtain CA list with IO::Socket::SSL.
Notable change to http() request interface is that http_end() now closes
the socket. This is to make sure that SSL connections are properly
closed and SSL sessions are not removed from the IO::Socket::SSL session
cache. This affected access_log.t, which was modified accordingly.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 18 May 2023 18:07:17 +0300 |
parents | dbce8fb5f5f8 |
children | 1ba5108b6c24 |
line wrap: on
line diff
--- a/ssl_certificates.t +++ b/ssl_certificates.t @@ -22,16 +22,8 @@ use Test::Nginx; select STDERR; $| = 1; select STDOUT; $| = 1; -eval { - require Net::SSLeay; - Net::SSLeay::load_error_strings(); - Net::SSLeay::SSLeay_add_ssl_algorithms(); - Net::SSLeay::randomize(); - Net::SSLeay::SSLeay(); -}; -plan(skip_all => 'Net::SSLeay not installed or too old') if $@; - -my $t = Test::Nginx->new()->has(qw/http http_ssl/)->has_daemon('openssl'); +my $t = Test::Nginx->new()->has(qw/http http_ssl socket_ssl/) + ->has_daemon('openssl'); plan(skip_all => 'no multiple certificates') if $t->has_module('BoringSSL'); @@ -51,8 +43,10 @@ http { ssl_certificate rsa.crt; ssl_ciphers DEFAULT:ECCdraft; + add_header X-SSL-Protocol $ssl_protocol; + server { - listen 127.0.0.1:8080 ssl; + listen 127.0.0.1:8443 ssl; server_name localhost; ssl_certificate_key ec.key; @@ -91,65 +85,54 @@ foreach my $name ('ec', 'rsa') { or die "Can't create certificate for $name: $!\n"; } +$t->write_file('index.html', ''); + $t->run()->plan(2); ############################################################################### -like(get_cert('RSA'), qr/CN=rsa/, 'ssl cert RSA'); -like(get_cert('ECDSA'), qr/CN=ec/, 'ssl cert ECDSA'); +TODO: { +local $TODO = 'broken TLSv1.3 sigalgs in LibreSSL' + if $t->has_module('LibreSSL') && test_tls13(); + +like(cert('RSA'), qr/CN=rsa/, 'ssl cert RSA'); + +} + +like(cert('ECDSA'), qr/CN=ec/, 'ssl cert ECDSA'); ############################################################################### -sub get_version { - my ($s, $ssl) = get_ssl_socket(); - return Net::SSLeay::version($ssl); +sub test_tls13 { + return http_get('/', SSL => 1) =~ /TLSv1.3/; } -sub get_cert { - my ($type) = @_; - $type = 'PSS' if $type eq 'RSA' && get_version() > 0x0303; - my ($s, $ssl) = get_ssl_socket($type); - my $cipher = Net::SSLeay::get_cipher($ssl); - Test::Nginx::log_core('||', "cipher: $cipher"); - return Net::SSLeay::dump_peer_certificate($ssl); +sub cert { + my $s = get_socket(@_) || return; + return $s->dump_peer_certificate(); } -sub get_ssl_socket { +sub get_socket { my ($type) = @_; - my $s; - - eval { - local $SIG{ALRM} = sub { die "timeout\n" }; - local $SIG{PIPE} = sub { die "sigpipe\n" }; - alarm(8); - $s = IO::Socket::INET->new('127.0.0.1:' . port(8080)); - alarm(0); - }; - alarm(0); - - if ($@) { - log_in("died: $@"); - return undef; - } - my $ctx = Net::SSLeay::CTX_new() or die("Failed to create SSL_CTX $!"); - - if (defined $type) { + my $ctx_cb = sub { + my $ctx = shift; + return unless defined $type; my $ssleay = Net::SSLeay::SSLeay(); - if ($ssleay < 0x1000200f || $ssleay == 0x20000000) { - Net::SSLeay::CTX_set_cipher_list($ctx, $type) - or die("Failed to set cipher list"); - } else { - # SSL_CTRL_SET_SIGALGS_LIST - Net::SSLeay::CTX_ctrl($ctx, 98, 0, $type . '+SHA256') - or die("Failed to set sigalgs"); - } - } + return if ($ssleay < 0x1000200f || $ssleay == 0x20000000); + my $sigalgs = 'RSA+SHA256:PSS+SHA256'; + $sigalgs = $type . '+SHA256' unless $type eq 'RSA'; + # SSL_CTRL_SET_SIGALGS_LIST + Net::SSLeay::CTX_ctrl($ctx, 98, 0, $sigalgs) + or die("Failed to set sigalgs"); + }; - my $ssl = Net::SSLeay::new($ctx) or die("Failed to create SSL $!"); - Net::SSLeay::set_fd($ssl, fileno($s)); - Net::SSLeay::connect($ssl) or die("ssl connect"); - return ($s, $ssl); + return http_get( + '/', start => 1, + SSL => 1, + SSL_cipher_list => $type, + SSL_create_ctx_callback => $ctx_cb + ); } ###############################################################################