blob: b1f03faa4ad2aab99c729d7602a3e38c333e8d9e [file] [log] [blame]
Bob Beckbc97b7a2023-04-18 08:35:15 -06001// Copyright 2016 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_PATH_BUILDER_H_
6#define BSSL_PKI_PATH_BUILDER_H_
7
8#include "fillins/openssl_util.h"
9#include <memory>
10#include <vector>
11
12
13
14#include "cert_errors.h"
15#include "parsed_certificate.h"
16#include "trust_store.h"
17#include "verify_certificate_chain.h"
18#include "input.h"
19#include "parse_values.h"
20
21namespace bssl {
22
23namespace der {
24struct GeneralizedTime;
25}
26
27class CertPathBuilder;
28class CertPathIter;
29class CertIssuerSource;
30
31// Base class for custom data that CertPathBuilderDelegate can attach to paths.
32class OPENSSL_EXPORT CertPathBuilderDelegateData {
33 public:
34 virtual ~CertPathBuilderDelegateData() = default;
35};
36
37// Represents a single candidate path that was built or is being processed.
38//
39// This is used both to represent valid paths, as well as invalid/partial ones.
40//
41// Consumers must use |IsValid()| to test whether the
42// CertPathBuilderResultPath is the result of a successful certificate
43// verification.
44struct OPENSSL_EXPORT CertPathBuilderResultPath {
45 CertPathBuilderResultPath();
46 ~CertPathBuilderResultPath();
47
48 // Returns true if the candidate path is valid. A "valid" path is one which
49 // chains to a trusted root, and did not have any high severity errors added
50 // to it during certificate verification.
51 bool IsValid() const;
52
53 // Returns the chain's root certificate or nullptr if the chain doesn't
54 // chain to a trust anchor.
55 const ParsedCertificate* GetTrustedCert() const;
56
57 // Path in the forward direction:
58 //
59 // certs[0] is the target certificate
60 // certs[i] was issued by certs[i+1]
61 // certs.back() is the root certificate (which may or may not be trusted).
62 ParsedCertificateList certs;
63
64 // Describes the trustedness of the final certificate in the chain,
65 // |certs.back()|
66 //
67 // For result paths where |IsValid()|, the final certificate is trusted.
68 // However for failed or partially constructed paths the final certificate may
69 // not be a trust anchor.
70 CertificateTrust last_cert_trust;
71
72 // The set of policies that the certificate is valid for (of the
73 // subset of policies user requested during verification).
74 std::set<der::Input> user_constrained_policy_set;
75
76 // Slot for per-path data that may set by CertPathBuilderDelegate. The
77 // specific type is chosen by the delegate. Can be nullptr when unused.
78 std::unique_ptr<CertPathBuilderDelegateData> delegate_data;
79
80 // The set of errors and warnings associated with this path (bucketed
81 // per-certificate). Note that consumers should always use |IsValid()| to
82 // determine validity of the CertPathBuilderResultPath, and not just inspect
83 // |errors|.
84 CertPathErrors errors;
85};
86
87// CertPathBuilderDelegate controls policies for certificate verification and
88// path building.
89class OPENSSL_EXPORT CertPathBuilderDelegate
90 : public VerifyCertificateChainDelegate {
91 public:
92 // This is called during path building on candidate paths which have already
93 // been run through RFC 5280 verification. |path| may already have errors
94 // and warnings set on it. Delegates can "reject" a candidate path from path
95 // building by adding high severity errors.
96 virtual void CheckPathAfterVerification(const CertPathBuilder& path_builder,
97 CertPathBuilderResultPath* path) = 0;
98
99 // This is called during path building in between attempts to build candidate
100 // paths. Delegates can cause path building to stop and return indicating
101 // the deadline was exceeded by returning true from this function.
102 virtual bool IsDeadlineExpired() = 0;
103};
104
105// Checks whether a certificate is trusted by building candidate paths to trust
106// anchors and verifying those paths according to RFC 5280. Each instance of
107// CertPathBuilder is used for a single verification.
108//
109// WARNING: This implementation is currently experimental. Consult an OWNER
110// before using it.
111class OPENSSL_EXPORT CertPathBuilder {
112 public:
113 // Provides the overall result of path building. This includes the paths that
114 // were attempted.
115 struct OPENSSL_EXPORT Result {
116 Result();
117 Result(Result&&);
118
119 Result(const Result&) = delete;
120 Result& operator=(const Result&) = delete;
121
122 ~Result();
123 Result& operator=(Result&&);
124
125 // Returns true if there was a valid path.
126 bool HasValidPath() const;
127
128 // Returns true if any of the attempted paths contain |error_id|.
129 bool AnyPathContainsError(CertErrorId error_id) const;
130
131 // Returns the CertPathBuilderResultPath for the best valid path, or nullptr
132 // if there was none.
133 const CertPathBuilderResultPath* GetBestValidPath() const;
134
135 // Returns the best CertPathBuilderResultPath or nullptr if there was none.
136 const CertPathBuilderResultPath* GetBestPathPossiblyInvalid() const;
137
138 // List of paths that were attempted and the result for each.
139 std::vector<std::unique_ptr<CertPathBuilderResultPath>> paths;
140
141 // Index into |paths|. Before use, |paths.empty()| must be checked.
142 // NOTE: currently the definition of "best" is fairly limited. Valid is
143 // better than invalid, but otherwise nothing is guaranteed.
144 size_t best_result_index = 0;
145
146 // The iteration count reached by path building.
147 uint32_t iteration_count = 0;
148
149 // The max depth seen while path building.
150 uint32_t max_depth_seen = 0;
151
152 // True if the search stopped because it exceeded the iteration limit
153 // configured with |SetIterationLimit|.
154 bool exceeded_iteration_limit = false;
155
156 // True if the search stopped because delegate->IsDeadlineExpired() returned
157 // true.
158 bool exceeded_deadline = false;
159 };
160
161 // Creates a CertPathBuilder that attempts to find a path from |cert| to a
162 // trust anchor in |trust_store| and is valid at |time|.
163 //
164 // The caller must keep |trust_store| and |delegate| valid for the lifetime
165 // of the CertPathBuilder.
166 //
167 // See VerifyCertificateChain() for a more detailed explanation of the
168 // same-named parameters not defined below.
169 //
170 // * |delegate|: Must be non-null. The delegate is called at various points in
171 // path building to verify specific parts of certificates or the
172 // final chain. See CertPathBuilderDelegate and
173 // VerifyCertificateChainDelegate for more information.
174 CertPathBuilder(std::shared_ptr<const ParsedCertificate> cert,
175 TrustStore* trust_store,
176 CertPathBuilderDelegate* delegate,
177 const der::GeneralizedTime& time,
178 KeyPurpose key_purpose,
179 InitialExplicitPolicy initial_explicit_policy,
180 const std::set<der::Input>& user_initial_policy_set,
181 InitialPolicyMappingInhibit initial_policy_mapping_inhibit,
182 InitialAnyPolicyInhibit initial_any_policy_inhibit);
183
184 CertPathBuilder(const CertPathBuilder&) = delete;
185 CertPathBuilder& operator=(const CertPathBuilder&) = delete;
186
187 ~CertPathBuilder();
188
189 // Adds a CertIssuerSource to provide intermediates for use in path building.
190 // Multiple sources may be added. Must not be called after Run is called.
191 // The |*cert_issuer_source| must remain valid for the lifetime of the
192 // CertPathBuilder.
193 //
194 // (If no issuer sources are added, the target certificate will only verify if
195 // it is a trust anchor or is directly signed by a trust anchor.)
196 void AddCertIssuerSource(CertIssuerSource* cert_issuer_source);
197
198 // Sets a limit to the number of times to repeat the process of considering a
199 // new intermediate over all potential paths. Setting |limit| to 0 disables
200 // the iteration limit, which is the default.
201 void SetIterationLimit(uint32_t limit);
202
203 // Sets a limit to the number of certificates to be added in a path from leaf
204 // to root. Setting |limit| to 0 disables this limit, which is the default.
205 void SetDepthLimit(uint32_t limit);
206
207 // If |explore_all_paths| is false (the default), path building will stop as
208 // soon as a valid path is found. If |explore_all_paths| is true, path
209 // building will continue until all possible paths have been exhausted (or
210 // iteration limit / deadline is exceeded).
211 void SetExploreAllPaths(bool explore_all_paths);
212
213 // Executes verification of the target certificate.
214 //
215 // Run must not be called more than once on each CertPathBuilder instance.
216 Result Run();
217
218 private:
219 void AddResultPath(std::unique_ptr<CertPathBuilderResultPath> result_path);
220
221 // |out_result_| may be referenced by other members, so should be initialized
222 // first.
223 Result out_result_;
224
225 std::unique_ptr<CertPathIter> cert_path_iter_;
226 CertPathBuilderDelegate * delegate_;
227 const der::GeneralizedTime time_;
228 const KeyPurpose key_purpose_;
229 const InitialExplicitPolicy initial_explicit_policy_;
230 const std::set<der::Input> user_initial_policy_set_;
231 const InitialPolicyMappingInhibit initial_policy_mapping_inhibit_;
232 const InitialAnyPolicyInhibit initial_any_policy_inhibit_;
233 uint32_t max_iteration_count_ = 0;
234 uint32_t max_path_building_depth_ = 0;
235 bool explore_all_paths_ = false;
236};
237
238} // namespace net
239
240#endif // BSSL_PKI_PATH_BUILDER_H_