Skip to content

Commit c85a9d0

Browse files
committed
Tests: ssl session ticket key rotation tests.
1 parent aedae20 commit c85a9d0

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

ssl_session_ticket_key.t

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#!/usr/bin/perl
2+
3+
# (C) Sergey Kandaurov
4+
# (C) Nginx, Inc.
5+
6+
# Tests for rotation of SSL session ticket keys.
7+
8+
###############################################################################
9+
10+
use warnings;
11+
use strict;
12+
13+
use Test::More;
14+
15+
BEGIN { use FindBin; chdir($FindBin::Bin); }
16+
17+
use lib 'lib';
18+
use Test::Nginx;
19+
20+
###############################################################################
21+
22+
select STDERR; $| = 1;
23+
select STDOUT; $| = 1;
24+
25+
eval {
26+
require Net::SSLeay; die if $Net::SSLeay::VERSION < 1.86;
27+
Net::SSLeay::load_error_strings();
28+
Net::SSLeay::SSLeay_add_ssl_algorithms();
29+
Net::SSLeay::randomize();
30+
};
31+
plan(skip_all => 'Net::SSLeay version => 1.86 required') if $@;
32+
33+
my $t = Test::Nginx->new()->has(qw/http http_ssl/)->has_daemon('openssl')
34+
->plan(2)->write_file_expand('nginx.conf', <<'EOF');
35+
36+
%%TEST_GLOBALS%%
37+
38+
daemon off;
39+
worker_processes 2;
40+
41+
events {
42+
}
43+
44+
http {
45+
%%TEST_GLOBALS_HTTP%%
46+
47+
ssl_certificate_key localhost.key;
48+
ssl_certificate localhost.crt;
49+
50+
server {
51+
listen 127.0.0.1:8080 ssl;
52+
server_name localhost;
53+
54+
ssl_session_cache shared:SSL:1m;
55+
ssl_session_timeout 2;
56+
}
57+
}
58+
59+
EOF
60+
61+
$t->write_file('openssl.conf', <<EOF);
62+
[ req ]
63+
default_bits = 2048
64+
encrypt_key = no
65+
distinguished_name = req_distinguished_name
66+
[ req_distinguished_name ]
67+
EOF
68+
69+
my $d = $t->testdir();
70+
71+
foreach my $name ('localhost') {
72+
system('openssl req -x509 -new '
73+
. "-config $d/openssl.conf -subj /CN=$name/ "
74+
. "-out $d/$name.crt -keyout $d/$name.key "
75+
. ">>$d/openssl.out 2>&1") == 0
76+
or die "Can't create certificate for $name: $!\n";
77+
}
78+
79+
$t->run();
80+
81+
###############################################################################
82+
83+
# the test uses multiple worker processes to check shared tickey key rotation
84+
#
85+
# before 1.23.2, any test can fail depending on which worker served connection:
86+
# the 1st test fails if served by another worker, because keys aren't shared
87+
# the 2nd test fails if served by the same worker due to the lack of rotation
88+
#
89+
# with a single worker process it is only the 2nd test that fails
90+
91+
local $TODO = 'not yet' unless $t->has_version('1.23.2');
92+
93+
my $key = get_ticket_key_name();
94+
95+
select undef, undef, undef, 0.5;
96+
is(get_ticket_key_name(), $key, 'ticket key match');
97+
98+
select undef, undef, undef, 2.5;
99+
cmp_ok(get_ticket_key_name(), 'ne', $key, 'ticket key next');
100+
101+
###############################################################################
102+
103+
sub get_ticket_key_name {
104+
my $ses = get_ssl_session();
105+
my $asn = Net::SSLeay::i2d_SSL_SESSION($ses);
106+
my $any = qr/[\x00-\xff]/;
107+
next:
108+
# tag(10) | len{2} | OCTETSTRING(4) | len{2} | ticket(key_name|..)
109+
$asn =~ /\xaa\x81($any)\x04\x81($any)($any{16})/g;
110+
return if !defined $3;
111+
goto next if unpack("C", $1) - unpack("C", $2) != 3;
112+
my $key = unpack "H*", $3;
113+
Test::Nginx::log_core('||', "ticket key: $key");
114+
return $key;
115+
}
116+
117+
sub get_ssl_session {
118+
my ($s, $ssl) = get_ssl_socket();
119+
120+
Net::SSLeay::write($ssl, <<EOF);
121+
GET / HTTP/1.0
122+
Host: localhost
123+
124+
EOF
125+
Net::SSLeay::read($ssl);
126+
Net::SSLeay::get_session($ssl);
127+
}
128+
129+
sub get_ssl_socket {
130+
my $s = IO::Socket::INET->new('127.0.0.1:' . port(8080));
131+
my $ctx = Net::SSLeay::CTX_new() or die("Failed to create SSL_CTX $!");
132+
my $ssl = Net::SSLeay::new($ctx) or die("Failed to create SSL $!");
133+
Net::SSLeay::set_fd($ssl, fileno($s));
134+
Net::SSLeay::connect($ssl) or die("ssl connect");
135+
return ($s, $ssl);
136+
}
137+
138+
###############################################################################

0 commit comments

Comments
 (0)