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