1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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_MULTI_THREADED_CERT_VERIFIER_H_ 6 #define NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/gtest_prod_util.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/threading/non_thread_safe.h" 16 #include "net/base/completion_callback.h" 17 #include "net/base/expiring_cache.h" 18 #include "net/base/hash_value.h" 19 #include "net/base/net_export.h" 20 #include "net/cert/cert_database.h" 21 #include "net/cert/cert_verifier.h" 22 #include "net/cert/cert_verify_result.h" 23 #include "net/cert/x509_cert_types.h" 24 25 namespace net { 26 27 class CertTrustAnchorProvider; 28 class CertVerifierJob; 29 class CertVerifierRequest; 30 class CertVerifierWorker; 31 class CertVerifyProc; 32 33 // MultiThreadedCertVerifier is a CertVerifier implementation that runs 34 // synchronous CertVerifier implementations on worker threads. 35 class NET_EXPORT_PRIVATE MultiThreadedCertVerifier 36 : public CertVerifier, 37 NON_EXPORTED_BASE(public base::NonThreadSafe), 38 public CertDatabase::Observer { 39 public: 40 explicit MultiThreadedCertVerifier(CertVerifyProc* verify_proc); 41 42 // When the verifier is destroyed, all certificate verifications requests are 43 // canceled, and their completion callbacks will not be called. 44 virtual ~MultiThreadedCertVerifier(); 45 46 // Configures a source of additional certificates that should be treated as 47 // trust anchors during verification, provided that the underlying 48 // CertVerifyProc supports additional trust beyond the default implementation. 49 // The CertTrustAnchorProvider will only be accessed on the same 50 // thread that Verify() is called on; that is, it will not be 51 // accessed from worker threads. 52 // It must outlive the MultiThreadedCertVerifier. 53 void SetCertTrustAnchorProvider( 54 CertTrustAnchorProvider* trust_anchor_provider); 55 56 // CertVerifier implementation 57 virtual int Verify(X509Certificate* cert, 58 const std::string& hostname, 59 int flags, 60 CRLSet* crl_set, 61 CertVerifyResult* verify_result, 62 const CompletionCallback& callback, 63 CertVerifier::RequestHandle* out_req, 64 const BoundNetLog& net_log) OVERRIDE; 65 66 virtual void CancelRequest(CertVerifier::RequestHandle req) OVERRIDE; 67 68 private: 69 friend class CertVerifierWorker; // Calls HandleResult. 70 friend class CertVerifierRequest; 71 friend class CertVerifierJob; 72 friend class MultiThreadedCertVerifierTest; 73 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, CacheHit); 74 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, DifferentCACerts); 75 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, InflightJoin); 76 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, CancelRequest); 77 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, 78 RequestParamsComparators); 79 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, 80 CertTrustAnchorProvider); 81 82 // Input parameters of a certificate verification request. 83 struct NET_EXPORT_PRIVATE RequestParams { 84 RequestParams(const SHA1HashValue& cert_fingerprint_arg, 85 const SHA1HashValue& ca_fingerprint_arg, 86 const std::string& hostname_arg, 87 int flags_arg, 88 const CertificateList& additional_trust_anchors); 89 ~RequestParams(); 90 91 bool operator<(const RequestParams& other) const; 92 93 std::string hostname; 94 int flags; 95 std::vector<SHA1HashValue> hash_values; 96 }; 97 98 // CachedResult contains the result of a certificate verification. 99 struct CachedResult { 100 CachedResult(); 101 ~CachedResult(); 102 103 int error; // The return value of CertVerifier::Verify. 104 CertVerifyResult result; // The output of CertVerifier::Verify. 105 }; 106 107 // Rather than having a single validity point along a monotonically increasing 108 // timeline, certificate verification is based on falling within a range of 109 // the certificate's NotBefore and NotAfter and based on what the current 110 // system clock says (which may advance forwards or backwards as users correct 111 // clock skew). CacheValidityPeriod and CacheExpirationFunctor are helpers to 112 // ensure that expiration is measured both by the 'general' case (now + cache 113 // TTL) and by whether or not significant enough clock skew was introduced 114 // since the last verification. 115 struct CacheValidityPeriod { 116 explicit CacheValidityPeriod(const base::Time& now); 117 CacheValidityPeriod(const base::Time& now, const base::Time& expiration); 118 119 base::Time verification_time; 120 base::Time expiration_time; 121 }; 122 123 struct CacheExpirationFunctor { 124 // Returns true iff |now| is within the validity period of |expiration|. 125 bool operator()(const CacheValidityPeriod& now, 126 const CacheValidityPeriod& expiration) const; 127 }; 128 129 typedef ExpiringCache<RequestParams, CachedResult, CacheValidityPeriod, 130 CacheExpirationFunctor> CertVerifierCache; 131 132 void HandleResult(X509Certificate* cert, 133 const std::string& hostname, 134 int flags, 135 const CertificateList& additional_trust_anchors, 136 int error, 137 const CertVerifyResult& verify_result); 138 139 // CertDatabase::Observer methods: 140 virtual void OnCACertChanged(const X509Certificate* cert) OVERRIDE; 141 142 // For unit testing. 143 void ClearCache() { cache_.Clear(); } 144 size_t GetCacheSize() const { return cache_.size(); } 145 uint64 cache_hits() const { return cache_hits_; } 146 uint64 requests() const { return requests_; } 147 uint64 inflight_joins() const { return inflight_joins_; } 148 149 // cache_ maps from a request to a cached result. 150 CertVerifierCache cache_; 151 152 // inflight_ maps from a request to an active verification which is taking 153 // place. 154 std::map<RequestParams, CertVerifierJob*> inflight_; 155 156 uint64 requests_; 157 uint64 cache_hits_; 158 uint64 inflight_joins_; 159 160 scoped_refptr<CertVerifyProc> verify_proc_; 161 162 CertTrustAnchorProvider* trust_anchor_provider_; 163 164 DISALLOW_COPY_AND_ASSIGN(MultiThreadedCertVerifier); 165 }; 166 167 } // namespace net 168 169 #endif // NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_ 170