Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1453)

Side by Side Diff: net/cert/nss_cert_database.cc

Issue 18121007: *WIP* Store NSS slots per profile. Move keygen to chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more refactoring Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/cert/nss_cert_database.h ('k') | net/cert/nss_cert_database_chromeos.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/cert/nss_cert_database.h" 5 #include "net/cert/nss_cert_database.h"
6 6
7 #include <cert.h> 7 #include <cert.h>
8 #include <certdb.h> 8 #include <certdb.h>
9 #include <keyhi.h> 9 #include <keyhi.h>
10 #include <pk11pub.h> 10 #include <pk11pub.h>
11 #include <secmod.h> 11 #include <secmod.h>
12 12
13 #include "base/lazy_instance.h"
13 #include "base/logging.h" 14 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/singleton.h"
16 #include "base/observer_list_threadsafe.h" 16 #include "base/observer_list_threadsafe.h"
17 #include "crypto/nss_util.h" 17 #include "crypto/nss_util.h"
18 #include "crypto/nss_util_internal.h" 18 #include "crypto/nss_util_internal.h"
19 #include "crypto/scoped_nss_types.h" 19 #include "crypto/scoped_nss_types.h"
20 #include "net/base/crypto_module.h" 20 #include "net/base/crypto_module.h"
21 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
22 #include "net/cert/cert_database.h" 22 #include "net/cert/cert_database.h"
23 #include "net/cert/x509_certificate.h" 23 #include "net/cert/x509_certificate.h"
24 #include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h" 24 #include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h"
25 #include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h" 25 #include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h"
26 26
27 // In NSS 3.13, CERTDB_VALID_PEER was renamed CERTDB_TERMINAL_RECORD. So we use 27 // In NSS 3.13, CERTDB_VALID_PEER was renamed CERTDB_TERMINAL_RECORD. So we use
28 // the new name of the macro. 28 // the new name of the macro.
29 #if !defined(CERTDB_TERMINAL_RECORD) 29 #if !defined(CERTDB_TERMINAL_RECORD)
30 #define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER 30 #define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER
31 #endif 31 #endif
32 32
33 // PSM = Mozilla's Personal Security Manager. 33 // PSM = Mozilla's Personal Security Manager.
34 namespace psm = mozilla_security_manager; 34 namespace psm = mozilla_security_manager;
35 35
36 namespace net { 36 namespace net {
37 37
38 namespace {
39 base::LazyInstance<NSSCertDatabase>::Leaky
40 g_nss_cert_database = LAZY_INSTANCE_INITIALIZER;
41 } // namespace
42
43
38 NSSCertDatabase::ImportCertFailure::ImportCertFailure( 44 NSSCertDatabase::ImportCertFailure::ImportCertFailure(
39 const scoped_refptr<X509Certificate>& cert, 45 const scoped_refptr<X509Certificate>& cert,
40 int err) 46 int err)
41 : certificate(cert), net_error(err) {} 47 : certificate(cert), net_error(err) {}
42 48
43 NSSCertDatabase::ImportCertFailure::~ImportCertFailure() {} 49 NSSCertDatabase::ImportCertFailure::~ImportCertFailure() {}
44 50
51 // Helper that observes events from a CertDatabaseSource and forwards them to
52 // the given CertDatabase.
53 class NSSCertDatabase::Notifier : public CertDatabaseSource::Observer {
54 public:
55 Notifier(NSSCertDatabase* cert_db) : cert_db_(cert_db) {}
56
57 virtual ~Notifier() {}
58
59 // CertDatabaseSource::Observer implementation:
60 virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE {
61 cert_db_->NotifyObserversOfCertAdded(cert);
62 }
63
64 virtual void OnCertRemoved(const X509Certificate* cert) OVERRIDE {
65 cert_db_->NotifyObserversOfCertRemoved(cert);
66 }
67
68 virtual void OnCACertChanged(const X509Certificate* cert) OVERRIDE {
69 cert_db_->NotifyObserversOfCACertChanged(cert);
70 }
71
72 private:
73 NSSCertDatabase* cert_db_;
74
75 DISALLOW_COPY_AND_ASSIGN(Notifier);
76 };
77
78 // static
79 NSSCertDatabase* NSSCertDatabase::GetInstanceNoWarn() {
80 return &g_nss_cert_database.Get();
81 //return Singleton<NSSCertDatabase,
82 // LeakySingletonTraits<NSSCertDatabase> >::get();
83 }
84
45 // static 85 // static
46 NSSCertDatabase* NSSCertDatabase::GetInstance() { 86 NSSCertDatabase* NSSCertDatabase::GetInstance() {
47 return Singleton<NSSCertDatabase, 87 #if defined(OS_CHROMEOS)
48 LeakySingletonTraits<NSSCertDatabase> >::get(); 88 LOG(WARNING) << "Using global NSSCertDatabase. Consider using "
89 << "NSSCertDatabaseChromeOS::GetForUser instead.";
90 #endif
91 return NSSCertDatabase::GetInstanceNoWarn();
49 } 92 }
50 93
51 NSSCertDatabase::NSSCertDatabase() 94 NSSCertDatabase::NSSCertDatabase()
52 : observer_list_(new ObserverListThreadSafe<Observer>) { 95 : observer_list_(new ObserverListThreadSafe<Observer>),
53 crypto::EnsureNSSInit(); 96 notifier_(new Notifier(this)) {
97 // This also makes sure that NSS has been initialized.
98 CertDatabase::GetInstance()->AddSource(this);
99
54 psm::EnsurePKCS12Init(); 100 psm::EnsurePKCS12Init();
55 } 101 }
56 102
57 NSSCertDatabase::~NSSCertDatabase() {} 103 NSSCertDatabase::~NSSCertDatabase() {}
58 104
59 void NSSCertDatabase::ListCerts(CertificateList* certs) { 105 void NSSCertDatabase::ListCerts(CertificateList* certs) {
60 certs->clear(); 106 certs->clear();
61 107
62 CERTCertList* cert_list = PK11_ListCerts(PK11CertListUnique, NULL); 108 CERTCertList* cert_list = PK11_ListCerts(PK11CertListUnique, NULL);
63 CERTCertListNode* node; 109 CERTCertListNode* node;
64 for (node = CERT_LIST_HEAD(cert_list); 110 for (node = CERT_LIST_HEAD(cert_list);
65 !CERT_LIST_END(node, cert_list); 111 !CERT_LIST_END(node, cert_list);
66 node = CERT_LIST_NEXT(node)) { 112 node = CERT_LIST_NEXT(node)) {
67 certs->push_back(X509Certificate::CreateFromHandle( 113 certs->push_back(X509Certificate::CreateFromHandle(
68 node->cert, X509Certificate::OSCertHandles())); 114 node->cert, X509Certificate::OSCertHandles()));
69 } 115 }
70 CERT_DestroyCertList(cert_list); 116 CERT_DestroyCertList(cert_list);
71 } 117 }
72 118
73 CryptoModule* NSSCertDatabase::GetPublicModule() const { 119 CryptoModule* NSSCertDatabase::GetPublicModule() const {
74 CryptoModule* module = 120 crypto::ScopedPK11Slot slot(GetPublicSlot());
75 CryptoModule::CreateFromHandle(crypto::GetPublicNSSKeySlot()); 121 CryptoModule* module = CryptoModule::CreateFromHandle(slot.get());
76 // The module is already referenced when returned from
77 // GetPublicNSSKeySlot, so we need to deref it once.
78 PK11_FreeSlot(module->os_module_handle());
79 122
80 return module; 123 return module;
81 } 124 }
82 125
83 CryptoModule* NSSCertDatabase::GetPrivateModule() const { 126 CryptoModule* NSSCertDatabase::GetPrivateModule() const {
84 CryptoModule* module = 127 crypto::ScopedPK11Slot slot(GetPrivateSlot());
85 CryptoModule::CreateFromHandle(crypto::GetPrivateNSSKeySlot()); 128 CryptoModule* module = CryptoModule::CreateFromHandle(slot.get());
86 // The module is already referenced when returned from
87 // GetPrivateNSSKeySlot, so we need to deref it once.
88 PK11_FreeSlot(module->os_module_handle());
89 129
90 return module; 130 return module;
91 } 131 }
92 132
133 crypto::ScopedPK11Slot NSSCertDatabase::GetPublicSlot() const {
134 return crypto::ScopedPK11Slot(crypto::GetPublicNSSKeySlot());
135 }
136
137 crypto::ScopedPK11Slot NSSCertDatabase::GetPrivateSlot() const {
138 return crypto::ScopedPK11Slot(crypto::GetPrivateNSSKeySlot());
139 }
140
93 void NSSCertDatabase::ListModules(CryptoModuleList* modules, 141 void NSSCertDatabase::ListModules(CryptoModuleList* modules,
94 bool need_rw) const { 142 bool need_rw) const {
95 modules->clear(); 143 modules->clear();
96 144
97 // The wincx arg is unused since we don't call PK11_SetIsLoggedInFunc. 145 // The wincx arg is unused since we don't call PK11_SetIsLoggedInFunc.
98 crypto::ScopedPK11SlotList slot_list( 146 crypto::ScopedPK11SlotList slot_list(
99 PK11_GetAllTokens(CKM_INVALID_MECHANISM, 147 PK11_GetAllTokens(CKM_INVALID_MECHANISM,
100 need_rw ? PR_TRUE : PR_FALSE, // needRW 148 need_rw ? PR_TRUE : PR_FALSE, // needRW
101 PR_TRUE, // loadCerts (unused) 149 PR_TRUE, // loadCerts (unused)
102 NULL)); // wincx 150 NULL)); // wincx
103 if (!slot_list) { 151 if (!slot_list) {
104 LOG(ERROR) << "PK11_GetAllTokens failed: " << PORT_GetError(); 152 LOG(ERROR) << "PK11_GetAllTokens failed: " << PORT_GetError();
105 return; 153 return;
106 } 154 }
107 155
108 PK11SlotListElement* slot_element = PK11_GetFirstSafe(slot_list.get()); 156 PK11SlotListElement* slot_element = PK11_GetFirstSafe(slot_list.get());
109 while (slot_element) { 157 while (slot_element) {
110 modules->push_back(CryptoModule::CreateFromHandle(slot_element->slot)); 158 modules->push_back(CryptoModule::CreateFromHandle(slot_element->slot));
111 slot_element = PK11_GetNextSafe(slot_list.get(), slot_element, 159 slot_element = PK11_GetNextSafe(slot_list.get(), slot_element,
112 PR_FALSE); // restart 160 PR_FALSE); // restart
113 } 161 }
114 } 162 }
115 163
116 int NSSCertDatabase::ImportFromPKCS12( 164 int NSSCertDatabase::ImportFromPKCS12(
117 CryptoModule* module, 165 CryptoModule* module,
118 const std::string& data, 166 const std::string& data,
119 const base::string16& password, 167 const base::string16& password,
120 bool is_extractable, 168 bool is_extractable,
121 net::CertificateList* imported_certs) { 169 net::CertificateList* imported_certs) {
170 DVLOG(1) << __func__ << " "
171 << PK11_GetModuleID(module->os_module_handle()) << ":"
172 << PK11_GetSlotID(module->os_module_handle());
122 int result = psm::nsPKCS12Blob_Import(module->os_module_handle(), 173 int result = psm::nsPKCS12Blob_Import(module->os_module_handle(),
123 data.data(), data.size(), 174 data.data(), data.size(),
124 password, 175 password,
125 is_extractable, 176 is_extractable,
126 imported_certs); 177 imported_certs);
127 if (result == net::OK) 178 if (result == net::OK)
128 NotifyObserversOfCertAdded(NULL); 179 NotifyObserversOfCertAdded(NULL);
129 180
130 return result; 181 return result;
131 } 182 }
(...skipping 17 matching lines...) Expand all
149 X509Certificate* certn_2 = certificates[certificates.size() - 2].get(); 200 X509Certificate* certn_2 = certificates[certificates.size() - 2].get();
150 X509Certificate* certn_1 = certificates[certificates.size() - 1].get(); 201 X509Certificate* certn_1 = certificates[certificates.size() - 1].get();
151 202
152 if (CERT_CompareName(&cert1->os_cert_handle()->issuer, 203 if (CERT_CompareName(&cert1->os_cert_handle()->issuer,
153 &cert0->os_cert_handle()->subject) == SECEqual) 204 &cert0->os_cert_handle()->subject) == SECEqual)
154 return cert0; 205 return cert0;
155 if (CERT_CompareName(&certn_2->os_cert_handle()->issuer, 206 if (CERT_CompareName(&certn_2->os_cert_handle()->issuer,
156 &certn_1->os_cert_handle()->subject) == SECEqual) 207 &certn_1->os_cert_handle()->subject) == SECEqual)
157 return certn_1; 208 return certn_1;
158 209
159 VLOG(1) << "certificate list is not a hierarchy"; 210 DVLOG(1) << "certificate list is not a hierarchy";
160 return cert0; 211 return cert0;
161 } 212 }
162 213
163 bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates, 214 bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates,
164 TrustBits trust_bits, 215 TrustBits trust_bits,
165 ImportCertFailureList* not_imported) { 216 ImportCertFailureList* not_imported) {
166 X509Certificate* root = FindRootInList(certificates); 217 X509Certificate* root = FindRootInList(certificates);
167 bool success = psm::ImportCACerts(certificates, root, trust_bits, 218 bool success = psm::ImportCACerts(
168 not_imported); 219 GetPublicSlot(),
220 certificates,
221 root,
222 trust_bits,
223 not_imported);
169 if (success) 224 if (success)
170 NotifyObserversOfCACertChanged(NULL); 225 NotifyObserversOfCACertChanged(NULL);
171 226
172 return success; 227 return success;
173 } 228 }
174 229
175 bool NSSCertDatabase::ImportServerCert(const CertificateList& certificates, 230 bool NSSCertDatabase::ImportServerCert(const CertificateList& certificates,
176 TrustBits trust_bits, 231 TrustBits trust_bits,
177 ImportCertFailureList* not_imported) { 232 ImportCertFailureList* not_imported) {
178 return psm::ImportServerCert(certificates, trust_bits, not_imported); 233 return psm::ImportServerCert(
234 GetPublicSlot(),
235 certificates,
236 trust_bits,
237 not_imported);
179 } 238 }
180 239
181 NSSCertDatabase::TrustBits NSSCertDatabase::GetCertTrust( 240 NSSCertDatabase::TrustBits NSSCertDatabase::GetCertTrust(
182 const X509Certificate* cert, 241 const X509Certificate* cert,
183 CertType type) const { 242 CertType type) const {
184 CERTCertTrust trust; 243 CERTCertTrust trust;
185 SECStatus srv = CERT_GetCertTrust(cert->os_cert_handle(), &trust); 244 SECStatus srv = CERT_GetCertTrust(cert->os_cert_handle(), &trust);
186 if (srv != SECSuccess) { 245 if (srv != SECSuccess) {
187 LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError(); 246 LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError();
188 return TRUST_DEFAULT; 247 return TRUST_DEFAULT;
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 383 }
325 384
326 void NSSCertDatabase::AddObserver(Observer* observer) { 385 void NSSCertDatabase::AddObserver(Observer* observer) {
327 observer_list_->AddObserver(observer); 386 observer_list_->AddObserver(observer);
328 } 387 }
329 388
330 void NSSCertDatabase::RemoveObserver(Observer* observer) { 389 void NSSCertDatabase::RemoveObserver(Observer* observer) {
331 observer_list_->RemoveObserver(observer); 390 observer_list_->RemoveObserver(observer);
332 } 391 }
333 392
393 void NSSCertDatabase::AddSource(CertDatabaseSource* source) {
394 source->AddObserver(this->notifier_.get());
395 }
396
334 void NSSCertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) { 397 void NSSCertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) {
335 observer_list_->Notify(&Observer::OnCertAdded, make_scoped_refptr(cert)); 398 observer_list_->Notify(&Observer::OnCertAdded, make_scoped_refptr(cert));
336 } 399 }
337 400
338 void NSSCertDatabase::NotifyObserversOfCertRemoved( 401 void NSSCertDatabase::NotifyObserversOfCertRemoved(
339 const X509Certificate* cert) { 402 const X509Certificate* cert) {
340 observer_list_->Notify(&Observer::OnCertRemoved, make_scoped_refptr(cert)); 403 observer_list_->Notify(&Observer::OnCertRemoved, make_scoped_refptr(cert));
341 } 404 }
342 405
343 void NSSCertDatabase::NotifyObserversOfCACertChanged( 406 void NSSCertDatabase::NotifyObserversOfCACertChanged(
344 const X509Certificate* cert) { 407 const X509Certificate* cert) {
345 observer_list_->Notify( 408 observer_list_->Notify(
346 &Observer::OnCACertChanged, make_scoped_refptr(cert)); 409 &Observer::OnCACertChanged, make_scoped_refptr(cert));
347 } 410 }
348 411
349 } // namespace net 412 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/nss_cert_database.h ('k') | net/cert/nss_cert_database_chromeos.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698