comparison ssl_session_ticket_key.t @ 1816:5817625792bd

Tests: ssl session ticket key rotation tests.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 20 Dec 2022 19:42:09 +0400
parents
children 0381a0a212e1
comparison
equal deleted inserted replaced
1815:173c9b792c2c 1816:5817625792bd
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 ###############################################################################