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