1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#ifndef CHROMEOS_CERT_LOADER_H_ 6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#define CHROMEOS_CERT_LOADER_H_ 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string> 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector> 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include "base/basictypes.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/compiler_specific.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/ref_counted.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/weak_ptr.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/observer_list.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/threading/thread_checker.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/chromeos_export.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/cert_database.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net { 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class NSSCertDatabase; 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class X509Certificate; 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)typedef std::vector<scoped_refptr<X509Certificate> > CertificateList; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos { 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This class is responsible for loading certificates once the TPM is 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// initialized. It is expected to be constructed on the UI thread and public 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// methods should all be called from the UI thread. 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// When certificates have been loaded (after login completes and tpm token is 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// initialized), or the cert database changes, observers are called with 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// OnCertificatesLoaded(). 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CHROMEOS_EXPORT CertLoader : public net::CertDatabase::Observer { 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) class Observer { 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called when the certificates, passed for convenience as |cert_list|, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // have completed loading. |initial_load| is true the first time this 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // is called. 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnCertificatesLoaded(const net::CertificateList& cert_list, 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool initial_load) = 0; 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~Observer() {} 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 48558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Sets the global instance. Must be called before any calls to Get(). 49558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch static void Initialize(); 50558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 51558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Destroys the global instance. 52558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch static void Shutdown(); 53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Gets the global instance. Initialize() must be called first. 55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch static CertLoader* Get(); 56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Returns true if the global instance has been initialized. 58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch static bool IsInitialized(); 59558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Returns the PKCS#11 attribute CKA_ID for a certificate as an upper-case 61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // hex string, or the empty string if none is found. Note that the returned ID 62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // should be used only to identify the cert in its slot. 63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // This should be used only for user certificates, assuming that only one 64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // private slot is loaded for a user. 65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(tbarzic): Make this check cert slot id if we start loading 66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // certificates for secondary users. 67c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch static std::string GetPkcs11IdForCert(const net::X509Certificate& cert); 68c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Starts the CertLoader with the NSS cert database. 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The CertLoader will _not_ take the ownership of the database, but it 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // expects it to stay alive at least until the shutdown starts on the main 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // thread. This assumes that |StartWithNSSDB| and other methods directly 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // using |database_| are not called during shutdown. 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void StartWithNSSDB(net::NSSCertDatabase* database); 753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void AddObserver(CertLoader::Observer* observer); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void RemoveObserver(CertLoader::Observer* observer); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int TPMTokenSlotID() const; 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool IsHardwareBacked() const; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Whether the certificate is hardware backed. Returns false if the CertLoader 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // was not yet started (both |CertificatesLoading()| and 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |certificates_loaded()| are false). 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool IsCertificateHardwareBacked(const net::X509Certificate* cert) const; 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Returns true when the certificate list has been requested but not loaded. 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool CertificatesLoading() const; 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool certificates_loaded() const { return certificates_loaded_; } 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This will be empty until certificates_loaded() is true. 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::CertificateList& cert_list() const { return *cert_list_; } 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void force_hardware_backed_for_test() { 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) force_hardware_backed_for_test_ = true; 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CertLoader(); 101558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch virtual ~CertLoader(); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Trigger a certificate load. If a certificate loading task is already in 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // progress, will start a reload once the current task is finished. 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void LoadCertificates(); 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Called if a certificate load task is finished. 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void UpdateCertificates(scoped_ptr<net::CertificateList> cert_list); 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void NotifyCertificatesLoaded(bool initial_load); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // net::CertDatabase::Observer 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual void OnCACertChanged(const net::X509Certificate* cert) OVERRIDE; 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnCertAdded(const net::X509Certificate* cert) OVERRIDE; 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnCertRemoved(const net::X509Certificate* cert) OVERRIDE; 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ObserverList<Observer> observers_; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Flags describing current CertLoader state. 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool certificates_loaded_; 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool certificates_update_required_; 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool certificates_update_running_; 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The user-specific NSS certificate database from which the certificates 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // should be loaded. 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::NSSCertDatabase* database_; 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Set during tests if |IsHardwareBacked()| should always return true. 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool force_hardware_backed_for_test_; 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Cached Certificates loaded from the database. 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<net::CertificateList> cert_list_; 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ThreadChecker thread_checker_; 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::WeakPtrFactory<CertLoader> weak_factory_; 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CertLoader); 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace chromeos 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 143558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif // CHROMEOS_CERT_LOADER_H_ 144