xref: /aosp_15_r20/external/cronet/net/cert/caching_cert_verifier.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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