# HG changeset patch # User Sergey Kandaurov <pluk...@nginx.com> # Date 1671070326 -14400 # Thu Dec 15 06:12:06 2022 +0400 # Node ID 82dc9c3a4ec81636e42e1417ce6661f3b0e4d358 # Parent ff6c99824947575d4a8d3c9aeea8d6b68e0ace29 Tests: ssl session ticket key rotation tests.
diff --git a/ssl_session_ticket_key.t b/ssl_session_ticket_key.t new file mode 100644 --- /dev/null +++ b/ssl_session_ticket_key.t @@ -0,0 +1,141 @@ +#!/usr/bin/perl + +# (C) Sergey Kandaurov +# (C) Nginx, Inc. + +# Tests for rotation of SSL session ticket keys. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +eval { + require Net::SSLeay; die if $Net::SSLeay::VERSION < 1.86; + Net::SSLeay::load_error_strings(); + Net::SSLeay::SSLeay_add_ssl_algorithms(); + Net::SSLeay::randomize(); +}; +plan(skip_all => 'Net::SSLeay version => 1.86 required') if $@; + +my $t = Test::Nginx->new()->has(qw/http http_ssl/)->has_daemon('openssl') + ->plan(2)->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; +worker_processes 2; + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + ssl_certificate_key localhost.key; + ssl_certificate localhost.crt; + + server { + listen 127.0.0.1:8080 ssl; + server_name localhost; + + ssl_session_cache shared:SSL:1m; + ssl_session_timeout 2; + } +} + +EOF + +$t->write_file('openssl.conf', <<EOF); +[ req ] +default_bits = 2048 +encrypt_key = no +distinguished_name = req_distinguished_name +[ req_distinguished_name ] +EOF + +my $d = $t->testdir(); + +foreach my $name ('localhost') { + system('openssl req -x509 -new ' + . "-config $d/openssl.conf -subj /CN=$name/ " + . "-out $d/$name.crt -keyout $d/$name.key " + . ">>$d/openssl.out 2>&1") == 0 + or die "Can't create certificate for $name: $!\n"; +} + +$t->run(); + +############################################################################### + +# any test can fail depending on which worker process served connection, +# with a single worker process it is only the 2nd test that fails +local $TODO = 'not yet' unless $t->has_version('1.23.2'); + +my $ses = get_ssl_session(); +my $key = get_ticket_key_name($ses); + +sleep 1; + +$ses = get_ssl_session($ses); +is(get_ticket_key_name($ses), $key, 'ticket key match'); + +sleep 2; + +$ses = get_ssl_session($ses); +isnt(get_ticket_key_name($ses), $key, 'ticket key next'); + +############################################################################### + +sub get_ticket_key_name { + my ($ses) = @_; + my $asn = Net::SSLeay::i2d_SSL_SESSION($ses); + my $any = qr/[\x00-\xff]/; +next: + # tag(10) | len{2} | OCTETSTRING(4) | len{2} | ticket(key_name|..) + $asn =~ /\xaa\x81($any)\x04\x81($any)($any{16})/g; + return if !defined $3; + goto next if unpack("C", $1) - unpack("C", $2) != 3; + unpack "H*", $3; +} + +sub get_ssl_session { + my ($ses) = @_; + + my ($s, $ssl) = get_ssl_socket(ses => $ses); + + Net::SSLeay::write($ssl, <<EOF); +GET / HTTP/1.0 +Host: localhost + +EOF + Net::SSLeay::read($ssl); + + Net::SSLeay::get_session($ssl); +} + +sub get_ssl_socket { + my (%extra) = @_; + + my $s = IO::Socket::INET->new('127.0.0.1:' . port(8080)); + my $ctx = Net::SSLeay::CTX_new() or die("Failed to create SSL_CTX $!"); + my $ssl = Net::SSLeay::new($ctx) or die("Failed to create SSL $!"); + Net::SSLeay::set_session($ssl, $extra{ses}) if $extra{ses}; + Net::SSLeay::set_fd($ssl, fileno($s)); + Net::SSLeay::connect($ssl) or die("ssl connect"); + return ($s, $ssl); +} + +############################################################################### _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel