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_DEFAULT_SERVER_BOUND_CERT_STORE_H_
      6 #define NET_SSL_DEFAULT_SERVER_BOUND_CERT_STORE_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/callback_forward.h"
     13 #include "base/compiler_specific.h"
     14 #include "base/memory/ref_counted.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/memory/scoped_vector.h"
     17 #include "base/memory/weak_ptr.h"
     18 #include "net/base/net_export.h"
     19 #include "net/ssl/server_bound_cert_store.h"
     20 
     21 namespace net {
     22 
     23 // This class is the system for storing and retrieving server bound certs.
     24 // Modeled after the CookieMonster class, it has an in-memory cert store,
     25 // and synchronizes server bound certs to an optional permanent storage that
     26 // implements the PersistentStore interface. The use case is described in
     27 // http://balfanz.github.com/tls-obc-spec/draft-balfanz-tls-obc-00.html
     28 class NET_EXPORT DefaultServerBoundCertStore : public ServerBoundCertStore {
     29  public:
     30   class PersistentStore;
     31 
     32   // The key for each ServerBoundCert* in ServerBoundCertMap is the
     33   // corresponding server.
     34   typedef std::map<std::string, ServerBoundCert*> ServerBoundCertMap;
     35 
     36   // The store passed in should not have had Init() called on it yet. This
     37   // class will take care of initializing it. The backing store is NOT owned by
     38   // this class, but it must remain valid for the duration of the
     39   // DefaultServerBoundCertStore's existence. If |store| is NULL, then no
     40   // backing store will be updated.
     41   explicit DefaultServerBoundCertStore(PersistentStore* store);
     42 
     43   virtual ~DefaultServerBoundCertStore();
     44 
     45   // ServerBoundCertStore implementation.
     46   virtual int GetServerBoundCert(
     47       const std::string& server_identifier,
     48       base::Time* expiration_time,
     49       std::string* private_key_result,
     50       std::string* cert_result,
     51       const GetCertCallback& callback) OVERRIDE;
     52   virtual void SetServerBoundCert(
     53       const std::string& server_identifier,
     54       base::Time creation_time,
     55       base::Time expiration_time,
     56       const std::string& private_key,
     57       const std::string& cert) OVERRIDE;
     58   virtual void DeleteServerBoundCert(
     59       const std::string& server_identifier,
     60       const base::Closure& callback) OVERRIDE;
     61   virtual void DeleteAllCreatedBetween(
     62       base::Time delete_begin,
     63       base::Time delete_end,
     64       const base::Closure& callback) OVERRIDE;
     65   virtual void DeleteAll(const base::Closure& callback) OVERRIDE;
     66   virtual void GetAllServerBoundCerts(
     67       const GetCertListCallback& callback) OVERRIDE;
     68   virtual int GetCertCount() OVERRIDE;
     69   virtual void SetForceKeepSessionState() OVERRIDE;
     70 
     71  private:
     72   class Task;
     73   class GetServerBoundCertTask;
     74   class SetServerBoundCertTask;
     75   class DeleteServerBoundCertTask;
     76   class DeleteAllCreatedBetweenTask;
     77   class GetAllServerBoundCertsTask;
     78 
     79   static const size_t kMaxCerts;
     80 
     81   // Deletes all of the certs. Does not delete them from |store_|.
     82   void DeleteAllInMemory();
     83 
     84   // Called by all non-static functions to ensure that the cert store has
     85   // been initialized.
     86   // TODO(mattm): since we load asynchronously now, maybe we should start
     87   // loading immediately on construction, or provide some method to initiate
     88   // loading?
     89   void InitIfNecessary() {
     90     if (!initialized_) {
     91       if (store_.get()) {
     92         InitStore();
     93       } else {
     94         loaded_ = true;
     95       }
     96       initialized_ = true;
     97     }
     98   }
     99 
    100   // Initializes the backing store and reads existing certs from it.
    101   // Should only be called by InitIfNecessary().
    102   void InitStore();
    103 
    104   // Callback for backing store loading completion.
    105   void OnLoaded(scoped_ptr<ScopedVector<ServerBoundCert> > certs);
    106 
    107   // Syncronous methods which do the actual work. Can only be called after
    108   // initialization is complete.
    109   void SyncSetServerBoundCert(
    110       const std::string& server_identifier,
    111       base::Time creation_time,
    112       base::Time expiration_time,
    113       const std::string& private_key,
    114       const std::string& cert);
    115   void SyncDeleteServerBoundCert(const std::string& server_identifier);
    116   void SyncDeleteAllCreatedBetween(base::Time delete_begin,
    117                                    base::Time delete_end);
    118   void SyncGetAllServerBoundCerts(ServerBoundCertList* cert_list);
    119 
    120   // Add |task| to |waiting_tasks_|.
    121   void EnqueueTask(scoped_ptr<Task> task);
    122   // If already initialized, run |task| immediately. Otherwise add it to
    123   // |waiting_tasks_|.
    124   void RunOrEnqueueTask(scoped_ptr<Task> task);
    125 
    126   // Deletes the cert for the specified server, if such a cert exists, from the
    127   // in-memory store. Deletes it from |store_| if |store_| is not NULL.
    128   void InternalDeleteServerBoundCert(const std::string& server);
    129 
    130   // Takes ownership of *cert.
    131   // Adds the cert for the specified server to the in-memory store. Deletes it
    132   // from |store_| if |store_| is not NULL.
    133   void InternalInsertServerBoundCert(const std::string& server_identifier,
    134                                      ServerBoundCert* cert);
    135 
    136   // Indicates whether the cert store has been initialized. This happens
    137   // lazily in InitIfNecessary().
    138   bool initialized_;
    139 
    140   // Indicates whether loading from the backend store is completed and
    141   // calls may be immediately processed.
    142   bool loaded_;
    143 
    144   // Tasks that are waiting to be run once we finish loading.
    145   ScopedVector<Task> waiting_tasks_;
    146   base::TimeTicks waiting_tasks_start_time_;
    147 
    148   scoped_refptr<PersistentStore> store_;
    149 
    150   ServerBoundCertMap server_bound_certs_;
    151 
    152   base::WeakPtrFactory<DefaultServerBoundCertStore> weak_ptr_factory_;
    153 
    154   DISALLOW_COPY_AND_ASSIGN(DefaultServerBoundCertStore);
    155 };
    156 
    157 typedef base::RefCountedThreadSafe<DefaultServerBoundCertStore::PersistentStore>
    158     RefcountedPersistentStore;
    159 
    160 class NET_EXPORT DefaultServerBoundCertStore::PersistentStore
    161     : public RefcountedPersistentStore {
    162  public:
    163   typedef base::Callback<void(scoped_ptr<ScopedVector<ServerBoundCert> >)>
    164       LoadedCallback;
    165 
    166   // Initializes the store and retrieves the existing certs. This will be
    167   // called only once at startup. Note that the certs are individually allocated
    168   // and that ownership is transferred to the caller upon return.
    169   // The |loaded_callback| must not be called synchronously.
    170   virtual void Load(const LoadedCallback& loaded_callback) = 0;
    171 
    172   virtual void AddServerBoundCert(const ServerBoundCert& cert) = 0;
    173 
    174   virtual void DeleteServerBoundCert(const ServerBoundCert& cert) = 0;
    175 
    176   // When invoked, instructs the store to keep session related data on
    177   // destruction.
    178   virtual void SetForceKeepSessionState() = 0;
    179 
    180  protected:
    181   friend class base::RefCountedThreadSafe<PersistentStore>;
    182 
    183   PersistentStore();
    184   virtual ~PersistentStore();
    185 
    186  private:
    187   DISALLOW_COPY_AND_ASSIGN(PersistentStore);
    188 };
    189 
    190 }  // namespace net
    191 
    192 #endif  // NET_SSL_DEFAULT_SERVER_BOUND_CERT_STORE_H_
    193