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