15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef NET_CERT_CERT_DATABASE_H_
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define NET_CERT_CERT_DATABASE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/x509_certificate.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> struct DefaultSingletonTraits;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class ObserverType> class ObserverListThreadSafe;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class provides cross-platform functions to verify and add user
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// certificates, and to observe changes to the underlying certificate stores.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(gauravsh): This class could be augmented with methods
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for all operations that manipulate the underlying system
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// certificate store.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT CertDatabase {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A CertDatabase::Observer will be notified on certificate database changes.
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The change could be either a user certificate is added/removed or trust on
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // a certificate is changed. Observers can be registered via
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // CertDatabase::AddObserver, and can un-register with
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CertDatabase::RemoveObserver.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class NET_EXPORT Observer {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Observer() {}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Will be called when a new certificate is added. If the imported cert can
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // be determined, |cert| will be non-NULL, but if not, or if multiple
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // certificates were imported, |cert| may be NULL.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnCertAdded(const X509Certificate* cert) {}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Will be called when a certificate is removed.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnCertRemoved(const X509Certificate* cert) {}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Will be called when a CA certificate was added, removed, or its trust
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // changed. This can also mean that a client certificate's trust changed.
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    virtual void OnCACertChanged(const X509Certificate* cert) {}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Observer() {}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(Observer);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the CertDatabase singleton.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static CertDatabase* GetInstance();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check whether this is a valid user cert that we have the private key for.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns OK or a network error code such as ERR_CERT_CONTAINS_ERRORS.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int CheckUserCert(X509Certificate* cert);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Store user (client) certificate. Assumes CheckUserCert has already passed.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns OK, or ERR_ADD_USER_CERT_FAILED if there was a problem saving to
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the platform cert database, or possibly other network error codes.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int AddUserCert(X509Certificate* cert);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Registers |observer| to receive notifications of certificate changes.  The
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thread on which this is called is the thread on which |observer| will be
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called back with notifications.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddObserver(Observer* observer);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unregisters |observer| from receiving notifications.  This must be called
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on the same thread on which AddObserver() was called.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveObserver(Observer* observer);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) && !defined(OS_IOS)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configures the current message loop to observe and forward events from
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keychain services. The MessageLoop must have an associated CFRunLoop,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which means that this must be called from a MessageLoop of TYPE_UI.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetMessageLoopForKeychainEvents();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(OS_ANDROID)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // On Android, the system key store may be replaced with a device-specific
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // KeyStore used for storing client certificates. When the Java side replaces
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the KeyStore used for client certificates, notifies the observers as if a
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // new client certificate was added.
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnAndroidKeyStoreChanged();
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // On Android, the system database is used. When the system notifies the
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // application that the certificates changed, the observers must be notified.
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void OnAndroidKeyChainChanged();
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Synthetically injects notifications to all observers. In general, this
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // should only be called by the creator of the CertDatabase. Used to inject
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // notifcations from other DB interfaces.
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void NotifyObserversOfCertAdded(const X509Certificate* cert);
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void NotifyObserversOfCertRemoved(const X509Certificate* cert);
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void NotifyObserversOfCACertChanged(const X509Certificate* cert);
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct DefaultSingletonTraits<CertDatabase>;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertDatabase();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~CertDatabase();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(OS_MACOSX) && !defined(OS_IOS)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Notifier;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class Notifier;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Notifier> notifier_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CertDatabase);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif  // NET_CERT_CERT_DATABASE_H_
123