1*6777b538SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef NET_CERT_CACHING_CERT_VERIFIER_H_ 6*6777b538SAndroid Build Coastguard Worker #define NET_CERT_CACHING_CERT_VERIFIER_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <memory> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h" 11*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 12*6777b538SAndroid Build Coastguard Worker #include "net/base/completion_once_callback.h" 13*6777b538SAndroid Build Coastguard Worker #include "net/base/expiring_cache.h" 14*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 15*6777b538SAndroid Build Coastguard Worker #include "net/cert/cert_database.h" 16*6777b538SAndroid Build Coastguard Worker #include "net/cert/cert_verifier.h" 17*6777b538SAndroid Build Coastguard Worker #include "net/cert/cert_verify_result.h" 18*6777b538SAndroid Build Coastguard Worker 19*6777b538SAndroid Build Coastguard Worker namespace net { 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker // CertVerifier that caches the results of certificate verifications. 22*6777b538SAndroid Build Coastguard Worker // 23*6777b538SAndroid Build Coastguard Worker // In general, certificate verification results will vary on only three 24*6777b538SAndroid Build Coastguard Worker // parameters: 25*6777b538SAndroid Build Coastguard Worker // - The time of validation (as certificates are only valid for a period of 26*6777b538SAndroid Build Coastguard Worker // time) 27*6777b538SAndroid Build Coastguard Worker // - The revocation status (a certificate may be revoked at any time, but 28*6777b538SAndroid Build Coastguard Worker // revocation statuses themselves have validity period, so a 'good' result 29*6777b538SAndroid Build Coastguard Worker // may be reused for a period of time) 30*6777b538SAndroid Build Coastguard Worker // - The trust settings (a user may change trust settings at any time) 31*6777b538SAndroid Build Coastguard Worker // 32*6777b538SAndroid Build Coastguard Worker // This class tries to optimize by allowing certificate verification results 33*6777b538SAndroid Build Coastguard Worker // to be cached for a limited amount of time (presently, 30 minutes), which 34*6777b538SAndroid Build Coastguard Worker // tries to balance the implementation complexity of needing to monitor the 35*6777b538SAndroid Build Coastguard Worker // above for meaningful changes and the practical utility of being able to 36*6777b538SAndroid Build Coastguard Worker // cache results when they're not expected to change. 37*6777b538SAndroid Build Coastguard Worker class NET_EXPORT CachingCertVerifier : public CertVerifier, 38*6777b538SAndroid Build Coastguard Worker public CertVerifier::Observer, 39*6777b538SAndroid Build Coastguard Worker public CertDatabase::Observer { 40*6777b538SAndroid Build Coastguard Worker public: 41*6777b538SAndroid Build Coastguard Worker // Creates a CachingCertVerifier that will use |verifier| to perform the 42*6777b538SAndroid Build Coastguard Worker // actual verifications if they're not already cached or if the cached 43*6777b538SAndroid Build Coastguard Worker // item has expired. 44*6777b538SAndroid Build Coastguard Worker explicit CachingCertVerifier(std::unique_ptr<CertVerifier> verifier); 45*6777b538SAndroid Build Coastguard Worker 46*6777b538SAndroid Build Coastguard Worker CachingCertVerifier(const CachingCertVerifier&) = delete; 47*6777b538SAndroid Build Coastguard Worker CachingCertVerifier& operator=(const CachingCertVerifier&) = delete; 48*6777b538SAndroid Build Coastguard Worker 49*6777b538SAndroid Build Coastguard Worker ~CachingCertVerifier() override; 50*6777b538SAndroid Build Coastguard Worker 51*6777b538SAndroid Build Coastguard Worker // CertVerifier implementation: 52*6777b538SAndroid Build Coastguard Worker int Verify(const RequestParams& params, 53*6777b538SAndroid Build Coastguard Worker CertVerifyResult* verify_result, 54*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback, 55*6777b538SAndroid Build Coastguard Worker std::unique_ptr<Request>* out_req, 56*6777b538SAndroid Build Coastguard Worker const NetLogWithSource& net_log) override; 57*6777b538SAndroid Build Coastguard Worker void SetConfig(const Config& config) override; 58*6777b538SAndroid Build Coastguard Worker void AddObserver(CertVerifier::Observer* observer) override; 59*6777b538SAndroid Build Coastguard Worker void RemoveObserver(CertVerifier::Observer* observer) override; 60*6777b538SAndroid Build Coastguard Worker 61*6777b538SAndroid Build Coastguard Worker private: 62*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(CachingCertVerifierTest, CacheHit); 63*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(CachingCertVerifierTest, CacheHitCTResultsCached); 64*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(CachingCertVerifierTest, DifferentCACerts); 65*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(CachingCertVerifierCacheClearingTest, 66*6777b538SAndroid Build Coastguard Worker CacheClearedSyncVerification); 67*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(CachingCertVerifierCacheClearingTest, 68*6777b538SAndroid Build Coastguard Worker CacheClearedAsyncVerification); 69*6777b538SAndroid Build Coastguard Worker 70*6777b538SAndroid Build Coastguard Worker // CachedResult contains the result of a certificate verification. 71*6777b538SAndroid Build Coastguard Worker struct NET_EXPORT_PRIVATE CachedResult { 72*6777b538SAndroid Build Coastguard Worker CachedResult(); 73*6777b538SAndroid Build Coastguard Worker ~CachedResult(); 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker int error = ERR_FAILED; // The return value of CertVerifier::Verify. 76*6777b538SAndroid Build Coastguard Worker CertVerifyResult result; // The output of CertVerifier::Verify. 77*6777b538SAndroid Build Coastguard Worker }; 78*6777b538SAndroid Build Coastguard Worker 79*6777b538SAndroid Build Coastguard Worker // Rather than having a single validity point along a monotonically increasing 80*6777b538SAndroid Build Coastguard Worker // timeline, certificate verification is based on falling within a range of 81*6777b538SAndroid Build Coastguard Worker // the certificate's NotBefore and NotAfter and based on what the current 82*6777b538SAndroid Build Coastguard Worker // system clock says (which may advance forwards or backwards as users correct 83*6777b538SAndroid Build Coastguard Worker // clock skew). CacheValidityPeriod and CacheExpirationFunctor are helpers to 84*6777b538SAndroid Build Coastguard Worker // ensure that expiration is measured both by the 'general' case (now + cache 85*6777b538SAndroid Build Coastguard Worker // TTL) and by whether or not significant enough clock skew was introduced 86*6777b538SAndroid Build Coastguard Worker // since the last verification. 87*6777b538SAndroid Build Coastguard Worker struct CacheValidityPeriod { 88*6777b538SAndroid Build Coastguard Worker explicit CacheValidityPeriod(base::Time now); 89*6777b538SAndroid Build Coastguard Worker CacheValidityPeriod(base::Time now, base::Time expiration); 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard Worker base::Time verification_time; 92*6777b538SAndroid Build Coastguard Worker base::Time expiration_time; 93*6777b538SAndroid Build Coastguard Worker }; 94*6777b538SAndroid Build Coastguard Worker 95*6777b538SAndroid Build Coastguard Worker struct CacheExpirationFunctor { 96*6777b538SAndroid Build Coastguard Worker // Returns true iff |now| is within the validity period of |expiration|. 97*6777b538SAndroid Build Coastguard Worker bool operator()(const CacheValidityPeriod& now, 98*6777b538SAndroid Build Coastguard Worker const CacheValidityPeriod& expiration) const; 99*6777b538SAndroid Build Coastguard Worker }; 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Worker using CertVerificationCache = ExpiringCache<RequestParams, 102*6777b538SAndroid Build Coastguard Worker CachedResult, 103*6777b538SAndroid Build Coastguard Worker CacheValidityPeriod, 104*6777b538SAndroid Build Coastguard Worker CacheExpirationFunctor>; 105*6777b538SAndroid Build Coastguard Worker 106*6777b538SAndroid Build Coastguard Worker // Handles completion of the request matching |params|, which started at 107*6777b538SAndroid Build Coastguard Worker // |start_time| and with config |config_id|, completing. |verify_result| and 108*6777b538SAndroid Build Coastguard Worker // |result| are added to the cache, and then |callback| (the original caller's 109*6777b538SAndroid Build Coastguard Worker // callback) is invoked. 110*6777b538SAndroid Build Coastguard Worker void OnRequestFinished(uint32_t config_id, 111*6777b538SAndroid Build Coastguard Worker const RequestParams& params, 112*6777b538SAndroid Build Coastguard Worker base::Time start_time, 113*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback, 114*6777b538SAndroid Build Coastguard Worker CertVerifyResult* verify_result, 115*6777b538SAndroid Build Coastguard Worker int error); 116*6777b538SAndroid Build Coastguard Worker 117*6777b538SAndroid Build Coastguard Worker // Adds |verify_result| and |error| to the cache for |params|, whose 118*6777b538SAndroid Build Coastguard Worker // verification attempt began at |start_time| with config |config_id|. See the 119*6777b538SAndroid Build Coastguard Worker // implementation for more details about the necessity of |start_time|. 120*6777b538SAndroid Build Coastguard Worker void AddResultToCache(uint32_t config_id, 121*6777b538SAndroid Build Coastguard Worker const RequestParams& params, 122*6777b538SAndroid Build Coastguard Worker base::Time start_time, 123*6777b538SAndroid Build Coastguard Worker const CertVerifyResult& verify_result, 124*6777b538SAndroid Build Coastguard Worker int error); 125*6777b538SAndroid Build Coastguard Worker 126*6777b538SAndroid Build Coastguard Worker // CertVerifier::Observer methods: 127*6777b538SAndroid Build Coastguard Worker void OnCertVerifierChanged() override; 128*6777b538SAndroid Build Coastguard Worker 129*6777b538SAndroid Build Coastguard Worker // CertDatabase::Observer methods: 130*6777b538SAndroid Build Coastguard Worker void OnTrustStoreChanged() override; 131*6777b538SAndroid Build Coastguard Worker 132*6777b538SAndroid Build Coastguard Worker // For unit testing. 133*6777b538SAndroid Build Coastguard Worker void ClearCache(); 134*6777b538SAndroid Build Coastguard Worker size_t GetCacheSize() const; cache_hits()135*6777b538SAndroid Build Coastguard Worker uint64_t cache_hits() const { return cache_hits_; } requests()136*6777b538SAndroid Build Coastguard Worker uint64_t requests() const { return requests_; } 137*6777b538SAndroid Build Coastguard Worker 138*6777b538SAndroid Build Coastguard Worker std::unique_ptr<CertVerifier> verifier_; 139*6777b538SAndroid Build Coastguard Worker 140*6777b538SAndroid Build Coastguard Worker uint32_t config_id_ = 0u; 141*6777b538SAndroid Build Coastguard Worker CertVerificationCache cache_; 142*6777b538SAndroid Build Coastguard Worker 143*6777b538SAndroid Build Coastguard Worker uint64_t requests_ = 0u; 144*6777b538SAndroid Build Coastguard Worker uint64_t cache_hits_ = 0u; 145*6777b538SAndroid Build Coastguard Worker }; 146*6777b538SAndroid Build Coastguard Worker 147*6777b538SAndroid Build Coastguard Worker } // namespace net 148*6777b538SAndroid Build Coastguard Worker 149*6777b538SAndroid Build Coastguard Worker #endif // NET_CERT_CACHING_CERT_VERIFIER_H_ 150