380e54ac697072f9756b15f03d6ecd66ff90ebad
[openssl.git] / test / recipes / 80-test_ssl.t
1 #! /usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use POSIX;
7 use File::Spec;
8 use File::Copy;
9 use Test::More 0.96;
10 use OpenSSL::Test qw/:DEFAULT with top_file/;
11
12 setup("test_ssl");
13
14 my $digest = "-sha1";
15 my @reqcmd = ("openssl", "req");
16 my @x509cmd = ("openssl", "x509", $digest);
17 my @verifycmd = ("openssl", "verify");
18 my $dummycnf = top_file("apps", "openssl.cnf");
19
20 my $CAkey = "keyCA.ss";
21 my $CAcert="certCA.ss";
22 my $CAserial="certCA.srl";
23 my $CAreq="reqCA.ss";
24 my $CAconf=top_file("test","CAss.cnf");
25 my $CAreq2="req2CA.ss"; # temp
26
27 my $Uconf=top_file("test","Uss.cnf");
28 my $Ukey="keyU.ss";
29 my $Ureq="reqU.ss";
30 my $Ucert="certU.ss";
31
32 my $P1conf=top_file("test","P1ss.cnf");
33 my $P1key="keyP1.ss";
34 my $P1req="reqP1.ss";
35 my $P1cert="certP1.ss";
36 my $P1intermediate="tmp_intP1.ss";
37
38 my $P2conf=top_file("test","P2ss.cnf");
39 my $P2key="keyP2.ss";
40 my $P2req="reqP2.ss";
41 my $P2cert="certP2.ss";
42 my $P2intermediate="tmp_intP2.ss";
43
44 plan tests =>
45     1                           # For testss
46     + 1                         # For ssltest -test_cipherlist
47     + 8                         # For the first testssl
48     + 8 * 4 * 4                 # For the first testsslproxy (16 times testssl)
49     + 8 * 4 * 4                 # For the second testsslproxy (16 times testssl)
50     ;
51
52 subtest 'test_ss' => sub {
53     if (testss()) {
54         open OUT, ">", "intP1.ss";
55         copy($CAcert, \*OUT); copy($Ucert, \*OUT);
56         close OUT;
57
58         open OUT, ">", "intP2.ss";
59         copy($CAcert, \*OUT); copy($Ucert, \*OUT); copy($P1cert, \*OUT);
60         close OUT;
61     }
62 };
63
64 my $check = ok(run(test(["ssltest","-test_cipherlist"])), "running ssltest");
65
66   SKIP: {
67       skip "ssltest ended with error, skipping the rest", 3
68           if !$check;
69
70       note('test_ssl -- key U');
71       testssl("keyU.ss", $Ucert, $CAcert);
72
73       note('test_ssl -- key P1');
74       testsslproxy("keyP1.ss", "certP1.ss", "intP1.ss");
75
76       note('test_ssl -- key P2');
77       testsslproxy("keyP2.ss", "certP2.ss", "intP2.ss");
78     }
79
80 # -----------
81 # subtest functions
82 sub testss {
83     open RND, ">>", ".rnd";
84     print RND "string to make the random number generator think it has entropy";
85     close RND;
86
87     my @req_new;
88     if (run(app(["openssl", "no-rsa"], stdout => undef))) {
89         @req_new = ("-newkey",
90                     "dsa:".File::Spec->catfile("..", "apps", "dsa512.pem"));
91     } else {
92         @req_new = ("-new");
93     }
94
95     plan tests => 15;
96
97   SKIP: {
98       skip 'failure', 14 unless
99           ok(run(app([@reqcmd, "-config", $CAconf,
100                       "-out", $CAreq, "-keyout", $CAkey,
101                       @req_new])),
102              'make cert request');
103
104       skip 'failure', 13 unless
105           ok(run(app([@x509cmd, "-CAcreateserial", "-in", $CAreq, "-days", "30",
106                       "-req", "-out", $CAcert, "-signkey", $CAkey,
107                       "-extfile", $CAconf, "-extensions", "v3_ca"],
108                      stdout => "err.ss")),
109              'convert request into self-signed cert');
110
111       skip 'failure', 12 unless
112           ok(run(app([@x509cmd, "-in", $CAcert,
113                       "-x509toreq", "-signkey", $CAkey, "-out", $CAreq2],
114                      stdout => "err.ss")),
115              'convert cert into a cert request');
116
117       skip 'failure', 11 unless
118           ok(run(app([@reqcmd, "-config", $dummycnf,
119                       "-verify", "-in", $CAreq, "-noout"])),
120              'verify request 1');
121
122
123       skip 'failure', 10 unless
124           ok(run(app([@reqcmd, "-config", $dummycnf,
125                       "-verify", "-in", $CAreq2, "-noout"])),
126              'verify request 2');
127
128       skip 'failure', 9 unless
129           ok(run(app([@verifycmd, "-CAfile", $CAcert, $CAcert])),
130              'verify signature');
131
132       skip 'failure', 8 unless
133           ok(run(app([@reqcmd, "-config", $Uconf,
134                       "-out", $Ureq, "-keyout", $Ukey, @req_new],
135                      stdout => "err.ss")),
136              'make a user cert request');
137
138       skip 'failure', 7 unless
139           ok(run(app([@x509cmd, "-CAcreateserial", "-in", $Ureq, "-days", "30",
140                       "-req", "-out", $Ucert,
141                       "-CA", $CAcert, "-CAkey", $CAkey, "-CAserial", $CAserial,
142                       "-extfile", $Uconf, "-extensions", "v3_ee"],
143                      stdout => "err.ss"))
144              && run(app([@verifycmd, "-CAfile", $CAcert, $Ucert])),
145              'sign user cert request');
146
147       skip 'failure', 6 unless
148           ok(run(app([@x509cmd,
149                       "-subject", "-issuer", "-startdate", "-enddate",
150                       "-noout", "-in", $Ucert])),
151              'Certificate details');
152
153
154       skip 'failure', 5 unless
155           ok(run(app([@reqcmd, "-config", $P1conf,
156                       "-out", $P1req, "-keyout", $P1key, @req_new],
157                      stdout => "err.ss")),
158              'make a proxy cert request');
159
160
161       skip 'failure', 4 unless
162           ok(run(app([@x509cmd, "-CAcreateserial", "-in", $P1req, "-days", "30",
163                       "-req", "-out", $P1cert,
164                       "-CA", $Ucert, "-CAkey", $Ukey,
165                       "-extfile", $P1conf, "-extensions", "v3_proxy"],
166                      stdout => "err.ss")),
167              'sign proxy with user cert');
168
169       copy($Ucert, $P1intermediate);
170       run(app([@verifycmd, "-CAfile", $CAcert,
171                "-untrusted", $P1intermediate, $P1cert]));
172       ok(run(app([@x509cmd,
173                   "-subject", "-issuer", "-startdate", "-enddate",
174                   "-noout", "-in", $P1cert])),
175          'Certificate details');
176
177       skip 'failure', 2 unless
178           ok(run(app([@reqcmd, "-config", $P2conf,
179                       "-out", $P2req, "-keyout", $P2key,
180                       @req_new],
181                      stdout => "err.ss")),
182              'make another proxy cert request');
183
184
185       skip 'failure', 1 unless
186           ok(run(app([@x509cmd, "-CAcreateserial", "-in", $P2req, "-days", "30",
187                       "-req", "-out", $P2cert,
188                       "-CA", $P1cert, "-CAkey", $P1key,
189                       "-extfile", $P2conf, "-extensions", "v3_proxy"],
190                      stdout => "err.ss")),
191              'sign second proxy cert request with the first proxy cert');
192
193
194       open OUT, ">", $P2intermediate;
195       copy($Ucert, \*OUT); copy($P1cert, \*OUT);
196       close OUT;
197       run(app([@verifycmd, "-CAfile", $CAcert,
198                "-untrusted", $P2intermediate, $P2cert]));
199       ok(run(app([@x509cmd,
200                   "-subject", "-issuer", "-startdate", "-enddate",
201                   "-noout", "-in", $P2cert])),
202          'Certificate details');
203     }
204 }
205
206 sub testssl {
207     my $key = shift || top_file("apps","server.pem");
208     my $cert = shift || top_file("apps","server.pem");
209     my $CAtmp = shift;
210     my @CA = $CAtmp ? ("-CAfile", $CAtmp) : ("-CApath", top_dir("certs"));
211     my @extra = @_;
212
213     my @ssltest = ("ssltest",
214                    "-key", $key, "-cert", $cert,
215                    "-c_key", $key, "-c_cert", $cert);
216
217     my $serverinfo = top_file("test","serverinfo.pem");
218
219     my $dsa_cert = 0;
220     if (grep /DSA Public Key/, run(app(["openssl", "x509", "-in", $cert,
221                                         "-text", "-noout"]), capture => 1)) {
222         $dsa_cert = 1;
223     }
224
225
226     # plan tests => 7;
227
228     subtest 'standard SSL tests' => sub {
229         ######################################################################
230         plan tests => 27;
231
232         ok(run(test([@ssltest, "-ssl3", @extra])),
233            'test sslv3');
234         ok(run(test([@ssltest, "-ssl3", "-server_auth", @CA, @extra])),
235            'test sslv3 with server authentication');
236         ok(run(test([@ssltest, "-ssl3", "-client_auth", @CA, @extra])),
237            'test sslv3 with client authentication');
238         ok(run(test([@ssltest, "-ssl3", "-server_auth", "-client_auth", @CA, @extra])),
239            'test sslv3 with both server and client authentication');
240         ok(run(test([@ssltest, @extra])),
241            'test sslv2/sslv3');
242         ok(run(test([@ssltest, "-server_auth", @CA, @extra])),
243            'test sslv2/sslv3 with server authentication');
244         ok(run(test([@ssltest, "-client_auth", @CA, @extra])),
245            'test sslv2/sslv3 with client authentication');
246         ok(run(test([@ssltest, "-server_auth", "-client_auth", @CA, @extra])),
247            'test sslv2/sslv3 with both server and client authentication');
248         ok(run(test([@ssltest, "-bio_pair", "-ssl3", @extra])),
249            'test sslv3 via BIO pair');
250         ok(run(test([@ssltest, "-bio_pair", "-ssl3", "-server_auth", @CA, @extra])),
251            'test sslv3 with server authentication via BIO pair');
252         ok(run(test([@ssltest, "-bio_pair", "-ssl3", "-client_auth", @CA, @extra])),
253            'test sslv3 with client authentication via BIO pair');
254         ok(run(test([@ssltest, "-bio_pair", "-ssl3", "-server_auth", "-client_auth", @CA, @extra])),
255            'test sslv3 with both server and client authentication via BIO pair');
256         ok(run(test([@ssltest, "-bio_pair", @extra])),
257            'test sslv2/sslv3 via BIO pair');
258         ok(run(test([@ssltest, "-dtls1", @extra])),
259            'test dtlsv1');
260         ok(run(test([@ssltest, "-dtls1", "-server_auth", @CA, @extra])),
261            'test dtlsv1 with server authentication');
262         ok(run(test([@ssltest, "-dtls1", "-client_auth", @CA, @extra])),
263            'test dtlsv1 with client authentication');
264         ok(run(test([@ssltest, "-dtls1", "-server_auth", "-client_auth", @CA, @extra])),
265            'test dtlsv1 with both server and client authentication');
266         ok(run(test([@ssltest, "-dtls12", @extra])),
267            'test dtlsv1.2');
268         ok(run(test([@ssltest, "-dtls12", "-server_auth", @CA, @extra])),
269            'test dtlsv1.2 with server authentication');
270         ok(run(test([@ssltest, "-dtls12", "-client_auth", @CA, @extra])),
271            'test dtlsv1.2 with client authentication');
272         ok(run(test([@ssltest, "-dtls12", "-server_auth", "-client_auth", @CA, @extra])),
273            'test dtlsv1.2 with both server and client authentication');
274         {
275           SKIP: {
276               skip "skipping test of sslv2/sslv3 w/o (EC)DHE test", 1 if $dsa_cert;
277
278               ok(run(test([@ssltest, "-bio_pair", "-no_dhe", "-no_ecdhe", @extra])),
279                  'test sslv2/sslv3 w/o (EC)DHE via BIO pair');
280             }
281         }
282         ok(run(test([@ssltest, "-bio_pair", "-dhe1024dsa", "-v", @extra])),
283            'test sslv2/sslv3 with 1024bit DHE via BIO pair');
284         ok(run(test([@ssltest, "-bio_pair", "-server_auth", @CA, @extra])),
285            'test sslv2/sslv3 with server authentication');
286         ok(run(test([@ssltest, "-bio_pair", "-client_auth", @CA, @extra])),
287            'test sslv2/sslv3 with client authentication via BIO pair');
288         ok(run(test([@ssltest, "-bio_pair", "-server_auth", "-client_auth", @CA, @extra])),
289            'test sslv2/sslv3 with both client and server authentication via BIO pair');
290         ok(run(test([@ssltest, "-bio_pair", "-server_auth", "-client_auth", "-app_verify", @CA, @extra])),
291            'test sslv2/sslv3 with both client and server authentication via BIO pair and app verify');
292     };
293
294     subtest "Testing ciphersuites" => sub {
295
296         my $no_dh = run(app(["openssl", "no-dhparam"], stdout => undef));
297         my $no_ec = run(app(["openssl", "no-ec"], stdout => undef));
298
299         my @protocols = ("TLSv1.2", "SSLv3");
300         my $protocolciphersuitcount = 0;
301         my %ciphersuites =
302             map { my @c =
303                       map { split(/:/, $_) }
304                       map { run(app(["openssl",
305                                      "ciphers", "$_"]),
306                                 capture => 1);
307                       }
308                       ( "RSA+$_",
309                         $no_dh ? () : "EDH+aRSA+$_:-EXP",
310                         $no_ec ? () : "EECDH+aRSA+$_:-EXP" );
311                   chomp @c;
312                   $protocolciphersuitcount += scalar @c;
313                   $_ => [ @c ] } @protocols;
314
315         plan tests => $protocolciphersuitcount + ($no_dh ? 0 : 2);
316
317         foreach my $protocol (@protocols) {
318             note "Testing ciphersuites for $protocol";
319             foreach my $cipher (@{$ciphersuites{$protocol}}) {
320                 ok(run(test([@ssltest, "-cipher", $cipher,
321                              $protocol eq "SSLv3" ? ("-ssl3") : ()])),
322                    "Testing $cipher");
323             }
324             if (!$no_dh) {
325                 is(run(test([@ssltest,
326                              "-s_cipher", "EDH",
327                              "-c_cipher", 'EDH:@SECLEVEL=1',
328                              "-dhe512",
329                              $protocol eq "SSLv3" ? ("-ssl3") : ()])), 0,
330                    "testing connection with weak DH, expecting failure");
331             }
332         }
333     };
334
335     subtest 'RSA/(EC)DHE/PSK tests' => sub {
336         ######################################################################
337
338         plan tests => 5;
339
340         {
341           SKIP: {
342               skip "skipping anonymous DH tests", 1
343                   if (run(app(["openssl", "no-dhparam"], stdout => undef)));
344
345               ok(run(test([@ssltest, "-v", "-bio_pair", "-tls1", "-cipher", "ADH", "-dhe1024dsa", "-num", "10", "-f", "-time", @extra])),
346                  'test tlsv1 with 1024bit anonymous DH, multiple handshakes');
347             }
348         }
349
350         {
351           SKIP: {
352               skip "skipping RSA tests", 2
353                   if (run(app(["openssl", "no-rsa"], stdout => undef)));
354
355               ok(run(test(["ssltest", "-v", "-bio_pair", "-tls1", "-cert", top_file("apps","server2.pem"), "-no_dhe", "-no_ecdhe", "-num", "10", "-f", "-time", @extra])),
356                  'test tlsv1 with 1024bit RSA, no (EC)DHE, multiple handshakes');
357
358               skip "skipping RSA+DHE tests", 1
359                   if (run(app(["openssl", "no-dhparam"], stdout => undef)));
360
361               ok(run(test(["ssltest", "-v", "-bio_pair", "-tls1", "-cert", top_file("apps","server2.pem"), "-dhe1024dsa", "-num", "10", "-f", "-time", @extra])),
362                  'test tlsv1 with 1024bit RSA, 1024bit DHE, multiple handshakes');
363             }
364         }
365         ok(run(test([@ssltest, "-tls1", "-cipher", "PSK", "-psk", "abc123", @extra])),
366            'test tls1 with PSK');
367
368         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-cipher", "PSK", "-psk", "abc123", @extra])),
369            'test tls1 with PSK via BIO pair');
370     };
371
372     subtest 'Next Protocol Negotiation Tests' => sub {
373         ######################################################################
374
375         plan tests => 7;
376
377         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-npn_client"])));
378         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-npn_server"])));
379         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-npn_server_reject"])));
380         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-npn_client", "-npn_server_reject"])));
381         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-npn_client", "-npn_server"])));
382         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-npn_client", "-npn_server", "-num", "2"])));
383         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-npn_client", "-npn_server", "-num", "2", "-reuse"])));
384     };
385
386     subtest 'Custom Extension tests' => sub {
387         ######################################################################
388
389         plan tests => 1;
390
391         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-custom_ext"])),
392            'test tls1 with custom extensions');
393     };
394
395     subtest 'Serverinfo tests' => sub {
396         ######################################################################
397
398         plan tests => 5;
399
400         note('echo test tls1 with serverinfo');
401         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-serverinfo_file", $serverinfo])));
402         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-serverinfo_file", $serverinfo, "-serverinfo_sct"])));
403         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-serverinfo_file", $serverinfo, "-serverinfo_tack"])));
404         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-serverinfo_file", $serverinfo, "-serverinfo_sct", "-serverinfo_tack"])));
405         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-custom_ext", "-serverinfo_file", $serverinfo, "-serverinfo_sct", "-serverinfo_tack"])));
406     };
407
408     subtest 'ALPN tests' => sub {
409         ######################################################################
410
411         plan tests => 12;
412
413         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-alpn_client", "foo", "-alpn_server", "bar"])));
414         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-alpn_client", "foo", "-alpn_server", "foo", "-alpn_expected", "foo"])));
415         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-alpn_client", "foo,bar", "-alpn_server", "foo", "-alpn_expected", "foo"])));
416         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-alpn_client", "bar,foo", "-alpn_server", "foo", "-alpn_expected", "foo"])));
417         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-alpn_client", "bar,foo", "-alpn_server", "foo,bar", "-alpn_expected", "foo"])));
418         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-alpn_client", "bar,foo", "-alpn_server", "bar,foo", "-alpn_expected", "bar"])));
419         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-alpn_client", "foo,bar", "-alpn_server", "bar,foo", "-alpn_expected", "bar"])));
420         ok(run(test([@ssltest, "-bio_pair", "-tls1", "-alpn_client", "baz", "-alpn_server", "bar,foo"])));
421
422         {
423           SKIP: {
424               skip "skipping SRP tests", 4
425                   if run(app(["openssl", "no-srp"], stdout => undef));
426
427               ok(run(test([@ssltest, "-tls1", "-cipher", "SRP", "-srpuser", "test", "-srppass", "abc123"])),
428                  'test tls1 with SRP');
429
430               ok(run(test([@ssltest, "-bio_pair", "-tls1", "-cipher", "SRP", "-srpuser", "test", "-srppass", "abc123"])),
431                  'test tls1 with SRP via BIO pair');
432
433               ok(run(test([@ssltest, "-tls1", "-cipher", "aSRP", "-srpuser", "test", "-srppass", "abc123"])),
434                  'test tls1 with SRP auth');
435
436               ok(run(test([@ssltest, "-bio_pair", "-tls1", "-cipher", "aSRP", "-srpuser", "test", "-srppass", "abc123"])),
437                  'test tls1 with SRP auth via BIO pair');
438             }
439         }
440     };
441
442     subtest 'Multi-buffer tests' => sub {
443         ######################################################################
444
445         plan tests => 2;
446
447         {
448           SKIP: {
449               skip "skipping multi-buffer tests", 2
450                   if @extra || (POSIX::uname())[4] ne "x86_64";
451               ok(run(test([@ssltest, "-cipher", "AES128-SHA",    "-bytes", "8m"])));
452               ok(run(test([@ssltest, "-cipher", "AES128-SHA256", "-bytes", "8m"])));
453             }
454         }
455     };
456 }
457
458 sub testsslproxy {
459     my ($a1, $a2, $a3, @rest) = @_;
460
461     # plan tests => 16;
462
463     note('Testing a lot of proxy conditions.');
464     note('Some of them may turn out being invalid, which is fine.');
465     foreach my $auth (('A', 'B', 'C', 'BC')) {
466         foreach my $cond (('A', 'B', 'C', 'A|B&!C')) {
467             # Exit code 3 is when ssltest couldn't parse the condition
468             with({ exit_checker => sub { return shift == 3 ? 0 : 1; } },
469                  sub {
470                      testssl($a1, $a2, $a3,
471                              "-proxy", "-proxy_auth", $auth,
472                              "-proxy_cond", $cond);
473                  });
474         }
475     }
476 }