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