1# -*- mode: perl; -*-
2
3## SSL test configurations
4
5package ssltests;
6
7use strict;
8use warnings;
9
10use OpenSSL::Test;
11use OpenSSL::Test::Utils qw(anydisabled disabled);
12setup("no_test_here");
13
14our $fips_mode;
15
16my @protocols;
17my @is_disabled = (0);
18
19# We test version-flexible negotiation (undef) and each protocol version.
20if ($fips_mode) {
21    @protocols = (undef, "TLSv1.2", "DTLSv1.2");
22    push @is_disabled, anydisabled("tls1_2", "dtls1_2");
23} else {
24    @protocols = (undef, "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2", "DTLSv1", "DTLSv1.2");
25    push @is_disabled, anydisabled("ssl3", "tls1", "tls1_1", "tls1_2", "dtls1", "dtls1_2");
26}
27
28our @tests = ();
29
30srand(4);
31sub randcase {
32    my ($names) = @_;
33    my @ret;
34    foreach my $name (split(/:/, $names)) {
35        my ($alg, $rest) = split(/(?=[+])/, $name, 2);
36        $alg =~ s{([a-zA-Z])}{chr(ord($1)^(int(rand(2.0)) * 32))}eg;
37        push @ret, $alg . ($rest // "");
38    }
39    return join(":", @ret);
40}
41
42sub generate_tests() {
43    foreach (0..$#protocols) {
44        my $protocol = $protocols[$_];
45        my $protocol_name = $protocol || "flex";
46        my $caalert;
47        my $method;
48        my $sctpenabled = 0;
49        if (!$is_disabled[$_]) {
50            if ($protocol_name eq "SSLv3") {
51                $caalert = "BadCertificate";
52            } else {
53                $caalert = "UnknownCA";
54            }
55            if ($protocol_name =~ m/^DTLS/) {
56                $method = "DTLS";
57                $sctpenabled = 1 if !disabled("sctp");
58            }
59            my $clihash;
60            my $clisigtype;
61            my $clisigalgs;
62            # TODO(TLS1.3) add TLSv1.3 versions
63            if ($protocol_name eq "TLSv1.2") {
64                $clihash = "SHA256";
65                $clisigtype = "RSA";
66                $clisigalgs = "SHA256+".randcase("RSA");
67            }
68            for (my $sctp = 0; $sctp <= $sctpenabled; $sctp++) {
69                # Sanity-check simple handshake.
70                push @tests, {
71                    name => "server-auth-${protocol_name}"
72                            .($sctp ? "-sctp" : ""),
73                    server => {
74                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
75                        "MinProtocol" => $protocol,
76                        "MaxProtocol" => $protocol
77                    },
78                    client => {
79                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
80                        "MinProtocol" => $protocol,
81                        "MaxProtocol" => $protocol
82                    },
83                    test   => {
84                        "ExpectedResult" => "Success",
85                        "Method" => $method,
86                    },
87                };
88                $tests[-1]{"test"}{"UseSCTP"} = "Yes" if $sctp;
89
90                # Handshake with client cert requested but not required or received.
91                push @tests, {
92                    name => "client-auth-${protocol_name}-request"
93                            .($sctp ? "-sctp" : ""),
94                    server => {
95                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
96                        "MinProtocol" => $protocol,
97                        "MaxProtocol" => $protocol,
98                        "VerifyMode" => "Request"
99                    },
100                    client => {
101                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
102                        "MinProtocol" => $protocol,
103                        "MaxProtocol" => $protocol
104                    },
105                    test   => {
106                        "ExpectedResult" => "Success",
107                        "Method" => $method,
108                    },
109                };
110                $tests[-1]{"test"}{"UseSCTP"} = "Yes" if $sctp;
111
112                # Handshake with client cert required but not present.
113                push @tests, {
114                    name => "client-auth-${protocol_name}-require-fail"
115                            .($sctp ? "-sctp" : ""),
116                    server => {
117                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
118                        "MinProtocol" => $protocol,
119                        "MaxProtocol" => $protocol,
120                        "VerifyCAFile" => test_pem("root-cert.pem"),
121                        "VerifyMode" => "Require",
122                    },
123                    client => {
124                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
125                        "MinProtocol" => $protocol,
126                        "MaxProtocol" => $protocol
127                    },
128                    test   => {
129                        "ExpectedResult" => "ServerFail",
130                        "ExpectedServerAlert" =>
131                        ($protocol_name eq "flex"
132                            && !disabled("tls1_3")
133                            && (!disabled("ec") || !disabled("dh")))
134                        ? "CertificateRequired" : "HandshakeFailure",
135                        "Method" => $method,
136                    },
137                };
138                $tests[-1]{"test"}{"UseSCTP"} = "Yes" if $sctp;
139
140                # Successful handshake with client authentication.
141                push @tests, {
142                    name => "client-auth-${protocol_name}-require"
143                             .($sctp ? "-sctp" : ""),
144                    server => {
145                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
146                        "MinProtocol" => $protocol,
147                        "MaxProtocol" => $protocol,
148                        "ClientSignatureAlgorithms" => $clisigalgs,
149                        "VerifyCAFile" => test_pem("root-cert.pem"),
150                        "VerifyMode" => "Request",
151                    },
152                    client => {
153                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
154                        "MinProtocol" => $protocol,
155                        "MaxProtocol" => $protocol,
156                        "Certificate" => test_pem("ee-client-chain.pem"),
157                        "PrivateKey"  => test_pem("ee-key.pem"),
158                    },
159                    test   => {
160                        "ExpectedResult" => "Success",
161                        "ExpectedClientCertType" => "RSA",
162                        "ExpectedClientSignType" => $clisigtype,
163                        "ExpectedClientSignHash" => $clihash,
164                        "ExpectedClientCANames" => "empty",
165                        "Method" => $method,
166                    },
167                };
168                $tests[-1]{"test"}{"UseSCTP"} = "Yes" if $sctp;
169
170                # Successful handshake with client RSA-PSS cert, StrictCertCheck
171                push @tests, {
172                    name => "client-auth-${protocol_name}-rsa-pss"
173                             .($sctp ? "-sctp" : ""),
174                    server => {
175                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
176                        "MinProtocol" => $protocol,
177                        "MaxProtocol" => $protocol,
178                        "ClientCAFile" => test_pem("rootcert.pem"),
179                        "VerifyCAFile" => test_pem("rootcert.pem"),
180                        "VerifyMode" => "Require",
181                    },
182                    client => {
183                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
184                        "MinProtocol" => $protocol,
185                        "MaxProtocol" => $protocol,
186                        "Certificate" => test_pem("client-pss-restrict-cert.pem"),
187                        "PrivateKey"  => test_pem("client-pss-restrict-key.pem"),
188                        "Options" => "StrictCertCheck",
189                    },
190                    test   => {
191                        "ExpectedResult" => "Success",
192                        "ExpectedClientCertType" => "RSA-PSS",
193                        "ExpectedClientCANames" => test_pem("rootcert.pem"),
194                        "Method" => $method,
195                    },
196                } if $protocol_name eq "TLSv1.2" || $protocol_name eq "flex";
197
198                # Failed handshake with client RSA-PSS cert, StrictCertCheck, bad CA
199                push @tests, {
200                    name => "client-auth-${protocol_name}-rsa-pss-bad"
201                             .($sctp ? "-sctp" : ""),
202                    server => {
203                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
204                        "MinProtocol" => $protocol,
205                        "MaxProtocol" => $protocol,
206                        "ClientCAFile" => test_pem("rootCA.pem"),
207                        "VerifyCAFile" => test_pem("rootCA.pem"),
208                        "VerifyMode" => "Require",
209                    },
210                    client => {
211                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
212                        "MinProtocol" => $protocol,
213                        "MaxProtocol" => $protocol,
214                        "Certificate" => test_pem("client-pss-restrict-cert.pem"),
215                        "PrivateKey"  => test_pem("client-pss-restrict-key.pem"),
216                        "Options" => "StrictCertCheck",
217                    },
218                    test   => {
219                        "ExpectedResult" => "ServerFail",
220                        "ExpectedServerAlert" =>
221                        ($protocol_name eq "flex"
222                            && !disabled("tls1_3")
223                            && (!disabled("ec") || !disabled("dh")))
224                        ? "CertificateRequired" : "HandshakeFailure",
225                        "Method" => $method,
226                    },
227                } if $protocol_name eq "TLSv1.2" || $protocol_name eq "flex";
228
229                # Successful handshake with client authentication non-empty names
230                push @tests, {
231                    name => "client-auth-${protocol_name}-require-non-empty-names"
232                            .($sctp ? "-sctp" : ""),
233                    server => {
234                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
235                        "MinProtocol" => $protocol,
236                        "MaxProtocol" => $protocol,
237                        "ClientSignatureAlgorithms" => $clisigalgs,
238                        "ClientCAFile" => test_pem("root-cert.pem"),
239                        "VerifyCAFile" => test_pem("root-cert.pem"),
240                        "VerifyMode" => "Request",
241                    },
242                    client => {
243                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
244                        "MinProtocol" => $protocol,
245                        "MaxProtocol" => $protocol,
246                        "Certificate" => test_pem("ee-client-chain.pem"),
247                        "PrivateKey"  => test_pem("ee-key.pem"),
248                    },
249                    test   => {
250                        "ExpectedResult" => "Success",
251                        "ExpectedClientCertType" => "RSA",
252                        "ExpectedClientSignType" => $clisigtype,
253                        "ExpectedClientSignHash" => $clihash,
254                        "ExpectedClientCANames" => test_pem("root-cert.pem"),
255                        "Method" => $method,
256                    },
257                };
258                $tests[-1]{"test"}{"UseSCTP"} = "Yes" if $sctp;
259
260                # Handshake with client authentication but without the root certificate.
261                push @tests, {
262                    name => "client-auth-${protocol_name}-noroot"
263                            .($sctp ? "-sctp" : ""),
264                    server => {
265                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
266                        "MinProtocol" => $protocol,
267                        "MaxProtocol" => $protocol,
268                        "VerifyMode" => "Require",
269                    },
270                    client => {
271                        "CipherString" => "DEFAULT:\@SECLEVEL=0",
272                        "MinProtocol" => $protocol,
273                        "MaxProtocol" => $protocol,
274                        "Certificate" => test_pem("ee-client-chain.pem"),
275                        "PrivateKey"  => test_pem("ee-key.pem"),
276                    },
277                    test   => {
278                        "ExpectedResult" => "ServerFail",
279                        "ExpectedServerAlert" => $caalert,
280                        "Method" => $method,
281                    },
282                };
283                $tests[-1]{"test"}{"UseSCTP"} = "Yes" if $sctp;
284            }
285        }
286    }
287}
288
289generate_tests();
290