Mercurial > hg > nginx-tests
comparison stream_ssl_variables.t @ 1863:dbb7561a9441
Tests: reworked stream SSL tests to use IO::Socket::SSL.
Relevant infrastructure is provided in Test::Nginx::Stream. This also
ensures that SSL handshake and various read operations are guarded
with timeouts.
The stream_ssl_verify_client.t test uses IO::Socket::SSL::_get_ssl_object()
to access the Net::SSLeay object directly, as it seems to be the only
way to obtain CA list with IO::Socket::SSL. While not exactly correct,
this seems to be good enough for tests.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 18 May 2023 18:07:12 +0300 |
parents | 65b1dd07c0e4 |
children | 884e898b9fe7 |
comparison
equal
deleted
inserted
replaced
1862:7681a970f6bd | 1863:dbb7561a9441 |
---|---|
21 ############################################################################### | 21 ############################################################################### |
22 | 22 |
23 select STDERR; $| = 1; | 23 select STDERR; $| = 1; |
24 select STDOUT; $| = 1; | 24 select STDOUT; $| = 1; |
25 | 25 |
26 eval { | 26 my $t = Test::Nginx->new() |
27 require Net::SSLeay; | 27 ->has(qw/stream stream_ssl stream_return socket_ssl_sni/) |
28 Net::SSLeay::load_error_strings(); | |
29 Net::SSLeay::SSLeay_add_ssl_algorithms(); | |
30 Net::SSLeay::randomize(); | |
31 }; | |
32 plan(skip_all => 'Net::SSLeay not installed') if $@; | |
33 | |
34 eval { | |
35 my $ctx = Net::SSLeay::CTX_new() or die; | |
36 my $ssl = Net::SSLeay::new($ctx) or die; | |
37 Net::SSLeay::set_tlsext_host_name($ssl, 'example.org') == 1 or die; | |
38 }; | |
39 plan(skip_all => 'Net::SSLeay with OpenSSL SNI support required') if $@; | |
40 | |
41 my $t = Test::Nginx->new()->has(qw/stream stream_ssl stream_return/) | |
42 ->has_daemon('openssl'); | 28 ->has_daemon('openssl'); |
43 | 29 |
44 $t->write_file_expand('nginx.conf', <<'EOF'); | 30 $t->write_file_expand('nginx.conf', <<'EOF'); |
45 | 31 |
46 %%TEST_GLOBALS%% | 32 %%TEST_GLOBALS%% |
57 ssl_certificate localhost.crt; | 43 ssl_certificate localhost.crt; |
58 ssl_session_cache builtin; | 44 ssl_session_cache builtin; |
59 | 45 |
60 server { | 46 server { |
61 listen 127.0.0.1:8080; | 47 listen 127.0.0.1:8080; |
62 listen 127.0.0.1:8081 ssl; | 48 listen 127.0.0.1:8443 ssl; |
63 return $ssl_session_reused:$ssl_session_id:$ssl_cipher:$ssl_protocol; | 49 return $ssl_session_reused:$ssl_session_id:$ssl_cipher:$ssl_protocol; |
64 } | 50 } |
65 | 51 |
66 server { | 52 server { |
67 listen 127.0.0.1:8082 ssl; | 53 listen 127.0.0.1:8444 ssl; |
68 return $ssl_server_name; | 54 return $ssl_server_name; |
69 } | 55 } |
70 } | 56 } |
71 | 57 |
72 EOF | 58 EOF |
91 | 77 |
92 $t->run()->plan(6); | 78 $t->run()->plan(6); |
93 | 79 |
94 ############################################################################### | 80 ############################################################################### |
95 | 81 |
96 my ($s, $ssl); | 82 my $s; |
97 | 83 |
98 is(stream('127.0.0.1:' . port(8080))->read(), ':::', 'no ssl'); | 84 is(stream('127.0.0.1:' . port(8080))->read(), ':::', 'no ssl'); |
99 | 85 |
100 ($s, $ssl) = get_ssl_socket(port(8081)); | 86 $s = stream( |
101 like(Net::SSLeay::read($ssl), qr/^\.:(\w{64})?:[\w-]+:(TLS|SSL)v(\d|\.)+$/, | 87 PeerAddr => '127.0.0.1:' . port(8443), |
88 SSL => 1, | |
89 SSL_session_cache_size => 100 | |
90 ); | |
91 like($s->read(), qr/^\.:(\w{64})?:[\w-]+:(TLS|SSL)v(\d|\.)+$/, | |
102 'ssl variables'); | 92 'ssl variables'); |
103 | 93 |
104 TODO: { | 94 TODO: { |
95 local $TODO = 'no TLSv1.3 sessions, old Net::SSLeay' | |
96 if $Net::SSLeay::VERSION < 1.88 && test_tls13(); | |
97 local $TODO = 'no TLSv1.3 sessions, old IO::Socket::SSL' | |
98 if $IO::Socket::SSL::VERSION < 2.061 && test_tls13(); | |
105 local $TODO = 'no TLSv1.3 sessions in LibreSSL' | 99 local $TODO = 'no TLSv1.3 sessions in LibreSSL' |
106 if $t->has_module('LibreSSL') && test_tls13(); | 100 if $t->has_module('LibreSSL') && test_tls13(); |
107 | 101 |
108 my $ses = Net::SSLeay::get_session($ssl); | 102 $s = stream( |
109 ($s, $ssl) = get_ssl_socket(port(8081), $ses); | 103 PeerAddr => '127.0.0.1:' . port(8443), |
110 like(Net::SSLeay::read($ssl), qr/^r:(\w{64})?:[\w-]+:(TLS|SSL)v(\d|\.)+$/, | 104 SSL => 1, |
105 SSL_reuse_ctx => $s->socket() | |
106 ); | |
107 like($s->read(), qr/^r:(\w{64})?:[\w-]+:(TLS|SSL)v(\d|\.)+$/, | |
111 'ssl variables - session reused'); | 108 'ssl variables - session reused'); |
112 | 109 |
113 } | 110 } |
114 | 111 |
115 SKIP: { | 112 SKIP: { |
116 skip 'no sni', 3 unless $t->has_module('sni'); | 113 skip 'no sni', 3 unless $t->has_module('sni'); |
117 | 114 |
118 ($s, $ssl) = get_ssl_socket(port(8082), undef, 'example.com'); | 115 $s = stream( |
119 is(Net::SSLeay::ssl_read_all($ssl), 'example.com', 'ssl server name'); | 116 PeerAddr => '127.0.0.1:' . port(8444), |
117 SSL => 1, | |
118 SSL_session_cache_size => 100, | |
119 SSL_hostname => 'example.com' | |
120 ); | |
121 is($s->read(), 'example.com', 'ssl server name'); | |
120 | 122 |
121 my $ses = Net::SSLeay::get_session($ssl); | 123 $s = stream( |
122 ($s, $ssl) = get_ssl_socket(port(8082), $ses, 'example.com'); | 124 PeerAddr => '127.0.0.1:' . port(8444), |
123 is(Net::SSLeay::ssl_read_all($ssl), 'example.com', 'ssl server name - reused'); | 125 SSL => 1, |
126 SSL_reuse_ctx => $s->socket(), | |
127 SSL_hostname => 'example.com' | |
128 ); | |
129 is($s->read(), 'example.com', 'ssl server name - reused'); | |
124 | 130 |
125 ($s, $ssl) = get_ssl_socket(port(8082)); | 131 $s = stream( |
126 is(Net::SSLeay::ssl_read_all($ssl), '', 'ssl server name empty'); | 132 PeerAddr => '127.0.0.1:' . port(8444), |
133 SSL => 1 | |
134 ); | |
135 is($s->read(), '', 'ssl server name empty'); | |
127 | 136 |
128 } | 137 } |
138 | |
139 undef $s; | |
129 | 140 |
130 ############################################################################### | 141 ############################################################################### |
131 | 142 |
132 sub test_tls13 { | 143 sub test_tls13 { |
133 ($s, $ssl) = get_ssl_socket(port(8081)); | 144 $s = stream(PeerAddr => '127.0.0.1:' . port(8443), SSL => 1); |
134 Net::SSLeay::read($ssl) =~ /TLSv1.3/; | 145 $s->read() =~ /TLSv1.3/; |
135 } | |
136 | |
137 sub get_ssl_socket { | |
138 my ($port, $ses, $name) = @_; | |
139 | |
140 my $s = IO::Socket::INET->new('127.0.0.1:' . $port); | |
141 my $ctx = Net::SSLeay::CTX_new() or die("Failed to create SSL_CTX $!"); | |
142 my $ssl = Net::SSLeay::new($ctx) or die("Failed to create SSL $!"); | |
143 Net::SSLeay::set_tlsext_host_name($ssl, $name) if defined $name; | |
144 Net::SSLeay::set_session($ssl, $ses) if defined $ses; | |
145 Net::SSLeay::set_fd($ssl, fileno($s)); | |
146 Net::SSLeay::connect($ssl) or die("ssl connect"); | |
147 return ($s, $ssl); | |
148 } | 146 } |
149 | 147 |
150 ############################################################################### | 148 ############################################################################### |