|
| 1 | +#!/usr/bin/perl |
| 2 | + |
| 3 | +# (C) Nginx, Inc. |
| 4 | + |
| 5 | +# Tests for SSL object cache. |
| 6 | + |
| 7 | +############################################################################### |
| 8 | + |
| 9 | +use warnings; |
| 10 | +use strict; |
| 11 | + |
| 12 | +use Test::More; |
| 13 | + |
| 14 | +use POSIX qw/ mkfifo /; |
| 15 | + |
| 16 | +BEGIN { use FindBin; chdir($FindBin::Bin); } |
| 17 | + |
| 18 | +use lib 'lib'; |
| 19 | +use Test::Nginx; |
| 20 | + |
| 21 | +############################################################################### |
| 22 | + |
| 23 | +select STDERR; $| = 1; |
| 24 | +select STDOUT; $| = 1; |
| 25 | + |
| 26 | +plan(skip_all => 'win32') if $^O eq 'MSWin32'; |
| 27 | + |
| 28 | +my $t = Test::Nginx->new(); |
| 29 | + |
| 30 | +plan(skip_all => "not yet") unless $t->has_version('1.27.2'); |
| 31 | + |
| 32 | +$t->has(qw/http http_ssl proxy socket_ssl/)->has_daemon('openssl') |
| 33 | + ->write_file_expand('nginx.conf', <<'EOF'); |
| 34 | +
|
| 35 | +%%TEST_GLOBALS%% |
| 36 | +
|
| 37 | +daemon off; |
| 38 | +
|
| 39 | +events { |
| 40 | +} |
| 41 | +
|
| 42 | +http { |
| 43 | + %%TEST_GLOBALS_HTTP%% |
| 44 | +
|
| 45 | + server { |
| 46 | + listen 127.0.0.1:8443 ssl; |
| 47 | + server_name 1.example.com; |
| 48 | +
|
| 49 | + ssl_certificate 1.example.com.crt.fifo; |
| 50 | + ssl_certificate_key 1.example.com.key.fifo; |
| 51 | +
|
| 52 | + ssl_trusted_certificate root.crt.fifo; |
| 53 | + ssl_crl root.crl.fifo; |
| 54 | + } |
| 55 | +
|
| 56 | + server { |
| 57 | + listen 127.0.0.1:8444 ssl; |
| 58 | + server_name 1.example.com; |
| 59 | +
|
| 60 | + ssl_certificate %%TESTDIR%%/1.example.com.crt.fifo; |
| 61 | + ssl_certificate_key %%TESTDIR%%/1.example.com.key.fifo; |
| 62 | +
|
| 63 | + ssl_trusted_certificate %%TESTDIR%%/root.crt.fifo; |
| 64 | + ssl_crl %%TESTDIR%%/root.crl.fifo; |
| 65 | + } |
| 66 | +
|
| 67 | + server { |
| 68 | + listen 127.0.0.1:8445 ssl; |
| 69 | + server_name 2.example.com; |
| 70 | +
|
| 71 | + add_header X-Verify $ssl_client_verify:$ssl_client_s_dn; |
| 72 | +
|
| 73 | + ssl_certificate 2.example.com.crt.fifo; |
| 74 | + ssl_certificate_key 2.example.com.key.fifo; |
| 75 | +
|
| 76 | + ssl_verify_client on; |
| 77 | + ssl_client_certificate root.crt.fifo; |
| 78 | + ssl_crl root.crl.fifo; |
| 79 | + } |
| 80 | +
|
| 81 | + server { |
| 82 | + listen 127.0.0.1:8080; |
| 83 | + server_name localhost; |
| 84 | +
|
| 85 | + location / { |
| 86 | + proxy_pass https://127.0.0.1:8445; |
| 87 | +
|
| 88 | + proxy_ssl_certificate 1.example.com.crt.fifo; |
| 89 | + proxy_ssl_certificate_key 1.example.com.key.fifo; |
| 90 | +
|
| 91 | + proxy_ssl_name 2.example.com; |
| 92 | + proxy_ssl_verify on; |
| 93 | + proxy_ssl_trusted_certificate root.crt.fifo; |
| 94 | + proxy_ssl_crl root.crl.fifo; |
| 95 | + } |
| 96 | + } |
| 97 | +} |
| 98 | +
|
| 99 | +EOF |
| 100 | + |
| 101 | +my $d = $t->testdir(); |
| 102 | + |
| 103 | +$t->write_file('openssl.conf', <<EOF); |
| 104 | +[ req ] |
| 105 | +default_bits = 2048 |
| 106 | +encrypt_key = no |
| 107 | +distinguished_name = req_distinguished_name |
| 108 | +x509_extensions = myca_extensions |
| 109 | +[ req_distinguished_name ] |
| 110 | +[ myca_extensions ] |
| 111 | +basicConstraints = critical,CA:TRUE |
| 112 | +EOF |
| 113 | + |
| 114 | +$t->write_file('ca.conf', <<EOF); |
| 115 | +[ ca ] |
| 116 | +default_ca = myca |
| 117 | +
|
| 118 | +[ myca ] |
| 119 | +new_certs_dir = $d |
| 120 | +database = $d/certindex |
| 121 | +default_md = sha256 |
| 122 | +policy = myca_policy |
| 123 | +serial = $d/certserial |
| 124 | +default_days = 1 |
| 125 | +
|
| 126 | +[ myca_policy ] |
| 127 | +commonName = supplied |
| 128 | +EOF |
| 129 | + |
| 130 | +foreach my $name ('root') { |
| 131 | + system('openssl req -x509 -new ' |
| 132 | + . "-config $d/openssl.conf -subj /CN=$name/ " |
| 133 | + . "-out $d/$name.crt -keyout $d/$name.key " |
| 134 | + . ">>$d/openssl.out 2>&1") == 0 |
| 135 | + or die "Can't create certificate for $name: $!\n"; |
| 136 | +} |
| 137 | + |
| 138 | +$t->write_file('certserial', '1000'); |
| 139 | +$t->write_file('certindex', ''); |
| 140 | + |
| 141 | +foreach my $name ('1.example.com', '2.example.com') { |
| 142 | + system('openssl req -new ' |
| 143 | + . "-config $d/openssl.conf -subj /CN=$name/ " |
| 144 | + . "-out $d/$name.csr -keyout $d/$name.key " |
| 145 | + . ">>$d/openssl.out 2>&1") == 0 |
| 146 | + or die "Can't create certificate for $name: $!\n"; |
| 147 | + |
| 148 | + system("openssl ca -batch -config $d/ca.conf " |
| 149 | + . "-keyfile $d/root.key -cert $d/root.crt " |
| 150 | + . "-subj /CN=$name/ -in $d/$name.csr -out $d/$name.crt " |
| 151 | + . ">>$d/openssl.out 2>&1") == 0 |
| 152 | + or die "Can't sign certificate for $name: $!\n"; |
| 153 | +} |
| 154 | + |
| 155 | +system("openssl ca -gencrl -config $d/ca.conf " |
| 156 | + . "-keyfile $d/root.key -cert $d/root.crt " |
| 157 | + . "-out $d/root.crl -crldays 1 " |
| 158 | + . ">>$d/openssl.out 2>&1") == 0 |
| 159 | + or die "Can't update crl: $!\n"; |
| 160 | + |
| 161 | +foreach my $name ('root.crt', 'root.crl', '1.example.com.crt', |
| 162 | + '1.example.com.key', '2.example.com.crt', '2.example.com.key') |
| 163 | +{ |
| 164 | + mkfifo("$d/$name.fifo", 0700); |
| 165 | + $t->run_daemon(\&fifo_writer_daemon, $t, $name); |
| 166 | +} |
| 167 | + |
| 168 | +$t->write_file('t', ''); |
| 169 | + |
| 170 | +$t->plan(4)->run(); |
| 171 | + |
| 172 | +############################################################################### |
| 173 | + |
| 174 | +like(get(8443, '1.example.com'), qr/200 OK/, 'cached certificate'); |
| 175 | +like(get(8444, '1.example.com'), qr/200 OK/, 'absolute path'); |
| 176 | + |
| 177 | +like(get(8445, '2.example.com', '1.example.com'), |
| 178 | + qr/200 OK.*SUCCESS:.*1\.example\.com/s, 'cached CA and CRL'); |
| 179 | + |
| 180 | +like(http_get('/t'), qr/200 OK.*SUCCESS:.*1\.example\.com/s, 'proxy ssl'); |
| 181 | + |
| 182 | +############################################################################### |
| 183 | + |
| 184 | +sub get { |
| 185 | + my ($port, $ca, $cert) = @_; |
| 186 | + |
| 187 | + http_get('/t', |
| 188 | + PeerAddr => '127.0.0.1:' . port($port), |
| 189 | + SSL => 1, |
| 190 | + $ca ? ( |
| 191 | + SSL_ca_file => "$d/$ca.crt", |
| 192 | + SSL_verifycn_name => $ca, |
| 193 | + SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_PEER(), |
| 194 | + ) : (), |
| 195 | + $cert ? ( |
| 196 | + SSL_cert_file => "$d/$cert.crt", |
| 197 | + SSL_key_file => "$d/$cert.key" |
| 198 | + ) : () |
| 199 | + ); |
| 200 | +} |
| 201 | + |
| 202 | +############################################################################### |
| 203 | + |
| 204 | +sub fifo_writer_daemon { |
| 205 | + my ($t, $name) = @_; |
| 206 | + |
| 207 | + my $content = $t->read_file($name); |
| 208 | + |
| 209 | + while (1) { |
| 210 | + $t->write_file("$name.fifo", $content); |
| 211 | + # reset content after the first read |
| 212 | + $content = ""; |
| 213 | + } |
| 214 | +} |
| 215 | + |
| 216 | +############################################################################### |
0 commit comments