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 NET_CERT_PKI_PATH_BUILDER_H_ 6 #define NET_CERT_PKI_PATH_BUILDER_H_ 7 8 #include <memory> 9 #include <vector> 10 11 #include "base/supports_user_data.h" 12 #include "net/base/net_export.h" 13 #include "net/cert/pki/cert_errors.h" 14 #include "net/cert/pki/parsed_certificate.h" 15 #include "net/cert/pki/trust_store.h" 16 #include "net/cert/pki/verify_certificate_chain.h" 17 #include "net/der/input.h" 18 #include "net/der/parse_values.h" 19 20 namespace net { 21 22 namespace der { 23 struct GeneralizedTime; 24 } 25 26 class CertPathBuilder; 27 class CertPathIter; 28 class CertIssuerSource; 29 30 // Base class for custom data that CertPathBuilderDelegate can attach to paths. 31 class NET_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. 43 struct NET_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. 54 const ParsedCertificate* GetTrustedCert() const; 55 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. 88 class NET_EXPORT CertPathBuilderDelegate 89 : public VerifyCertificateChainDelegate { 90 public: 91 // This is called during path building on candidate paths which have already 92 // been run through RFC 5280 verification. |path| may already have errors 93 // and warnings set on it. Delegates can "reject" a candidate path from path 94 // building by adding high severity errors. 95 virtual void CheckPathAfterVerification(const CertPathBuilder& path_builder, 96 CertPathBuilderResultPath* path) = 0; 97 98 // This is called during path building in between attempts to build candidate 99 // paths. Delegates can cause path building to stop and return indicating 100 // the deadline was exceeded by returning true from this function. 101 virtual bool IsDeadlineExpired() = 0; 102 }; 103 104 // Checks whether a certificate is trusted by building candidate paths to trust 105 // anchors and verifying those paths according to RFC 5280. Each instance of 106 // CertPathBuilder is used for a single verification. 107 // 108 // WARNING: This implementation is currently experimental. Consult an OWNER 109 // before using it. 110 class NET_EXPORT CertPathBuilder { 111 public: 112 // Provides the overall result of path building. This includes the paths that 113 // were attempted. 114 struct NET_EXPORT Result : public base::SupportsUserData { 115 Result(); 116 Result(Result&&); 117 118 Result(const Result&) = delete; 119 Result& operator=(const Result&) = delete; 120 121 ~Result() override; 122 Result& operator=(Result&&); 123 124 // Returns true if there was a valid path. 125 bool HasValidPath() const; 126 127 // Returns true if any of the attempted paths contain |error_id|. 128 bool AnyPathContainsError(CertErrorId error_id) const; 129 130 // Returns the CertPathBuilderResultPath for the best valid path, or nullptr 131 // if there was none. 132 const CertPathBuilderResultPath* GetBestValidPath() const; 133 134 // Returns the best CertPathBuilderResultPath or nullptr if there was none. 135 const CertPathBuilderResultPath* GetBestPathPossiblyInvalid() const; 136 137 // List of paths that were attempted and the result for each. 138 std::vector<std::unique_ptr<CertPathBuilderResultPath>> paths; 139 140 // Index into |paths|. Before use, |paths.empty()| must be checked. 141 // NOTE: currently the definition of "best" is fairly limited. Valid is 142 // better than invalid, but otherwise nothing is guaranteed. 143 size_t best_result_index = 0; 144 145 // The iteration count reached by path building. 146 uint32_t iteration_count = 0; 147 148 // The max depth seen while path building. 149 uint32_t max_depth_seen = 0; 150 151 // True if the search stopped because it exceeded the iteration limit 152 // configured with |SetIterationLimit|. 153 bool exceeded_iteration_limit = false; 154 155 // True if the search stopped because delegate->IsDeadlineExpired() returned 156 // true. 157 bool exceeded_deadline = false; 158 }; 159 160 // Creates a CertPathBuilder that attempts to find a path from |cert| to a 161 // trust anchor in |trust_store| and is valid at |time|. 162 // 163 // The caller must keep |trust_store| and |delegate| valid for the lifetime 164 // of the CertPathBuilder. 165 // 166 // See VerifyCertificateChain() for a more detailed explanation of the 167 // same-named parameters not defined below. 168 // 169 // * |delegate|: Must be non-null. The delegate is called at various points in 170 // path building to verify specific parts of certificates or the 171 // final chain. See CertPathBuilderDelegate and 172 // VerifyCertificateChainDelegate for more information. 173 CertPathBuilder(std::shared_ptr<const ParsedCertificate> cert, 174 TrustStore* trust_store, 175 CertPathBuilderDelegate* delegate, 176 const der::GeneralizedTime& time, 177 KeyPurpose key_purpose, 178 InitialExplicitPolicy initial_explicit_policy, 179 const std::set<der::Input>& user_initial_policy_set, 180 InitialPolicyMappingInhibit initial_policy_mapping_inhibit, 181 InitialAnyPolicyInhibit initial_any_policy_inhibit); 182 183 CertPathBuilder(const CertPathBuilder&) = delete; 184 CertPathBuilder& operator=(const CertPathBuilder&) = delete; 185 186 ~CertPathBuilder(); 187 188 // Adds a CertIssuerSource to provide intermediates for use in path building. 189 // Multiple sources may be added. Must not be called after Run is called. 190 // The |*cert_issuer_source| must remain valid for the lifetime of the 191 // CertPathBuilder. 192 // 193 // (If no issuer sources are added, the target certificate will only verify if 194 // it is a trust anchor or is directly signed by a trust anchor.) 195 void AddCertIssuerSource(CertIssuerSource* cert_issuer_source); 196 197 // Sets a limit to the number of times to repeat the process of considering a 198 // new intermediate over all potential paths. Setting |limit| to 0 disables 199 // the iteration limit, which is the default. 200 void SetIterationLimit(uint32_t limit); 201 202 // Sets a limit to the number of certificates to be added in a path from leaf 203 // to root. Setting |limit| to 0 disables this limit, which is the default. 204 void SetDepthLimit(uint32_t limit); 205 206 // If |explore_all_paths| is false (the default), path building will stop as 207 // soon as a valid path is found. If |explore_all_paths| is true, path 208 // building will continue until all possible paths have been exhausted (or 209 // iteration limit / deadline is exceeded). 210 void SetExploreAllPaths(bool explore_all_paths); 211 212 // Executes verification of the target certificate. 213 // 214 // Run must not be called more than once on each CertPathBuilder instance. 215 Result Run(); 216 217 private: 218 void AddResultPath(std::unique_ptr<CertPathBuilderResultPath> result_path); 219 220 // |out_result_| may be referenced by other members, so should be initialized 221 // first. 222 Result out_result_; 223 224 std::unique_ptr<CertPathIter> cert_path_iter_; 225 raw_ptr<CertPathBuilderDelegate> delegate_; 226 const der::GeneralizedTime time_; 227 const KeyPurpose key_purpose_; 228 const InitialExplicitPolicy initial_explicit_policy_; 229 const std::set<der::Input> user_initial_policy_set_; 230 const InitialPolicyMappingInhibit initial_policy_mapping_inhibit_; 231 const InitialAnyPolicyInhibit initial_any_policy_inhibit_; 232 uint32_t max_iteration_count_ = 0; 233 uint32_t max_path_building_depth_ = 0; 234 bool explore_all_paths_ = false; 235 }; 236 237 } // namespace net 238 239 #endif // NET_CERT_PKI_PATH_BUILDER_H_ 240