1 // Copyright (c) 2011 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_BASE_CERT_VERIFIER_H_ 6 #define NET_BASE_CERT_VERIFIER_H_ 7 #pragma once 8 9 #include <map> 10 #include <string> 11 12 #include "base/basictypes.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/threading/non_thread_safe.h" 15 #include "base/time.h" 16 #include "net/base/cert_database.h" 17 #include "net/base/cert_verify_result.h" 18 #include "net/base/completion_callback.h" 19 #include "net/base/x509_cert_types.h" 20 21 namespace net { 22 23 class CertVerifierJob; 24 class CertVerifierWorker; 25 class X509Certificate; 26 27 // CachedCertVerifyResult contains the result of a certificate verification. 28 struct CachedCertVerifyResult { 29 CachedCertVerifyResult(); 30 ~CachedCertVerifyResult(); 31 32 // Returns true if |current_time| is greater than or equal to |expiry|. 33 bool HasExpired(base::Time current_time) const; 34 35 int error; // The return value of CertVerifier::Verify. 36 CertVerifyResult result; // The output of CertVerifier::Verify. 37 38 // The time at which the certificate verification result expires. 39 base::Time expiry; 40 }; 41 42 // CertVerifier represents a service for verifying certificates. 43 // 44 // CertVerifier can handle multiple requests at a time, so when canceling a 45 // request the RequestHandle that was returned by Verify() needs to be 46 // given. A simpler alternative for consumers that only have 1 outstanding 47 // request at a time is to create a SingleRequestCertVerifier wrapper around 48 // CertVerifier (which will automatically cancel the single request when it 49 // goes out of scope). 50 class CertVerifier : public base::NonThreadSafe, 51 public CertDatabase::Observer { 52 public: 53 // Opaque type used to cancel a request. 54 typedef void* RequestHandle; 55 56 // CertVerifier must not call base::Time::Now() directly. It must call 57 // time_service_->Now(). This allows unit tests to mock the current time. 58 class TimeService { 59 public: ~TimeService()60 virtual ~TimeService() {} 61 62 virtual base::Time Now() = 0; 63 }; 64 65 CertVerifier(); 66 67 // Used by unit tests to mock the current time. Takes ownership of 68 // |time_service|. 69 explicit CertVerifier(TimeService* time_service); 70 71 // When the verifier is destroyed, all certificate verifications requests are 72 // canceled, and their completion callbacks will not be called. 73 ~CertVerifier(); 74 75 // Verifies the given certificate against the given hostname. Returns OK if 76 // successful or an error code upon failure. 77 // 78 // The |*verify_result| structure, including the |verify_result->cert_status| 79 // bitmask, is always filled out regardless of the return value. If the 80 // certificate has multiple errors, the corresponding status flags are set in 81 // |verify_result->cert_status|, and the error code for the most serious 82 // error is returned. 83 // 84 // |flags| is bitwise OR'd of X509Certificate::VerifyFlags. 85 // If VERIFY_REV_CHECKING_ENABLED is set in |flags|, certificate revocation 86 // checking is performed. 87 // 88 // If VERIFY_EV_CERT is set in |flags| too, EV certificate verification is 89 // performed. If |flags| is VERIFY_EV_CERT (that is, 90 // VERIFY_REV_CHECKING_ENABLED is not set), EV certificate verification will 91 // not be performed. 92 // 93 // |callback| must not be null. ERR_IO_PENDING is returned if the operation 94 // could not be completed synchronously, in which case the result code will 95 // be passed to the callback when available. 96 // 97 // If |out_req| is non-NULL, then |*out_req| will be filled with a handle to 98 // the async request. This handle is not valid after the request has 99 // completed. 100 int Verify(X509Certificate* cert, 101 const std::string& hostname, 102 int flags, 103 CertVerifyResult* verify_result, 104 CompletionCallback* callback, 105 RequestHandle* out_req); 106 107 // Cancels the specified request. |req| is the handle returned by Verify(). 108 // After a request is canceled, its completion callback will not be called. 109 void CancelRequest(RequestHandle req); 110 111 // Clears the verification result cache. 112 void ClearCache(); 113 114 size_t GetCacheSize() const; 115 requests()116 uint64 requests() const { return requests_; } cache_hits()117 uint64 cache_hits() const { return cache_hits_; } inflight_joins()118 uint64 inflight_joins() const { return inflight_joins_; } 119 120 private: 121 friend class CertVerifierWorker; // Calls HandleResult. 122 123 // Input parameters of a certificate verification request. 124 struct RequestParams { 125 bool operator==(const RequestParams& other) const { 126 // |flags| is compared before |cert_fingerprint| and |hostname| under 127 // assumption that integer comparisons are faster than memory and string 128 // comparisons. 129 return (flags == other.flags && 130 memcmp(cert_fingerprint.data, other.cert_fingerprint.data, 131 sizeof(cert_fingerprint.data)) == 0 && 132 hostname == other.hostname); 133 } 134 135 bool operator<(const RequestParams& other) const { 136 // |flags| is compared before |cert_fingerprint| and |hostname| under 137 // assumption that integer comparisons are faster than memory and string 138 // comparisons. 139 if (flags != other.flags) 140 return flags < other.flags; 141 int rv = memcmp(cert_fingerprint.data, other.cert_fingerprint.data, 142 sizeof(cert_fingerprint.data)); 143 if (rv != 0) 144 return rv < 0; 145 return hostname < other.hostname; 146 } 147 148 SHA1Fingerprint cert_fingerprint; 149 std::string hostname; 150 int flags; 151 }; 152 153 void HandleResult(X509Certificate* cert, 154 const std::string& hostname, 155 int flags, 156 int error, 157 const CertVerifyResult& verify_result); 158 159 // CertDatabase::Observer methods: 160 virtual void OnCertTrustChanged(const X509Certificate* cert); 161 162 // cache_ maps from a request to a cached result. The cached result may 163 // have expired and the size of |cache_| must be <= kMaxCacheEntries. 164 std::map<RequestParams, CachedCertVerifyResult> cache_; 165 166 // inflight_ maps from a request to an active verification which is taking 167 // place. 168 std::map<RequestParams, CertVerifierJob*> inflight_; 169 170 scoped_ptr<TimeService> time_service_; 171 172 uint64 requests_; 173 uint64 cache_hits_; 174 uint64 inflight_joins_; 175 176 DISALLOW_COPY_AND_ASSIGN(CertVerifier); 177 }; 178 179 // This class represents the task of verifying a certificate. It wraps 180 // CertVerifier to verify only a single certificate at a time and cancels this 181 // request when going out of scope. 182 class SingleRequestCertVerifier { 183 public: 184 // |cert_verifier| must remain valid for the lifetime of |this|. 185 explicit SingleRequestCertVerifier(CertVerifier* cert_verifier); 186 187 // If a completion callback is pending when the verifier is destroyed, the 188 // certificate verification is canceled, and the completion callback will 189 // not be called. 190 ~SingleRequestCertVerifier(); 191 192 // Verifies the given certificate, filling out the |verify_result| object 193 // upon success. See CertVerifier::Verify() for details. 194 int Verify(X509Certificate* cert, 195 const std::string& hostname, 196 int flags, 197 CertVerifyResult* verify_result, 198 CompletionCallback* callback); 199 200 private: 201 // Callback for when the request to |cert_verifier_| completes, so we 202 // dispatch to the user's callback. 203 void OnVerifyCompletion(int result); 204 205 // The actual certificate verifier that will handle the request. 206 CertVerifier* const cert_verifier_; 207 208 // The current request (if any). 209 CertVerifier::RequestHandle cur_request_; 210 CompletionCallback* cur_request_callback_; 211 212 // Completion callback for when request to |cert_verifier_| completes. 213 CompletionCallbackImpl<SingleRequestCertVerifier> callback_; 214 215 DISALLOW_COPY_AND_ASSIGN(SingleRequestCertVerifier); 216 }; 217 218 } // namespace net 219 220 #endif // NET_BASE_CERT_VERIFIER_H_ 221