xref: /freebsd/crypto/openssl/test/recipes/25-test_verify.t (revision 4b15965daa99044daf184221b7c283bf7f2d7e66)
1#! /usr/bin/env perl
2# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.
3#
4# Licensed under the Apache License 2.0 (the "License").  You may not use
5# this file except in compliance with the License.  You can obtain a copy
6# in the file LICENSE in the source distribution or at
7# https://www.openssl.org/source/license.html
8
9
10use strict;
11use warnings;
12
13use Cwd qw(abs_path);
14use File::Spec::Functions qw/canonpath/;
15use File::Copy;
16use OpenSSL::Test qw/:DEFAULT srctop_file bldtop_dir ok_nofips with/;
17use OpenSSL::Test::Utils;
18
19setup("test_verify");
20
21my @certspath = qw(test certs);
22sub verify {
23    my ($cert, $purpose, $trusted, $untrusted, @opts) = @_;
24    my @args = qw(openssl verify -auth_level 1);
25    push(@args, "-purpose", $purpose) if $purpose ne "";
26    push(@args, @opts);
27    for (@$trusted) { push(@args, "-trusted", srctop_file(@certspath, "$_.pem")) }
28    for (@$untrusted) { push(@args, "-untrusted", srctop_file(@certspath, "$_.pem")) }
29    push(@args, srctop_file(@certspath, "$cert.pem"));
30    run(app([@args]));
31}
32
33plan tests => 203;
34
35# Canonical success
36ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
37   "accept compat trust");
38
39# Root CA variants
40ok(!verify("ee-cert", "sslserver", [qw(root-nonca)], [qw(ca-cert)]),
41   "fail trusted non-ca root");
42ok(!verify("ee-cert", "sslserver", [qw(nroot+serverAuth)], [qw(ca-cert)]),
43   "fail server trust non-ca root");
44ok(!verify("ee-cert", "sslserver", [qw(nroot+anyEKU)], [qw(ca-cert)]),
45   "fail wildcard trust non-ca root");
46ok(!verify("ee-cert", "sslserver", [qw(root-cert2)], [qw(ca-cert)]),
47   "fail wrong root key");
48ok(!verify("ee-cert", "sslserver", [qw(root-name2)], [qw(ca-cert)]),
49   "fail wrong root DN");
50
51# Critical extensions
52
53ok(verify("ee-cert-noncrit-unknown-ext", "", ["root-cert"], ["ca-cert"]),
54   "accept non-critical unknown extension");
55ok(!verify("ee-cert-crit-unknown-ext", "", ["root-cert"], ["ca-cert"]),
56   "reject critical unknown extension");
57ok(verify("ee-cert-ocsp-nocheck", "", ["root-cert"], ["ca-cert"]),
58   "accept critical OCSP No Check");
59
60# Explicit trust/purpose combinations
61#
62ok(verify("ee-cert", "sslserver", [qw(sroot-cert)], [qw(ca-cert)]),
63   "accept server purpose");
64ok(!verify("ee-cert", "sslserver", [qw(croot-cert)], [qw(ca-cert)]),
65   "fail client purpose"); # beware, questionable non-standard EKU check on trust anchor
66ok(verify("ee-cert", "sslserver", [qw(root+serverAuth)], [qw(ca-cert)]),
67   "accept server trust");
68ok(verify("ee-cert", "sslserver", [qw(sroot+serverAuth)], [qw(ca-cert)]),
69   "accept server trust with server purpose");
70ok(verify("ee-cert", "sslserver", [qw(croot+serverAuth)], [qw(ca-cert)]),
71   "accept server trust with client purpose");
72# Wildcard trust
73ok(verify("ee-cert", "sslserver", [qw(root+anyEKU)], [qw(ca-cert)]),
74   "accept wildcard trust");
75ok(verify("ee-cert", "sslserver", [qw(sroot+anyEKU)], [qw(ca-cert)]),
76   "accept wildcard trust with server purpose");
77ok(verify("ee-cert", "sslserver", [qw(croot+anyEKU)], [qw(ca-cert)]),
78   "accept wildcard trust with client purpose");
79# Inapplicable mistrust
80ok(verify("ee-cert", "sslserver", [qw(root-clientAuth)], [qw(ca-cert)]),
81   "accept client mistrust");
82ok(verify("ee-cert", "sslserver", [qw(sroot-clientAuth)], [qw(ca-cert)]),
83   "accept client mistrust with server purpose");
84ok(!verify("ee-cert", "sslserver", [qw(croot-clientAuth)], [qw(ca-cert)]),
85   "fail client mistrust with client purpose"); # beware, questionable non-standard EKU check on trust anchor
86# Inapplicable trust
87ok(!verify("ee-cert", "sslserver", [qw(root+clientAuth)], [qw(ca-cert)]),
88   "fail client trust");
89ok(!verify("ee-cert", "sslserver", [qw(sroot+clientAuth)], [qw(ca-cert)]),
90   "fail client trust with server purpose");
91ok(!verify("ee-cert", "sslserver", [qw(croot+clientAuth)], [qw(ca-cert)]),
92   "fail client trust with client purpose");
93# Server mistrust
94ok(!verify("ee-cert", "sslserver", [qw(root-serverAuth)], [qw(ca-cert)]),
95   "fail rejected EKU");
96ok(!verify("ee-cert", "sslserver", [qw(sroot-serverAuth)], [qw(ca-cert)]),
97   "fail server mistrust with server purpose");
98ok(!verify("ee-cert", "sslserver", [qw(croot-serverAuth)], [qw(ca-cert)]),
99   "fail server mistrust with client purpose");
100# Wildcard mistrust
101ok(!verify("ee-cert", "sslserver", [qw(root-anyEKU)], [qw(ca-cert)]),
102   "fail wildcard mistrust");
103ok(!verify("ee-cert", "sslserver", [qw(sroot-anyEKU)], [qw(ca-cert)]),
104   "fail wildcard mistrust with server purpose");
105ok(!verify("ee-cert", "sslserver", [qw(croot-anyEKU)], [qw(ca-cert)]),
106   "fail wildcard mistrust with client purpose");
107
108# Check that trusted-first is on by setting up paths to different roots
109# depending on whether the intermediate is the trusted or untrusted one.
110#
111ok(verify("ee-cert", "sslserver", [qw(root-serverAuth root-cert2 ca-root2)],
112          [qw(ca-cert)]),
113   "accept trusted-first path");
114ok(verify("ee-cert", "sslserver", [qw(root-cert root2+serverAuth ca-root2)],
115          [qw(ca-cert)]),
116   "accept trusted-first path with server trust");
117ok(!verify("ee-cert", "sslserver", [qw(root-cert root2-serverAuth ca-root2)],
118           [qw(ca-cert)]),
119   "fail trusted-first path with server mistrust");
120ok(!verify("ee-cert", "sslserver", [qw(root-cert root2+clientAuth ca-root2)],
121           [qw(ca-cert)]),
122   "fail trusted-first path with client trust");
123
124# CA variants
125ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-nonca)]),
126   "fail non-CA untrusted intermediate");
127ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-nonbc)]),
128   "fail non-CA untrusted intermediate");
129ok(!verify("ee-cert", "sslserver", [qw(root-cert ca-nonca)], []),
130   "fail non-CA trust-store intermediate");
131ok(!verify("ee-cert", "sslserver", [qw(root-cert ca-nonbc)], []),
132   "fail non-CA trust-store intermediate");
133ok(!verify("ee-cert", "sslserver", [qw(root-cert nca+serverAuth)], []),
134   "fail non-CA server trust intermediate");
135ok(!verify("ee-cert", "sslserver", [qw(root-cert nca+anyEKU)], []),
136   "fail non-CA wildcard trust intermediate");
137ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-cert2)]),
138   "fail wrong intermediate CA key");
139ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-name2)]),
140   "fail wrong intermediate CA DN");
141ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-root2)]),
142   "fail wrong intermediate CA issuer");
143ok(!verify("ee-cert", "sslserver", [], [qw(ca-cert)], "-partial_chain"),
144   "fail untrusted partial chain");
145ok(verify("ee-cert", "sslserver", [qw(ca-cert)], [], "-partial_chain"),
146   "accept trusted partial chain");
147ok(!verify("ee-cert", "sslserver", [qw(ca-expired)], [], "-partial_chain"),
148   "reject expired trusted partial chain"); # this check is beyond RFC 5280
149ok(!verify("ee-cert", "sslserver", [qw(root-expired)], [qw(ca-cert)]),
150   "reject expired trusted root"); # this check is beyond RFC 5280
151ok(verify("ee-cert", "sslserver", [qw(sca-cert)], [], "-partial_chain"),
152   "accept partial chain with server purpose");
153ok(!verify("ee-cert", "sslserver", [qw(cca-cert)], [], "-partial_chain"),
154   "fail partial chain with client purpose"); # beware, questionable non-standard EKU check on trust anchor
155ok(verify("ee-cert", "sslserver", [qw(ca+serverAuth)], [], "-partial_chain"),
156   "accept server trust partial chain");
157ok(verify("ee-cert", "sslserver", [qw(cca+serverAuth)], [], "-partial_chain"),
158   "accept server trust client purpose partial chain");
159ok(verify("ee-cert", "sslserver", [qw(ca-clientAuth)], [], "-partial_chain"),
160   "accept client mistrust partial chain");
161ok(verify("ee-cert", "sslserver", [qw(ca+anyEKU)], [], "-partial_chain"),
162   "accept wildcard trust partial chain");
163ok(!verify("ee-cert", "sslserver", [], [qw(ca+serverAuth)], "-partial_chain"),
164   "fail untrusted partial issuer with ignored server trust");
165ok(!verify("ee-cert", "sslserver", [qw(ca-serverAuth)], [], "-partial_chain"),
166   "fail server mistrust partial chain");
167ok(!verify("ee-cert", "sslserver", [qw(ca+clientAuth)], [], "-partial_chain"),
168   "fail client trust partial chain");
169ok(!verify("ee-cert", "sslserver", [qw(ca-anyEKU)], [], "-partial_chain"),
170   "fail wildcard mistrust partial chain");
171
172# We now test auxiliary trust even for intermediate trusted certs without
173# -partial_chain.  Note that "-trusted_first" is now always on and cannot
174# be disabled.
175ok(verify("ee-cert", "sslserver", [qw(root-cert ca+serverAuth)], [qw(ca-cert)]),
176   "accept server trust");
177ok(verify("ee-cert", "sslserver", [qw(root-cert ca+anyEKU)], [qw(ca-cert)]),
178   "accept wildcard trust");
179ok(verify("ee-cert", "sslserver", [qw(root-cert sca-cert)], [qw(ca-cert)]),
180   "accept server purpose");
181ok(verify("ee-cert", "sslserver", [qw(root-cert sca+serverAuth)], [qw(ca-cert)]),
182   "accept server trust and purpose");
183ok(verify("ee-cert", "sslserver", [qw(root-cert sca+anyEKU)], [qw(ca-cert)]),
184   "accept wildcard trust and server purpose");
185ok(verify("ee-cert", "sslserver", [qw(root-cert sca-clientAuth)], [qw(ca-cert)]),
186   "accept client mistrust and server purpose");
187ok(verify("ee-cert", "sslserver", [qw(root-cert cca+serverAuth)], [qw(ca-cert)]),
188   "accept server trust and client purpose");
189ok(verify("ee-cert", "sslserver", [qw(root-cert cca+anyEKU)], [qw(ca-cert)]),
190   "accept wildcard trust and client purpose");
191ok(!verify("ee-cert", "sslserver", [qw(root-cert cca-cert)], [qw(ca-cert)]),
192   "fail client purpose intermediate trusted"); # beware, questionable non-standard EKU check on trust anchor
193ok(!verify("ee-cert", "sslserver", [qw(root-cert ca-anyEKU)], [qw(ca-cert)]),
194   "fail wildcard mistrust");
195ok(!verify("ee-cert", "sslserver", [qw(root-cert ca-serverAuth)], [qw(ca-cert)]),
196   "fail server mistrust");
197ok(!verify("ee-cert", "sslserver", [qw(root-cert ca+clientAuth)], [qw(ca-cert)]),
198   "fail client trust");
199ok(!verify("ee-cert", "sslserver", [qw(root-cert sca+clientAuth)], [qw(ca-cert)]),
200   "fail client trust and server purpose");
201ok(!verify("ee-cert", "sslserver", [qw(root-cert cca+clientAuth)], [qw(ca-cert)]),
202   "fail client trust and client purpose");
203ok(!verify("ee-cert", "sslserver", [qw(root-cert cca-serverAuth)], [qw(ca-cert)]),
204   "fail server mistrust and client purpose");
205ok(!verify("ee-cert", "sslserver", [qw(root-cert cca-clientAuth)], [qw(ca-cert)]),
206   "fail client mistrust and client purpose");
207ok(!verify("ee-cert", "sslserver", [qw(root-cert sca-serverAuth)], [qw(ca-cert)]),
208   "fail server mistrust and server purpose");
209ok(!verify("ee-cert", "sslserver", [qw(root-cert sca-anyEKU)], [qw(ca-cert)]),
210   "fail wildcard mistrust and server purpose");
211ok(!verify("ee-cert", "sslserver", [qw(root-cert cca-anyEKU)], [qw(ca-cert)]),
212   "fail wildcard mistrust and client purpose");
213
214# EE variants
215ok(verify("ee-client", "sslclient", [qw(root-cert)], [qw(ca-cert)]),
216   "accept client chain");
217ok(!verify("ee-client", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
218   "fail server leaf purpose");
219ok(!verify("ee-cert", "sslclient", [qw(root-cert)], [qw(ca-cert)]),
220   "fail client leaf purpose");
221ok(!verify("ee-cert2", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
222   "fail wrong intermediate CA key");
223ok(!verify("ee-name2", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
224   "fail wrong intermediate CA DN");
225ok(!verify("ee-expired", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
226   "fail expired leaf");
227ok(verify("ee-cert", "sslserver", [qw(ee-cert)], [], "-partial_chain"),
228   "accept last-resort direct leaf match");
229ok(verify("ee-client", "sslclient", [qw(ee-client)], [], "-partial_chain"),
230   "accept last-resort direct leaf match");
231ok(!verify("ee-cert", "sslserver", [qw(ee-client)], [], "-partial_chain"),
232   "fail last-resort direct leaf non-match");
233ok(verify("ee-cert", "sslserver", [qw(ee+serverAuth)], [], "-partial_chain"),
234   "accept direct match with server trust");
235ok(!verify("ee-cert", "sslserver", [qw(ee-serverAuth)], [], "-partial_chain"),
236   "fail direct match with server mistrust");
237ok(verify("ee-client", "sslclient", [qw(ee+clientAuth)], [], "-partial_chain"),
238   "accept direct match with client trust");
239ok(!verify("ee-client", "sslclient", [qw(ee-clientAuth)], [], "-partial_chain"),
240   "reject direct match with client mistrust");
241ok(verify("ee-pathlen", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
242   "accept non-ca with pathlen:0 by default");
243ok(!verify("ee-pathlen", "sslserver", [qw(root-cert)], [qw(ca-cert)], "-x509_strict"),
244   "reject non-ca with pathlen:0 with strict flag");
245
246# EE veaiants wrt timestamp signing
247ok(verify("ee-timestampsign-CABforum", "timestampsign", [qw(root-cert)], [qw(ca-cert)]),
248   "accept timestampsign according to CAB forum");
249ok(!verify("ee-timestampsign-CABforum-noncritxku", "timestampsign", [qw(root-cert)], [qw(ca-cert)]),
250   "fail timestampsign according to CAB forum with extendedKeyUsage not critical");
251ok(!verify("ee-timestampsign-CABforum-serverauth", "timestampsign", [qw(root-cert)], [qw(ca-cert)]),
252   "fail timestampsign according to CAB forum with serverAuth");
253ok(!verify("ee-timestampsign-CABforum-anyextkeyusage", "timestampsign", [qw(root-cert)], [qw(ca-cert)]),
254   "fail timestampsign according to CAB forum with anyExtendedKeyUsage");
255ok(!verify("ee-timestampsign-CABforum-crlsign", "timestampsign", [qw(root-cert)], [qw(ca-cert)]),
256   "fail timestampsign according to CAB forum with cRLSign");
257ok(!verify("ee-timestampsign-CABforum-keycertsign", "timestampsign", [qw(root-cert)], [qw(ca-cert)]),
258   "fail timestampsign according to CAB forum with keyCertSign");
259ok(verify("ee-timestampsign-rfc3161", "timestampsign", [qw(root-cert)], [qw(ca-cert)]),
260   "accept timestampsign according to RFC 3161");
261ok(!verify("ee-timestampsign-rfc3161-noncritxku", "timestampsign", [qw(root-cert)], [qw(ca-cert)]),
262   "fail timestampsign according to RFC 3161 with extendedKeyUsage not critical");
263ok(verify("ee-timestampsign-rfc3161-digsig", "timestampsign", [qw(root-cert)], [qw(ca-cert)]),
264   "accept timestampsign according to RFC 3161 with digitalSignature");
265
266# EE variants wrt code signing
267ok(verify("ee-codesign", "codesign", [qw(root-cert)], [qw(ca-cert)]),
268   "accept codesign");
269ok(!verify("ee-codesign-serverauth", "codesign", [qw(root-cert)], [qw(ca-cert)]),
270   "fail codesign with additional serverAuth");
271ok(!verify("ee-codesign-anyextkeyusage", "codesign", [qw(root-cert)], [qw(ca-cert)]),
272   "fail codesign with additional anyExtendedKeyUsage");
273ok(!verify("ee-codesign-crlsign", "codesign", [qw(root-cert)], [qw(ca-cert)]),
274   "fail codesign with additional cRLSign");
275ok(!verify("ee-codesign-keycertsign", "codesign", [qw(root-cert)], [qw(ca-cert)]),
276   "fail codesign with additional keyCertSign");
277ok(!verify("ee-codesign-noncritical", "codesign", [qw(root-cert)], [qw(ca-cert)]),
278   "fail codesign without critical KU");
279ok(!verify("ee-cert", "codesign", [qw(root-cert)], [qw(ca-cert)]),
280   "fail sslserver as code sign");
281ok(!verify("ee-client", "codesign", [qw(root-cert)], [qw(ca-cert)]),
282   "fail sslclient as codesign");
283ok(!verify("ee-timestampsign-CABforum", "codesign", [qw(root-cert)], [qw(ca-cert)]),
284   "fail timestampsign according to CAB forum as codesign");
285ok(!verify("ee-timestampsign-rfc3161", "codesign", [qw(root-cert)], [qw(ca-cert)]),
286   "fail timestampsign according to RFC 3161 as codesign");
287
288# Proxy certificates
289ok(!verify("pc1-cert", "sslclient", [qw(root-cert)], [qw(ee-client ca-cert)]),
290   "fail to accept proxy cert without -allow_proxy_certs");
291ok(verify("pc1-cert", "sslclient", [qw(root-cert)], [qw(ee-client ca-cert)],
292          "-allow_proxy_certs"),
293   "accept proxy cert 1");
294ok(verify("pc2-cert", "sslclient", [qw(root-cert)], [qw(pc1-cert ee-client ca-cert)],
295          "-allow_proxy_certs"),
296   "accept proxy cert 2");
297ok(!verify("bad-pc3-cert", "sslclient", [qw(root-cert)], [qw(pc1-cert ee-client ca-cert)],
298          "-allow_proxy_certs"),
299   "fail proxy cert with incorrect subject");
300ok(!verify("bad-pc4-cert", "sslclient", [qw(root-cert)], [qw(pc1-cert ee-client ca-cert)],
301          "-allow_proxy_certs"),
302   "fail proxy cert with incorrect pathlen");
303ok(verify("pc5-cert", "sslclient", [qw(root-cert)], [qw(pc1-cert ee-client ca-cert)],
304          "-allow_proxy_certs"),
305   "accept proxy cert missing proxy policy");
306ok(!verify("pc6-cert", "sslclient", [qw(root-cert)], [qw(pc1-cert ee-client ca-cert)],
307          "-allow_proxy_certs"),
308   "failed proxy cert where last CN was added as a multivalue RDN component");
309
310# Security level tests
311ok(verify("ee-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "2"),
312   "accept RSA 2048 chain at auth level 2");
313ok(!verify("ee-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "3"),
314   "reject RSA 2048 root at auth level 3");
315ok(verify("ee-cert", "", ["root-cert-768"], ["ca-cert-768i"], "-auth_level", "0"),
316   "accept RSA 768 root at auth level 0");
317ok(!verify("ee-cert", "", ["root-cert-768"], ["ca-cert-768i"]),
318   "reject RSA 768 root at auth level 1");
319ok(verify("ee-cert-768i", "", ["root-cert"], ["ca-cert-768"], "-auth_level", "0"),
320   "accept RSA 768 intermediate at auth level 0");
321ok(!verify("ee-cert-768i", "", ["root-cert"], ["ca-cert-768"]),
322   "reject RSA 768 intermediate at auth level 1");
323ok(verify("ee-cert-768", "", ["root-cert"], ["ca-cert"], "-auth_level", "0"),
324   "accept RSA 768 leaf at auth level 0");
325ok(!verify("ee-cert-768", "", ["root-cert"], ["ca-cert"]),
326   "reject RSA 768 leaf at auth level 1");
327#
328ok(verify("ee-cert", "", ["root-cert-md5"], ["ca-cert"], "-auth_level", "2"),
329   "accept md5 self-signed TA at auth level 2");
330ok(verify("ee-cert", "", ["ca-cert-md5-any"], [], "-auth_level", "2"),
331   "accept md5 intermediate TA at auth level 2");
332ok(verify("ee-cert", "", ["root-cert"], ["ca-cert-md5"], "-auth_level", "0"),
333   "accept md5 intermediate at auth level 0");
334ok(!verify("ee-cert", "", ["root-cert"], ["ca-cert-md5"]),
335   "reject md5 intermediate at auth level 1");
336ok(verify("ee-cert-md5", "", ["root-cert"], ["ca-cert"], "-auth_level", "0"),
337   "accept md5 leaf at auth level 0");
338ok(!verify("ee-cert-md5", "", ["root-cert"], ["ca-cert"]),
339   "reject md5 leaf at auth level 1");
340
341# Explicit vs named curve tests
342SKIP: {
343    skip "EC is not supported by this OpenSSL build", 7
344        if disabled("ec");
345    ok(!verify("ee-cert-ec-explicit", "", ["root-cert"],
346               ["ca-cert-ec-named"]),
347        "reject explicit curve leaf with named curve intermediate");
348    ok(!verify("ee-cert-ec-named-explicit", "", ["root-cert"],
349               ["ca-cert-ec-explicit"]),
350        "reject named curve leaf with explicit curve intermediate");
351    ok(verify("ee-cert-ec-named-named", "", ["root-cert"],
352              ["ca-cert-ec-named"]),
353        "accept named curve leaf with named curve intermediate");
354    ok(verify("ee-cert-ec-sha3-224", "", ["root-cert"], ["ca-cert-ec-named"], ),
355        "accept cert generated with EC and SHA3-224");
356    ok(verify("ee-cert-ec-sha3-256", "", ["root-cert"], ["ca-cert-ec-named"], ),
357        "accept cert generated with EC and SHA3-256");
358    ok(verify("ee-cert-ec-sha3-384", "", ["root-cert"], ["ca-cert-ec-named"], ),
359        "accept cert generated with EC and SHA3-384");
360    ok(verify("ee-cert-ec-sha3-512", "", ["root-cert"], ["ca-cert-ec-named"], ),
361        "accept cert generated with EC and SHA3-512");
362}
363# Same as above but with base provider used for decoding
364SKIP: {
365    my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
366    my $provconf = srctop_file("test", "fips-and-base.cnf");
367    my $provpath = bldtop_dir("providers");
368    my @prov = ("-provider-path", $provpath);
369
370    skip "EC is not supported or FIPS is disabled", 7
371        if disabled("ec") || $no_fips;
372
373    $ENV{OPENSSL_CONF} = $provconf;
374
375    ok(verify("ee-cert-ec-sha3-224", "", ["root-cert"], ["ca-cert-ec-named"], @prov),
376        "accept cert generated with EC and SHA3-224 w/fips");
377    ok(verify("ee-cert-ec-sha3-256", "", ["root-cert"], ["ca-cert-ec-named"], @prov),
378        "accept cert generated with EC and SHA3-256 w/fips");
379    ok(verify("ee-cert-ec-sha3-384", "", ["root-cert"], ["ca-cert-ec-named"], @prov),
380        "accept cert generated with EC and SHA3-384 w/fips");
381    ok(verify("ee-cert-ec-sha3-512", "", ["root-cert"], ["ca-cert-ec-named"], @prov),
382        "accept cert generated with EC and SHA3-512 w/fips");
383
384    delete $ENV{OPENSSL_CONF};
385
386    run(test(["fips_version_test", "-config", $provconf, ">3.0.0"]),
387             capture => 1, statusvar => \my $exit);
388    skip "FIPS provider version is too old", 3
389        if !$exit;
390
391    $ENV{OPENSSL_CONF} = $provconf;
392
393    ok(!verify("ee-cert-ec-explicit", "", ["root-cert"],
394               ["ca-cert-ec-named"], @prov),
395        "reject explicit curve leaf with named curve intermediate w/fips");
396    ok(!verify("ee-cert-ec-named-explicit", "", ["root-cert"],
397               ["ca-cert-ec-explicit"], @prov),
398        "reject named curve leaf with explicit curve intermediate w/fips");
399    ok(verify("ee-cert-ec-named-named", "", ["root-cert"],
400              ["ca-cert-ec-named"], @prov),
401        "accept named curve leaf with named curve intermediate w/fips");
402    delete $ENV{OPENSSL_CONF};
403}
404
405# Depth tests, note the depth limit bounds the number of CA certificates
406# between the trust-anchor and the leaf, so, for example, with a root->ca->leaf
407# chain, depth = 1 is sufficient, but depth == 0 is not.
408#
409ok(verify("ee-cert", "", ["root-cert"], ["ca-cert"], "-verify_depth", "2"),
410   "accept chain with verify_depth 2");
411ok(verify("ee-cert", "", ["root-cert"], ["ca-cert"], "-verify_depth", "1"),
412   "accept chain with verify_depth 1");
413ok(!verify("ee-cert", "", ["root-cert"], ["ca-cert"], "-verify_depth", "0"),
414   "reject chain with verify_depth 0");
415ok(verify("ee-cert", "", ["ca-cert-md5-any"], [], "-verify_depth", "0"),
416   "accept md5 intermediate TA with verify_depth 0");
417
418# Name Constraints tests.
419
420ok(verify("alt1-cert", "", ["root-cert"], ["ncca1-cert"], ),
421   "Name Constraints everything permitted");
422
423ok(verify("alt2-cert", "", ["root-cert"], ["ncca2-cert"], ),
424   "Name Constraints nothing excluded");
425
426ok(verify("alt3-cert", "", ["root-cert"], ["ncca1-cert", "ncca3-cert"], ),
427   "Name Constraints nested test all permitted");
428
429ok(verify("goodcn1-cert", "", ["root-cert"], ["ncca1-cert"], ),
430   "Name Constraints CNs permitted");
431
432ok(verify("goodcn2-cert", "", ["root-cert"], ["ncca1-cert"], ),
433   "Name Constraints CNs permitted - no SAN extension");
434
435ok(!verify("badcn1-cert", "", ["root-cert"], ["ncca1-cert"], ),
436   "Name Constraints CNs not permitted");
437
438ok(!verify("badalt1-cert", "", ["root-cert"], ["ncca1-cert"], ),
439   "Name Constraints hostname not permitted");
440
441ok(!verify("badalt2-cert", "", ["root-cert"], ["ncca2-cert"], ),
442   "Name Constraints hostname excluded");
443
444ok(!verify("badalt3-cert", "", ["root-cert"], ["ncca1-cert"], ),
445   "Name Constraints email address not permitted");
446
447ok(!verify("badalt4-cert", "", ["root-cert"], ["ncca1-cert"], ),
448   "Name Constraints subject email address not permitted");
449
450ok(!verify("badalt5-cert", "", ["root-cert"], ["ncca1-cert"], ),
451   "Name Constraints IP address not permitted");
452
453ok(!verify("badalt6-cert", "", ["root-cert"], ["ncca1-cert"], ),
454   "Name Constraints CN hostname not permitted");
455
456ok(!verify("badalt7-cert", "", ["root-cert"], ["ncca1-cert"], ),
457   "Name Constraints CN BMPSTRING hostname not permitted");
458
459ok(!verify("badalt8-cert", "", ["root-cert"], ["ncca1-cert", "ncca3-cert"], ),
460   "Name constraints nested DNS name not permitted 1");
461
462ok(!verify("badalt9-cert", "", ["root-cert"], ["ncca1-cert", "ncca3-cert"], ),
463   "Name constraints nested DNS name not permitted 2");
464
465ok(!verify("badalt10-cert", "", ["root-cert"], ["ncca1-cert", "ncca3-cert"], ),
466   "Name constraints nested DNS name excluded");
467
468ok(!verify("bad-othername-cert", "", ["root-cert"], ["nccaothername-cert"], ),
469   "CVE-2022-4203 type confusion test");
470
471ok(verify("nc-uri-cert", "", ["root-cert"], ["ncca4-cert"], ),
472   "Name constraints URI with userinfo");
473
474#Check that we get the expected failure return code
475with({ exit_checker => sub { return shift == 2; } },
476     sub {
477         ok(verify("bad-othername-namec", "", ["bad-othername-namec-inter"], [],
478                   "-partial_chain", "-attime", "1623060000"),
479            "Name constraints bad othername name constraint");
480     });
481
482ok(verify("ee-pss-sha1-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "0"),
483    "Accept PSS signature using SHA1 at auth level 0");
484
485ok(verify("ee-pss-sha256-cert", "", ["root-cert"], ["ca-cert"], ),
486    "CA with PSS signature using SHA256");
487
488ok(!verify("ee-pss-sha1-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "1"),
489    "Reject PSS signature using SHA1 and auth level 1");
490
491ok(verify("ee-pss-sha256-cert", "", ["root-cert"], ["ca-cert"], "-auth_level", "2"),
492    "PSS signature using SHA256 and auth level 2");
493
494ok(verify("ee-pss-cert", "", ["root-cert"], ["ca-pss-cert"], ),
495    "CA PSS signature");
496ok(!verify("ee-pss-wrong1.5-cert", "", ["root-cert"], ["ca-pss-cert"], ),
497    "CA producing regular PKCS#1 v1.5 signature with PSA-PSS key");
498
499ok(!verify("many-names1", "", ["many-constraints"], ["many-constraints"], ),
500    "Too many names and constraints to check (1)");
501ok(!verify("many-names2", "", ["many-constraints"], ["many-constraints"], ),
502    "Too many names and constraints to check (2)");
503ok(!verify("many-names3", "", ["many-constraints"], ["many-constraints"], ),
504    "Too many names and constraints to check (3)");
505
506ok(verify("some-names1", "", ["many-constraints"], ["many-constraints"], ),
507    "Not too many names and constraints to check (1)");
508ok(verify("some-names2", "", ["many-constraints"], ["many-constraints"], ),
509    "Not too many names and constraints to check (2)");
510ok(verify("some-names2", "", ["many-constraints"], ["many-constraints"], ),
511    "Not too many names and constraints to check (3)");
512ok(verify("root-cert-rsa2", "", ["root-cert-rsa2"], [], "-check_ss_sig"),
513    "Public Key Algorithm rsa instead of rsaEncryption");
514
515ok(verify("ee-self-signed", "", ["ee-self-signed"], [], "-attime", "1593565200"),
516   "accept trusted self-signed EE cert excluding key usage keyCertSign");
517ok(verify("ee-ss-with-keyCertSign", "", ["ee-ss-with-keyCertSign"], []),
518   "accept trusted self-signed EE cert with key usage keyCertSign also when strict");
519
520SKIP: {
521    skip "Ed25519 is not supported by this OpenSSL build", 6
522        if disabled("ecx");
523
524    # ED25519 certificate from draft-ietf-curdle-pkix-04
525    ok(verify("ee-ed25519", "", ["root-ed25519"], []),
526       "accept X25519 EE cert issued by trusted Ed25519 self-signed CA cert");
527
528    ok(!verify("ee-ed25519", "", ["root-ed25519"], [], "-x509_strict"),
529       "reject X25519 EE cert in strict mode since AKID is missing");
530
531    ok(!verify("root-ed25519", "", ["ee-ed25519"], []),
532       "fail Ed25519 CA and EE certs swapped");
533
534    ok(verify("root-ed25519", "", ["root-ed25519"], []),
535       "accept trusted Ed25519 self-signed CA cert");
536
537    ok(!verify("ee-ed25519", "", ["ee-ed25519"], []),
538       "fail trusted Ed25519-signed self-issued X25519 cert");
539
540    ok(verify("ee-ed25519", "", ["ee-ed25519"], [], "-partial_chain"),
541       "accept last-resort direct leaf match Ed25519-signed self-issued cert");
542
543}
544
545SKIP: {
546    skip "SM2 is not supported by this OpenSSL build", 2 if disabled("sm2");
547
548   ok_nofips(verify("sm2", "", ["sm2-ca-cert"], [], "-vfyopt", "distid:1234567812345678"),
549       "SM2 ID test");
550   ok_nofips(verify("sm2", "", ["sm2-ca-cert"], [], "-vfyopt", "hexdistid:31323334353637383132333435363738"),
551       "SM2 hex ID test");
552}
553
554# Mixed content tests
555my $cert_file = srctop_file('test', 'certs', 'root-cert.pem');
556my $rsa_file = srctop_file('test', 'certs', 'key-pass-12345.pem');
557
558SKIP: {
559    my $certplusrsa_file = 'certplusrsa.pem';
560    my $certplusrsa;
561
562    skip "Couldn't create certplusrsa.pem", 1
563        unless ( open $certplusrsa, '>', $certplusrsa_file
564                 and copy($cert_file, $certplusrsa)
565                 and copy($rsa_file, $certplusrsa)
566                 and close $certplusrsa );
567
568    ok(run(app([ qw(openssl verify -trusted), $certplusrsa_file, $cert_file ])),
569       'Mixed cert + key file test');
570}
571
572SKIP: {
573    my $rsapluscert_file = 'rsapluscert.pem';
574    my $rsapluscert;
575
576    skip "Couldn't create rsapluscert.pem", 1
577        unless ( open $rsapluscert, '>', $rsapluscert_file
578                 and copy($rsa_file, $rsapluscert)
579                 and copy($cert_file, $rsapluscert)
580                 and close $rsapluscert );
581
582    ok(run(app([ qw(openssl verify -trusted), $rsapluscert_file, $cert_file ])),
583       'Mixed key + cert file test');
584}
585
586# Certificate Policies
587ok(verify("ee-cert-policies", "", ["root-cert"], ["ca-pol-cert"],
588          "-policy_check", "-policy", "1.3.6.1.4.1.16604.998855.1",
589          "-explicit_policy"),
590   "Certificate policy");
591
592ok(!verify("ee-cert-policies-bad", "", ["root-cert"], ["ca-pol-cert"],
593           "-policy_check", "-policy", "1.3.6.1.4.1.16604.998855.1",
594           "-explicit_policy"),
595   "Bad certificate policy");
596
597# CAstore option
598my $rootcertname = "root-cert";
599my $rootcert = srctop_file(@certspath, "${rootcertname}.pem");
600sub vfy_root { verify($rootcertname, "", [], [], @_) }
601ok(vfy_root("-CAfile", $rootcert), "CAfile");
602ok(vfy_root("-CAstore", $rootcert), "CAstore");
603ok(vfy_root("-CAstore", $rootcert, "-CAfile", $rootcert), "CAfile and existing CAstore");
604ok(!vfy_root("-CAstore", "non-existing", "-CAfile", $rootcert), "CAfile and non-existing CAstore");
605SKIP: {
606    skip "file names with colons aren't supported on Windows and VMS", 2
607        if $^O =~ /^(MsWin32|VMS)$/;
608    my $foo_file = "foo:cert.pem";
609    copy($rootcert, $foo_file);
610    ok(vfy_root("-CAstore", $foo_file), "CAstore foo:file");
611}
612my $foo_file = "cert.pem";
613copy($rootcert, $foo_file);
614ok(vfy_root("-CAstore", $foo_file), "CAstore foo:file");
615my $abs_cert = abs_path($rootcert);
616# Windows file: URIs should have a path part starting with a slash, i.e.
617# file://authority/C:/what/ever/foo.pem and file:///C:/what/ever/foo.pem
618# file://C:/what/ever/foo.pem is non-standard and may not be accepted.
619# See RFC 8089 for details.
620$abs_cert = "/" . $abs_cert if ($^O eq "MSWin32");
621ok(vfy_root("-CAstore", "file://".$abs_cert), "CAstore file:///path");
622ok(vfy_root("-CAstore", "file://localhost".$abs_cert), "CAstore file://localhost/path");
623ok(!vfy_root("-CAstore", "file://otherhost".$abs_cert), "CAstore file://otherhost/path");
624