blob: e6f44d9684032c770896a155512652c53a521dce [file] [log] [blame]
Bob Beckbc97b7a2023-04-18 08:35:15 -06001// Copyright 2015 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BSSL_PKI_VERIFY_CERTIFICATE_CHAIN_H_
6#define BSSL_PKI_VERIFY_CERTIFICATE_CHAIN_H_
7
8#include "fillins/openssl_util.h"
9#include <set>
10
11
12#include "cert_errors.h"
13#include "parsed_certificate.h"
14#include "signature_verify_cache.h"
15#include "input.h"
16#include <openssl/evp.h>
17
18namespace bssl {
19
20namespace der {
21struct GeneralizedTime;
22}
23
24struct CertificateTrust;
25
26// The key purpose (extended key usage) to check for during verification.
27enum class KeyPurpose {
28 ANY_EKU,
29 SERVER_AUTH,
30 CLIENT_AUTH,
31 SERVER_AUTH_STRICT, // Skip ANY_EKU when checking, require EKU present in
32 // certificate.
33 CLIENT_AUTH_STRICT, // Skip ANY_EKU when checking, require EKU present in
34 // certificate.
35};
36
37enum class InitialExplicitPolicy {
38 kFalse,
39 kTrue,
40};
41
42enum class InitialPolicyMappingInhibit {
43 kFalse,
44 kTrue,
45};
46
47enum class InitialAnyPolicyInhibit {
48 kFalse,
49 kTrue,
50};
51
52// VerifyCertificateChainDelegate exposes delegate methods used when verifying a
53// chain.
54class OPENSSL_EXPORT VerifyCertificateChainDelegate {
55 public:
56 // Implementations should return true if |signature_algorithm| is allowed for
57 // certificate signing, false otherwise. When returning false implementations
58 // can optionally add high-severity errors to |errors| with details on why it
59 // was rejected.
60 virtual bool IsSignatureAlgorithmAcceptable(
61 SignatureAlgorithm signature_algorithm,
62 CertErrors* errors) = 0;
63
64 // Implementations should return true if |public_key| is acceptable. This is
65 // called for each certificate in the chain, including the target certificate.
66 // When returning false implementations can optionally add high-severity
67 // errors to |errors| with details on why it was rejected.
68 //
69 // |public_key| can be assumed to be non-null.
70 virtual bool IsPublicKeyAcceptable(EVP_PKEY* public_key,
71 CertErrors* errors) = 0;
72
73 // This is called during verification to obtain a pointer to a signature
74 // verification cache if one exists. nullptr may be returned indicating there
75 // is no verification cache.
76 virtual SignatureVerifyCache* GetVerifyCache() = 0;
77
78 virtual ~VerifyCertificateChainDelegate();
79};
80
81// VerifyCertificateChain() verifies an ordered certificate path in accordance
82// with RFC 5280's "Certification Path Validation" algorithm (section 6).
83//
84// -----------------------------------------
85// Deviations from RFC 5280
86// -----------------------------------------
87//
88// * If Extended Key Usage appears on intermediates, it is treated as
89// a restriction on subordinate certificates.
90// * No revocation checking is performed.
91//
92// -----------------------------------------
93// Additional responsibilities of the caller
94// -----------------------------------------
95//
96// After successful path verification, the caller is responsible for
97// subsequently checking:
98//
99// * The end-entity's KeyUsage before using its SPKI.
100// * The end-entity's name/subjectAltName. Name constraints from intermediates
101// will have already been applied, so it is sufficient to check the
102// end-entity for a match. The caller MUST NOT check hostnames on the
103// commonName field because this implementation does not apply dnsName
104// constraints on commonName.
105//
106// ---------
107// Inputs
108// ---------
109//
110// certs:
111// A non-empty chain of DER-encoded certificates, listed in the
112// "forward" direction. The first certificate is the target
113// certificate to verify, and the last certificate has trustedness
114// given by |last_cert_trust| (generally a trust anchor).
115//
116// * certs[0] is the target certificate to verify.
117// * certs[i+1] holds the certificate that issued cert_chain[i].
118// * certs[N-1] the root certificate
119//
120// Note that THIS IS NOT identical in meaning to the same named
121// "certs" input defined in RFC 5280 section 6.1.1.a. The differences
122// are:
123//
124// * The order of certificates is reversed
125// * In RFC 5280 "certs" DOES NOT include the trust anchor
126//
127// last_cert_trust:
128// Trustedness of |certs.back()|. The trustedness of |certs.back()|
129// MUST BE decided by the caller -- this function takes it purely as
130// an input. Moreover, the CertificateTrust can be used to specify
131// trust anchor constraints.
132//
133// This combined with |certs.back()| (the root certificate) fills a
134// similar role to "trust anchor information" defined in RFC 5280
135// section 6.1.1.d.
136//
137// delegate:
138// |delegate| must be non-null. It is used to answer policy questions such
139// as whether a signature algorithm is acceptable, or a public key is strong
140// enough.
141//
142// time:
143// The UTC time to use for expiration checks. This is equivalent to
144// the input from RFC 5280 section 6.1.1:
145//
146// (b) the current date/time.
147//
148// required_key_purpose:
149// The key purpose that the target certificate needs to be valid for.
150//
151// user_initial_policy_set:
152// This is equivalent to the same named input in RFC 5280 section
153// 6.1.1:
154//
155// (c) user-initial-policy-set: A set of certificate policy
156// identifiers naming the policies that are acceptable to the
157// certificate user. The user-initial-policy-set contains the
158// special value any-policy if the user is not concerned about
159// certificate policy.
160//
161// initial_policy_mapping_inhibit:
162// This is equivalent to the same named input in RFC 5280 section
163// 6.1.1:
164//
165// (e) initial-policy-mapping-inhibit, which indicates if policy
166// mapping is allowed in the certification path.
167//
168// initial_explicit_policy:
169// This is equivalent to the same named input in RFC 5280 section
170// 6.1.1:
171//
172// (f) initial-explicit-policy, which indicates if the path must be
173// valid for at least one of the certificate policies in the
174// user-initial-policy-set.
175//
176// initial_any_policy_inhibit:
177// This is equivalent to the same named input in RFC 5280 section
178// 6.1.1:
179//
180// (g) initial-any-policy-inhibit, which indicates whether the
181// anyPolicy OID should be processed if it is included in a
182// certificate.
183//
184// ---------
185// Outputs
186// ---------
187//
188// user_constrained_policy_set:
189// Can be null. If non-null, |user_constrained_policy_set| will be filled
190// with the matching policies (intersected with user_initial_policy_set).
191// This is equivalent to the same named output in X.509 section 10.2.
192// Note that it is OK for this to point to input user_initial_policy_set.
193//
194// errors:
195// Must be non-null. The set of errors/warnings encountered while
196// validating the path are appended to this structure. If verification
197// failed, then there is guaranteed to be at least 1 high severity error
198// written to |errors|.
199//
200// -------------------------
201// Trust Anchor constraints
202// -------------------------
203//
204// Conceptually, VerifyCertificateChain() sets RFC 5937's
205// "enforceTrustAnchorConstraints" to true.
206//
207// One specifies trust anchor constraints using the |last_cert_trust|
208// parameter in conjunction with extensions appearing in |certs.back()|.
209//
210// The trust anchor |certs.back()| is always passed as a certificate to
211// this function, however the manner in which that certificate is
212// interpreted depends on |last_cert_trust|:
213//
214// TRUSTED_ANCHOR:
215//
216// No properties from the root certificate, other than its Subject and
217// SPKI, are checked during verification. This is the usual
218// interpretation for a "trust anchor".
219//
220// enforce_anchor_expiry=true:
221//
222// The validity period of the root is checked, in addition to Subject and SPKI.
223//
224// enforce_anchor_constraints=true:
225//
226// Only a subset of extensions and properties from the certificate are checked.
227// In general, constraints encoded by extensions are only enforced if the
228// extension is present.
229//
230// * Signature: No
231// * Validity (expiration): No
232// * Key usage: Yes
233// * Extended key usage: Yes (required if required_key_purpose is STRICT)
234// * Basic constraints: Yes
235// * Name constraints: Yes
236// * Certificate policies: Yes
237// * Policy Mappings: Yes
238// * inhibitAnyPolicy: Yes
239// * PolicyConstraints: Yes
240//
241// The presence of any other unrecognized extension marked as critical fails
242// validation.
243OPENSSL_EXPORT void VerifyCertificateChain(
244 const ParsedCertificateList& certs,
245 const CertificateTrust& last_cert_trust,
246 VerifyCertificateChainDelegate* delegate,
247 const der::GeneralizedTime& time,
248 KeyPurpose required_key_purpose,
249 InitialExplicitPolicy initial_explicit_policy,
250 const std::set<der::Input>& user_initial_policy_set,
251 InitialPolicyMappingInhibit initial_policy_mapping_inhibit,
252 InitialAnyPolicyInhibit initial_any_policy_inhibit,
253 std::set<der::Input>* user_constrained_policy_set,
254 CertPathErrors* errors);
255
256// Returns true if `cert` is self-signed. Returns false `cert` is not
257// self-signed or there was an error. If `errors` is non-null, it will contain
258// additional information about the problem. If `cache` is non-null, it will be
259// used to cache the signature verification step.
260OPENSSL_EXPORT bool VerifyCertificateIsSelfSigned(const ParsedCertificate& cert,
261 SignatureVerifyCache* cache,
262 CertErrors* errors);
263
264} // namespace net
265
266#endif // BSSL_PKI_VERIFY_CERTIFICATE_CHAIN_H_