blob: 5e82944b6f8ba34dd74e294dab9820fa53cb8caf [file] [log] [blame]
Sergey Kandaurov21e861a2017-02-06 19:13:49 +03001#!/usr/bin/perl
2
3# (C) Sergey Kandaurov
4# (C) Nginx, Inc.
5
6# Tests for http ssl module, ssl_crl directive.
7
8###############################################################################
9
10use warnings;
11use strict;
12
13use Test::More;
14
15BEGIN { use FindBin; chdir($FindBin::Bin); }
16
17use lib 'lib';
18use Test::Nginx;
19
20###############################################################################
21
22select STDERR; $| = 1;
23select STDOUT; $| = 1;
24
25eval { require IO::Socket::SSL; };
26plan(skip_all => 'IO::Socket::SSL not installed') if $@;
27eval { IO::Socket::SSL::SSL_VERIFY_NONE(); };
28plan(skip_all => 'IO::Socket::SSL too old') if $@;
29
30my $t = Test::Nginx->new()->has(qw/http http_ssl/)
31 ->has_daemon('openssl')->plan(3);
32
33$t->write_file_expand('nginx.conf', <<'EOF');
34
35%%TEST_GLOBALS%%
36
37daemon off;
38
39events {
40}
41
42http {
43 %%TEST_GLOBALS_HTTP%%
44
45 ssl_certificate_key localhost.key;
46 ssl_certificate localhost.crt;
47
48 ssl_verify_client on;
49 ssl_client_certificate int-root.crt;
50
51 add_header X-Verify $ssl_client_verify always;
52
53 server {
54 listen 127.0.0.1:8080 ssl;
55 server_name localhost;
56
57 ssl_client_certificate root.crt;
58 ssl_crl empty.crl;
59 }
60
61 server {
62 listen 127.0.0.1:8081 ssl;
63 server_name localhost;
64
65 ssl_client_certificate root.crt;
66 ssl_crl root.crl;
67 }
68
69 server {
70 listen 127.0.0.1:8082 ssl;
71 server_name localhost;
72
73 ssl_verify_depth 2;
74 ssl_crl root.crl;
75 }
76}
77
78EOF
79
80my $d = $t->testdir();
81
82$t->write_file('openssl.conf', <<EOF);
83[ req ]
84default_bits = 1024
85encrypt_key = no
86distinguished_name = req_distinguished_name
87[ req_distinguished_name ]
88EOF
89
90$t->write_file('ca.conf', <<EOF);
91[ ca ]
92default_ca = myca
93
94[ myca ]
95new_certs_dir = $d
96database = $d/certindex
97default_md = sha1
98policy = myca_policy
99serial = $d/certserial
100default_days = 1
101
102[ myca_policy ]
103commonName = supplied
104EOF
105
106foreach my $name ('root', 'localhost') {
107 system('openssl req -x509 -new '
Sergey Kandaurov2225e6e2017-09-20 14:46:51 +0300108 . "-config $d/openssl.conf -subj /CN=$name/ "
109 . "-out $d/$name.crt -keyout $d/$name.key "
Sergey Kandaurov21e861a2017-02-06 19:13:49 +0300110 . ">>$d/openssl.out 2>&1") == 0
111 or die "Can't create certificate for $name: $!\n";
112}
113
114foreach my $name ('int', 'end') {
115 system("openssl req -new "
Sergey Kandaurov2225e6e2017-09-20 14:46:51 +0300116 . "-config $d/openssl.conf -subj /CN=$name/ "
117 . "-out $d/$name.csr -keyout $d/$name.key "
Sergey Kandaurov21e861a2017-02-06 19:13:49 +0300118 . ">>$d/openssl.out 2>&1") == 0
119 or die "Can't create certificate for $name: $!\n";
120}
121
122$t->write_file('certserial', '1000');
123$t->write_file('certindex', '');
124
Sergey Kandaurov2225e6e2017-09-20 14:46:51 +0300125system("openssl ca -batch -config $d/ca.conf "
126 . "-keyfile $d/root.key -cert $d/root.crt "
127 . "-subj /CN=int/ -in $d/int.csr -out $d/int.crt "
Sergey Kandaurov21e861a2017-02-06 19:13:49 +0300128 . ">>$d/openssl.out 2>&1") == 0
129 or die "Can't sign certificate for int: $!\n";
130
Sergey Kandaurov2225e6e2017-09-20 14:46:51 +0300131system("openssl ca -batch -config $d/ca.conf "
132 . "-keyfile $d/int.key -cert $d/int.crt "
133 . "-subj /CN=end/ -in $d/end.csr -out $d/end.crt "
Sergey Kandaurov21e861a2017-02-06 19:13:49 +0300134 . ">>$d/openssl.out 2>&1") == 0
135 or die "Can't sign certificate for end: $!\n";
136
Sergey Kandaurov2225e6e2017-09-20 14:46:51 +0300137system("openssl ca -gencrl -config $d/ca.conf "
138 . "-keyfile $d/root.key -cert $d/root.crt "
139 . "-out $d/empty.crl -crldays 1 "
Sergey Kandaurov21e861a2017-02-06 19:13:49 +0300140 . ">>$d/openssl.out 2>&1") == 0
141 or die "Can't create empty crl: $!\n";
142
Sergey Kandaurov2225e6e2017-09-20 14:46:51 +0300143system("openssl ca -config $d/ca.conf -revoke $d/int.crt "
144 . "-keyfile $d/root.key -cert $d/root.crt "
Sergey Kandaurov21e861a2017-02-06 19:13:49 +0300145 . ">>$d/openssl.out 2>&1") == 0
146 or die "Can't revoke int.crt: $!\n";
147
Sergey Kandaurov2225e6e2017-09-20 14:46:51 +0300148system("openssl ca -gencrl -config $d/ca.conf "
149 . "-keyfile $d/root.key -cert $d/root.crt "
150 . "-out $d/root.crl -crldays 1 "
Sergey Kandaurov21e861a2017-02-06 19:13:49 +0300151 . ">>$d/openssl.out 2>&1") == 0
152 or die "Can't update crl: $!\n";
153
154$t->write_file('int-root.crt',
155 $t->read_file('int.crt') . $t->read_file('root.crt'));
156
157$t->write_file('t', '');
158$t->run();
159
160###############################################################################
161
162like(get(8080, 'int'), qr/SUCCESS/, 'crl - no revoked certs');
163like(get(8081, 'int'), qr/FAILED/, 'crl - client cert revoked');
164like(get(8082, 'end'), qr/FAILED/, 'crl - intermediate cert revoked');
165
166###############################################################################
167
168sub get {
169 my ($port, $cert) = @_;
170 my $s = get_ssl_socket($port, $cert) or return;
171 http_get('/t', socket => $s);
172}
173
174sub get_ssl_socket {
175 my ($port, $cert) = @_;
176 my ($s);
177
178 eval {
179 local $SIG{ALRM} = sub { die "timeout\n" };
180 local $SIG{PIPE} = sub { die "sigpipe\n" };
181 alarm(2);
182 $s = IO::Socket::SSL->new(
183 Proto => 'tcp',
184 PeerAddr => '127.0.0.1',
185 PeerPort => port($port),
186 SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE(),
187 SSL_cert_file => "$d/$cert.crt",
188 SSL_key_file => "$d/$cert.key",
189 SSL_error_trap => sub { die $_[1] }
190 );
191 alarm(0);
192 };
193 alarm(0);
194
195 if ($@) {
196 log_in("died: $@");
197 return undef;
198 }
199
200 return $s;
201}
202
203###############################################################################