Home | History | Annotate | Download | only in cert
      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_CERT_NSS_CERT_DATABASE_H_
      6 #define NET_CERT_NSS_CERT_DATABASE_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/callback_forward.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "base/strings/string16.h"
     16 #include "crypto/scoped_nss_types.h"
     17 #include "net/base/net_errors.h"
     18 #include "net/base/net_export.h"
     19 #include "net/cert/cert_type.h"
     20 #include "net/cert/x509_certificate.h"
     21 
     22 namespace base {
     23 class TaskRunner;
     24 }
     25 template <class ObserverType> class ObserverListThreadSafe;
     26 
     27 namespace net {
     28 
     29 class CryptoModule;
     30 typedef std::vector<scoped_refptr<CryptoModule> > CryptoModuleList;
     31 
     32 // Provides functions to manipulate the NSS certificate stores.
     33 // Forwards notifications about certificate changes to the global CertDatabase
     34 // singleton.
     35 class NET_EXPORT NSSCertDatabase {
     36  public:
     37   class NET_EXPORT Observer {
     38    public:
     39     virtual ~Observer() {}
     40 
     41     // Will be called when a new certificate is added.
     42     // Called with |cert| == NULL after importing a list of certificates
     43     // in ImportFromPKCS12().
     44     virtual void OnCertAdded(const X509Certificate* cert) {}
     45 
     46     // Will be called when a certificate is removed.
     47     virtual void OnCertRemoved(const X509Certificate* cert) {}
     48 
     49     // Will be called when a CA certificate is changed.
     50     // Called with |cert| == NULL after importing a list of certificates
     51     // in ImportCACerts().
     52     virtual void OnCACertChanged(const X509Certificate* cert) {}
     53 
     54    protected:
     55     Observer() {}
     56 
     57    private:
     58     DISALLOW_COPY_AND_ASSIGN(Observer);
     59   };
     60 
     61   // Stores per-certificate error codes for import failures.
     62   struct NET_EXPORT ImportCertFailure {
     63    public:
     64     ImportCertFailure(const scoped_refptr<X509Certificate>& cert, int err);
     65     ~ImportCertFailure();
     66 
     67     scoped_refptr<X509Certificate> certificate;
     68     int net_error;
     69   };
     70   typedef std::vector<ImportCertFailure> ImportCertFailureList;
     71 
     72   // Constants that define which usages a certificate is trusted for.
     73   // They are used in combination with CertType to specify trust for each type
     74   // of certificate.
     75   // For a CA_CERT, they specify that the CA is trusted for issuing server and
     76   // client certs of each type.
     77   // For SERVER_CERT, only TRUSTED_SSL makes sense, and specifies the cert is
     78   // trusted as a server.
     79   // For EMAIL_CERT, only TRUSTED_EMAIL makes sense, and specifies the cert is
     80   // trusted for email.
     81   // DISTRUSTED_* specifies that the cert should not be trusted for the given
     82   // usage, regardless of whether it would otherwise inherit trust from the
     83   // issuer chain.
     84   // Use TRUST_DEFAULT to inherit trust as normal.
     85   // NOTE: The actual constants are defined using an enum instead of static
     86   // consts due to compilation/linkage constraints with template functions.
     87   typedef uint32 TrustBits;
     88   enum {
     89     TRUST_DEFAULT         =      0,
     90     TRUSTED_SSL           = 1 << 0,
     91     TRUSTED_EMAIL         = 1 << 1,
     92     TRUSTED_OBJ_SIGN      = 1 << 2,
     93     DISTRUSTED_SSL        = 1 << 3,
     94     DISTRUSTED_EMAIL      = 1 << 4,
     95     DISTRUSTED_OBJ_SIGN   = 1 << 5,
     96   };
     97 
     98   typedef base::Callback<void(scoped_ptr<CertificateList> certs)>
     99       ListCertsCallback;
    100 
    101   typedef base::Callback<void(bool)> DeleteCertCallback;
    102 
    103   // Creates a NSSCertDatabase that will store public information (such as
    104   // certificates and trust records) in |public_slot|, and private information
    105   // (such as keys) in |private_slot|.
    106   // In general, code should avoid creating an NSSCertDatabase directly,
    107   // as doing so requires making opinionated decisions about where to store
    108   // data, and instead prefer to be passed an existing NSSCertDatabase
    109   // instance.
    110   // |public_slot| must not be NULL, |private_slot| can be NULL. Both slots can
    111   // be identical.
    112   NSSCertDatabase(crypto::ScopedPK11Slot public_slot,
    113                   crypto::ScopedPK11Slot private_slot);
    114   virtual ~NSSCertDatabase();
    115 
    116   // Get a list of unique certificates in the certificate database (one
    117   // instance of all certificates).
    118   // DEPRECATED by |ListCerts|. See http://crbug.com/340460.
    119   virtual void ListCertsSync(CertificateList* certs);
    120 
    121   // Asynchronously get a list of unique certificates in the certificate
    122   // database (one instance of all certificates). Note that the callback may be
    123   // run even after the database is deleted.
    124   virtual void ListCerts(const ListCertsCallback& callback);
    125 
    126   // Get a list of certificates in the certificate database of the given slot.
    127   // Note that the callback may be run even after the database is deleted.
    128   // Must be called on the IO thread and it calls |callback| on the IO thread.
    129   // This does not block by retrieving the certs asynchronously on a worker
    130   // thread. Never calls |callback| synchronously.
    131   virtual void ListCertsInSlot(const ListCertsCallback& callback,
    132                                PK11SlotInfo* slot);
    133 
    134 #if defined(OS_CHROMEOS)
    135   // Get the slot for system-wide key data. May be NULL if the system token was
    136   // not explicitly set.
    137   // Note: The System slot is set after the NSSCertDatabase is constructed and
    138   // this call returns synchronously. Thus, it is possible to call this function
    139   // before SetSystemSlot is called and get a NULL result.
    140   // See https://crbug.com/399554 .
    141   virtual crypto::ScopedPK11Slot GetSystemSlot() const;
    142 #endif
    143 
    144   // Get the default slot for public key data.
    145   crypto::ScopedPK11Slot GetPublicSlot() const;
    146 
    147   // Get the default slot for private key or mixed private/public key data.
    148   // Can return NULL.
    149   crypto::ScopedPK11Slot GetPrivateSlot() const;
    150 
    151   // Get the default module for public key data.
    152   // The returned pointer must be stored in a scoped_refptr<CryptoModule>.
    153   // DEPRECATED: use GetPublicSlot instead.
    154   // TODO(mattm): remove usage of this method and remove it.
    155   CryptoModule* GetPublicModule() const;
    156 
    157   // Get the default module for private key or mixed private/public key data.
    158   // The returned pointer must be stored in a scoped_refptr<CryptoModule>.
    159   // DEPRECATED: use GetPrivateSlot instead.
    160   // TODO(mattm): remove usage of this method and remove it.
    161   CryptoModule* GetPrivateModule() const;
    162 
    163   // Get all modules.
    164   // If |need_rw| is true, only writable modules will be returned.
    165   // TODO(mattm): come up with better alternative to CryptoModuleList.
    166   virtual void ListModules(CryptoModuleList* modules, bool need_rw) const;
    167 
    168   // Import certificates and private keys from PKCS #12 blob into the module.
    169   // If |is_extractable| is false, mark the private key as being unextractable
    170   // from the module.
    171   // Returns OK or a network error code such as ERR_PKCS12_IMPORT_BAD_PASSWORD
    172   // or ERR_PKCS12_IMPORT_ERROR. |imported_certs|, if non-NULL, returns a list
    173   // of certs that were imported.
    174   int ImportFromPKCS12(CryptoModule* module,
    175                        const std::string& data,
    176                        const base::string16& password,
    177                        bool is_extractable,
    178                        CertificateList* imported_certs);
    179 
    180   // Export the given certificates and private keys into a PKCS #12 blob,
    181   // storing into |output|.
    182   // Returns the number of certificates successfully exported.
    183   int ExportToPKCS12(const CertificateList& certs,
    184                      const base::string16& password,
    185                      std::string* output) const;
    186 
    187   // Uses similar logic to nsNSSCertificateDB::handleCACertDownload to find the
    188   // root.  Assumes the list is an ordered hierarchy with the root being either
    189   // the first or last element.
    190   // TODO(mattm): improve this to handle any order.
    191   X509Certificate* FindRootInList(const CertificateList& certificates) const;
    192 
    193   // Import CA certificates.
    194   // Tries to import all the certificates given.  The root will be trusted
    195   // according to |trust_bits|.  Any certificates that could not be imported
    196   // will be listed in |not_imported|.
    197   // Returns false if there is an internal error, otherwise true is returned and
    198   // |not_imported| should be checked for any certificates that were not
    199   // imported.
    200   bool ImportCACerts(const CertificateList& certificates,
    201                      TrustBits trust_bits,
    202                      ImportCertFailureList* not_imported);
    203 
    204   // Import server certificate.  The first cert should be the server cert.  Any
    205   // additional certs should be intermediate/CA certs and will be imported but
    206   // not given any trust.
    207   // Any certificates that could not be imported will be listed in
    208   // |not_imported|.
    209   // |trust_bits| can be set to explicitly trust or distrust the certificate, or
    210   // use TRUST_DEFAULT to inherit trust as normal.
    211   // Returns false if there is an internal error, otherwise true is returned and
    212   // |not_imported| should be checked for any certificates that were not
    213   // imported.
    214   bool ImportServerCert(const CertificateList& certificates,
    215                         TrustBits trust_bits,
    216                         ImportCertFailureList* not_imported);
    217 
    218   // Get trust bits for certificate.
    219   TrustBits GetCertTrust(const X509Certificate* cert, CertType type) const;
    220 
    221   // IsUntrusted returns true if |cert| is specifically untrusted. These
    222   // certificates are stored in the database for the specific purpose of
    223   // rejecting them.
    224   bool IsUntrusted(const X509Certificate* cert) const;
    225 
    226   // Set trust values for certificate.
    227   // Returns true on success or false on failure.
    228   bool SetCertTrust(const X509Certificate* cert,
    229                     CertType type,
    230                     TrustBits trust_bits);
    231 
    232   // Delete certificate and associated private key (if one exists).
    233   // |cert| is still valid when this function returns. Returns true on
    234   // success.
    235   bool DeleteCertAndKey(X509Certificate* cert);
    236 
    237   // Like DeleteCertAndKey but does not block by running the removal on a worker
    238   // thread. This must be called on IO thread and it will run |callback| on IO
    239   // thread. Never calls |callback| synchronously.
    240   void DeleteCertAndKeyAsync(const scoped_refptr<X509Certificate>& cert,
    241                              const DeleteCertCallback& callback);
    242 
    243   // Check whether cert is stored in a readonly slot.
    244   bool IsReadOnly(const X509Certificate* cert) const;
    245 
    246   // Check whether cert is stored in a hardware slot.
    247   bool IsHardwareBacked(const X509Certificate* cert) const;
    248 
    249   // Overrides task runner that's used for running slow tasks.
    250   void SetSlowTaskRunnerForTest(
    251       const scoped_refptr<base::TaskRunner>& task_runner);
    252 
    253  protected:
    254   // Certificate listing implementation used by |ListCerts*| and
    255   // |ListCertsSync|. Static so it may safely be used on the worker thread.
    256   // If |slot| is NULL, obtains the certs of all slots, otherwise only of
    257   // |slot|.
    258   static void ListCertsImpl(crypto::ScopedPK11Slot slot,
    259                             CertificateList* certs);
    260 
    261   // Gets task runner that should be used for slow tasks like certificate
    262   // listing. Defaults to a base::WorkerPool runner, but may be overriden
    263   // in tests (see SetSlowTaskRunnerForTest).
    264   scoped_refptr<base::TaskRunner> GetSlowTaskRunner() const;
    265 
    266  private:
    267   // Registers |observer| to receive notifications of certificate changes.  The
    268   // thread on which this is called is the thread on which |observer| will be
    269   // called back with notifications.
    270   // NOTE: Observers registered here will only receive notifications generated
    271   // directly through the NSSCertDatabase, but not those from the CertDatabase.
    272   // CertDatabase observers will receive all certificate notifications.
    273   void AddObserver(Observer* observer);
    274 
    275   // Unregisters |observer| from receiving notifications.  This must be called
    276   // on the same thread on which AddObserver() was called.
    277   void RemoveObserver(Observer* observer);
    278 
    279   // Notifies observers of the removal of |cert| and calls |callback| with
    280   // |success| as argument.
    281   void NotifyCertRemovalAndCallBack(scoped_refptr<X509Certificate> cert,
    282                                     const DeleteCertCallback& callback,
    283                                     bool success);
    284 
    285   // Broadcasts notifications to all registered observers.
    286   void NotifyObserversOfCertAdded(const X509Certificate* cert);
    287   void NotifyObserversOfCertRemoved(const X509Certificate* cert);
    288   void NotifyObserversOfCACertChanged(const X509Certificate* cert);
    289 
    290   // Certificate removal implementation used by |DeleteCertAndKey*|. Static so
    291   // it may safely be used on the worker thread.
    292   static bool DeleteCertAndKeyImpl(scoped_refptr<X509Certificate> cert);
    293 
    294   crypto::ScopedPK11Slot public_slot_;
    295   crypto::ScopedPK11Slot private_slot_;
    296 
    297   // A helper observer that forwards events from this database to CertDatabase.
    298   scoped_ptr<Observer> cert_notification_forwarder_;
    299 
    300   // Task runner that should be used in tests if set.
    301   scoped_refptr<base::TaskRunner> slow_task_runner_for_test_;
    302 
    303   const scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_;
    304 
    305   base::WeakPtrFactory<NSSCertDatabase> weak_factory_;
    306 
    307   DISALLOW_COPY_AND_ASSIGN(NSSCertDatabase);
    308 };
    309 
    310 }  // namespace net
    311 
    312 #endif  // NET_CERT_NSS_CERT_DATABASE_H_
    313