Home | History | Annotate | Download | only in base
      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