Home | History | Annotate | Download | only in ssl
      1 // Copyright (c) 2012 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_SSL_SERVER_BOUND_CERT_SERVICE_H_
      6 #define NET_SSL_SERVER_BOUND_CERT_SERVICE_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "base/threading/non_thread_safe.h"
     16 #include "base/time/time.h"
     17 #include "net/base/completion_callback.h"
     18 #include "net/base/net_export.h"
     19 #include "net/ssl/server_bound_cert_store.h"
     20 
     21 namespace base {
     22 class TaskRunner;
     23 }
     24 
     25 namespace net {
     26 
     27 class ServerBoundCertServiceJob;
     28 class ServerBoundCertServiceRequest;
     29 class ServerBoundCertServiceWorker;
     30 
     31 // A class for creating and fetching server bound certs. These certs are used
     32 // to identify users' machines; their public keys are used as channel IDs in
     33 // http://tools.ietf.org/html/draft-balfanz-tls-channelid-00.
     34 // As a result although certs are set to be invalid after one year, we don't
     35 // actually expire them. Once generated, certs are valid as long as the users
     36 // want. Users can delete existing certs, and new certs will be generated
     37 // automatically.
     38 
     39 // Inherits from NonThreadSafe in order to use the function
     40 // |CalledOnValidThread|.
     41 class NET_EXPORT ServerBoundCertService
     42     : NON_EXPORTED_BASE(public base::NonThreadSafe) {
     43  public:
     44   class NET_EXPORT RequestHandle {
     45    public:
     46     RequestHandle();
     47     ~RequestHandle();
     48 
     49     // Cancel the request.  Does nothing if the request finished or was already
     50     // cancelled.
     51     void Cancel();
     52 
     53     bool is_active() const { return request_ != NULL; }
     54 
     55    private:
     56     friend class ServerBoundCertService;
     57 
     58     void RequestStarted(ServerBoundCertService* service,
     59                         ServerBoundCertServiceRequest* request,
     60                         const CompletionCallback& callback);
     61 
     62     void OnRequestComplete(int result);
     63 
     64     ServerBoundCertService* service_;
     65     ServerBoundCertServiceRequest* request_;
     66     CompletionCallback callback_;
     67   };
     68 
     69   // Password used on EncryptedPrivateKeyInfo data stored in EC private_key
     70   // values.  (This is not used to provide any security, but to workaround NSS
     71   // being unable to import unencrypted PrivateKeyInfo for EC keys.)
     72   static const char kEPKIPassword[];
     73 
     74   // This object owns |server_bound_cert_store|.  |task_runner| will
     75   // be used to post certificate generation worker tasks.  The tasks are
     76   // safe for use with WorkerPool and SequencedWorkerPool::CONTINUE_ON_SHUTDOWN.
     77   ServerBoundCertService(
     78       ServerBoundCertStore* server_bound_cert_store,
     79       const scoped_refptr<base::TaskRunner>& task_runner);
     80 
     81   ~ServerBoundCertService();
     82 
     83   // Returns the domain to be used for |host|.  The domain is the
     84   // "registry controlled domain", or the "ETLD + 1" where one exists, or
     85   // the origin otherwise.
     86   static std::string GetDomainForHost(const std::string& host);
     87 
     88   // Tests whether the system time is within the supported range for
     89   // certificate generation.  This value is cached when ServerBoundCertService
     90   // is created, so if the system time is changed by a huge amount, this may no
     91   // longer hold.
     92   bool IsSystemTimeValid() const { return is_system_time_valid_; }
     93 
     94   // Fetches the domain bound cert for the specified host if one exists and
     95   // creates one otherwise. Returns OK if successful or an error code upon
     96   // failure.
     97   //
     98   // On successful completion, |private_key| stores a DER-encoded
     99   // PrivateKeyInfo struct, and |cert| stores a DER-encoded certificate.
    100   // The PrivateKeyInfo is always an ECDSA private key.
    101   //
    102   // |callback| must not be null. ERR_IO_PENDING is returned if the operation
    103   // could not be completed immediately, in which case the result code will
    104   // be passed to the callback when available.
    105   //
    106   // |*out_req| will be initialized with a handle to the async request. This
    107   // RequestHandle object must be cancelled or destroyed before the
    108   // ServerBoundCertService is destroyed.
    109   int GetDomainBoundCert(
    110       const std::string& host,
    111       std::string* private_key,
    112       std::string* cert,
    113       const CompletionCallback& callback,
    114       RequestHandle* out_req);
    115 
    116   // Returns the backing ServerBoundCertStore.
    117   ServerBoundCertStore* GetCertStore();
    118 
    119   // Public only for unit testing.
    120   int cert_count();
    121   uint64 requests() const { return requests_; }
    122   uint64 cert_store_hits() const { return cert_store_hits_; }
    123   uint64 inflight_joins() const { return inflight_joins_; }
    124   uint64 workers_created() const { return workers_created_; }
    125 
    126  private:
    127   // Cancels the specified request. |req| is the handle stored by
    128   // GetDomainBoundCert(). After a request is canceled, its completion
    129   // callback will not be called.
    130   void CancelRequest(ServerBoundCertServiceRequest* req);
    131 
    132   void GotServerBoundCert(int err,
    133                           const std::string& server_identifier,
    134                           base::Time expiration_time,
    135                           const std::string& key,
    136                           const std::string& cert);
    137   void GeneratedServerBoundCert(
    138       const std::string& server_identifier,
    139       int error,
    140       scoped_ptr<ServerBoundCertStore::ServerBoundCert> cert);
    141   void HandleResult(int error,
    142                     const std::string& server_identifier,
    143                     const std::string& private_key,
    144                     const std::string& cert);
    145 
    146   scoped_ptr<ServerBoundCertStore> server_bound_cert_store_;
    147   scoped_refptr<base::TaskRunner> task_runner_;
    148 
    149   // inflight_ maps from a server to an active generation which is taking
    150   // place.
    151   std::map<std::string, ServerBoundCertServiceJob*> inflight_;
    152   base::WeakPtrFactory<ServerBoundCertService> weak_ptr_factory_;
    153 
    154   uint64 requests_;
    155   uint64 cert_store_hits_;
    156   uint64 inflight_joins_;
    157   uint64 workers_created_;
    158 
    159   bool is_system_time_valid_;
    160 
    161   DISALLOW_COPY_AND_ASSIGN(ServerBoundCertService);
    162 };
    163 
    164 }  // namespace net
    165 
    166 #endif  // NET_SSL_SERVER_BOUND_CERT_SERVICE_H_
    167