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