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

Side by Side Diff: base/nss_util.cc

Issue 6684018: Initialize NSS with no DB in the renderer process (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleanup] Created 9 years, 9 months 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "base/nss_util.h" 5 #include "base/nss_util.h"
6 #include "base/nss_util_internal.h" 6 #include "base/nss_util_internal.h"
7 7
8 #include <nss.h> 8 #include <nss.h>
9 #include <plarena.h> 9 #include <plarena.h>
10 #include <prerror.h> 10 #include <prerror.h>
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 return PK11_ReferenceSlot(real_db_slot_); 197 return PK11_ReferenceSlot(real_db_slot_);
198 return PK11_GetInternalKeySlot(); 198 return PK11_GetInternalKeySlot();
199 } 199 }
200 200
201 #if defined(USE_NSS) 201 #if defined(USE_NSS)
202 Lock* write_lock() { 202 Lock* write_lock() {
203 return &write_lock_; 203 return &write_lock_;
204 } 204 }
205 #endif // defined(USE_NSS) 205 #endif // defined(USE_NSS)
206 206
207 // This method is used to force NSS to ne initialized without a DB.
208 // Call this method before NSSInitSingleton() is constructed.
209 static void ForceNoDBInit() {
210 force_nodb_init_ = true;
211 }
212
207 private: 213 private:
208 friend struct DefaultLazyInstanceTraits<NSSInitSingleton>; 214 friend struct DefaultLazyInstanceTraits<NSSInitSingleton>;
209 215
210 NSSInitSingleton() 216 NSSInitSingleton()
211 : real_db_slot_(NULL), 217 : real_db_slot_(NULL),
212 test_db_slot_(NULL), 218 test_db_slot_(NULL),
213 root_(NULL), 219 root_(NULL),
214 chromeos_user_logged_in_(false) { 220 chromeos_user_logged_in_(false) {
215 EnsureNSPRInit(); 221 EnsureNSPRInit();
216 222
(...skipping 12 matching lines...) Expand all
229 LOG(ERROR) << "NSS_VersionCheck(\"3.12.3\") failed. " 235 LOG(ERROR) << "NSS_VersionCheck(\"3.12.3\") failed. "
230 "We depend on NSS >= 3.12.3, and this error is not fatal " 236 "We depend on NSS >= 3.12.3, and this error is not fatal "
231 "only because many people have busted NSS setups (for " 237 "only because many people have busted NSS setups (for "
232 "example, using the wrong version of NSPR). " 238 "example, using the wrong version of NSPR). "
233 "Please upgrade to the latest NSS and NSPR, and if you " 239 "Please upgrade to the latest NSS and NSPR, and if you "
234 "still get this error, contact your distribution " 240 "still get this error, contact your distribution "
235 "maintainer."; 241 "maintainer.";
236 } 242 }
237 243
238 SECStatus status = SECFailure; 244 SECStatus status = SECFailure;
245 bool nodb_init = force_nodb_init_;
246
239 #if !defined(USE_NSS) 247 #if !defined(USE_NSS)
240 // Use the system certificate store, so initialize NSS without database. 248 // Use the system certificate store, so initialize NSS without database.
241 status = NSS_NoDB_Init(NULL); 249 nodb_init = true;
242 if (status != SECSuccess) { 250 #endif
243 LOG(ERROR) << "Error initializing NSS without a persistent "
244 "database: NSS error code " << PR_GetError();
245 }
246 #else
247 FilePath database_dir = GetInitialConfigDirectory();
248 if (!database_dir.empty()) {
249 // This duplicates the work which should have been done in
250 // EarlySetupForNSSInit. However, this function is idempotent so there's
251 // no harm done.
252 UseLocalCacheOfNSSDatabaseIfNFS(database_dir);
253 251
254 // Initialize with a persistent database (likely, ~/.pki/nssdb). 252 if (nodb_init) {
255 // Use "sql:" which can be shared by multiple processes safely.
256 std::string nss_config_dir =
257 StringPrintf("sql:%s", database_dir.value().c_str());
258 #if defined(OS_CHROMEOS)
259 status = NSS_Init(nss_config_dir.c_str());
260 #else
261 status = NSS_InitReadWrite(nss_config_dir.c_str());
262 #endif
263 if (status != SECSuccess) {
264 LOG(ERROR) << "Error initializing NSS with a persistent "
265 "database (" << nss_config_dir
266 << "): NSS error code " << PR_GetError();
267 }
268 }
269 if (status != SECSuccess) {
270 LOG(WARNING) << "Initialize NSS without a persistent database "
271 "(~/.pki/nssdb).";
272 status = NSS_NoDB_Init(NULL); 253 status = NSS_NoDB_Init(NULL);
273 if (status != SECSuccess) { 254 if (status != SECSuccess) {
274 LOG(ERROR) << "Error initializing NSS without a persistent " 255 LOG(ERROR) << "Error initializing NSS without a persistent "
275 "database: NSS error code " << PR_GetError(); 256 "database: NSS error code " << PR_GetError();
276 return;
277 } 257 }
258 } else {
259 FilePath database_dir = GetInitialConfigDirectory();
260 if (!database_dir.empty()) {
261 // This duplicates the work which should have been done in
262 // EarlySetupForNSSInit. However, this function is idempotent so
263 // there's no harm done.
264 UseLocalCacheOfNSSDatabaseIfNFS(database_dir);
265
266 // Initialize with a persistent database (likely, ~/.pki/nssdb).
267 // Use "sql:" which can be shared by multiple processes safely.
268 std::string nss_config_dir =
269 StringPrintf("sql:%s", database_dir.value().c_str());
270 #if defined(OS_CHROMEOS)
271 status = NSS_Init(nss_config_dir.c_str());
272 #else
273 status = NSS_InitReadWrite(nss_config_dir.c_str());
274 #endif
275 if (status != SECSuccess) {
276 LOG(ERROR) << "Error initializing NSS with a persistent "
277 "database (" << nss_config_dir
278 << "): NSS error code " << PR_GetError();
279 }
280 }
281 if (status != SECSuccess) {
282 LOG(WARNING) << "Initialize NSS without a persistent database "
283 "(~/.pki/nssdb).";
284 status = NSS_NoDB_Init(NULL);
285 if (status != SECSuccess) {
286 LOG(ERROR) << "Error initializing NSS without a persistent "
287 "database: NSS error code " << PR_GetError();
288 return;
289 }
290 }
291
292 PK11_SetPasswordFunc(PKCS11PasswordFunc);
293
294 // If we haven't initialized the password for the NSS databases,
295 // initialize an empty-string password so that we don't need to
296 // log in.
297 PK11SlotInfo* slot = PK11_GetInternalKeySlot();
298 if (slot) {
299 // PK11_InitPin may write to the keyDB, but no other thread can use NSS
300 // yet, so we don't need to lock.
301 if (PK11_NeedUserInit(slot))
302 PK11_InitPin(slot, NULL, NULL);
303 PK11_FreeSlot(slot);
304 }
305
306 root_ = InitDefaultRootCerts();
278 } 307 }
279
280 PK11_SetPasswordFunc(PKCS11PasswordFunc);
281
282 // If we haven't initialized the password for the NSS databases,
283 // initialize an empty-string password so that we don't need to
284 // log in.
285 PK11SlotInfo* slot = PK11_GetInternalKeySlot();
286 if (slot) {
287 // PK11_InitPin may write to the keyDB, but no other thread can use NSS
288 // yet, so we don't need to lock.
289 if (PK11_NeedUserInit(slot))
290 PK11_InitPin(slot, NULL, NULL);
291 PK11_FreeSlot(slot);
292 }
293
294 root_ = InitDefaultRootCerts();
295 #endif // !defined(USE_NSS)
296 } 308 }
297 309
298 // NOTE(willchan): We don't actually execute this code since we leak NSS to 310 // NOTE(willchan): We don't actually execute this code since we leak NSS to
299 // prevent non-joinable threads from using NSS after it's already been shut 311 // prevent non-joinable threads from using NSS after it's already been shut
300 // down. 312 // down.
301 ~NSSInitSingleton() { 313 ~NSSInitSingleton() {
302 if (real_db_slot_) { 314 if (real_db_slot_) {
303 SECMOD_CloseUserDB(real_db_slot_); 315 SECMOD_CloseUserDB(real_db_slot_);
304 PK11_FreeSlot(real_db_slot_); 316 PK11_FreeSlot(real_db_slot_);
305 real_db_slot_ = NULL; 317 real_db_slot_ = NULL;
(...skipping 24 matching lines...) Expand all
330 if (PK11_NeedUserInit(db_slot)) 342 if (PK11_NeedUserInit(db_slot))
331 PK11_InitPin(db_slot, NULL, NULL); 343 PK11_InitPin(db_slot, NULL, NULL);
332 } 344 }
333 else { 345 else {
334 LOG(ERROR) << "Error opening persistent database (" << modspec 346 LOG(ERROR) << "Error opening persistent database (" << modspec
335 << "): NSS error code " << PR_GetError(); 347 << "): NSS error code " << PR_GetError();
336 } 348 }
337 return db_slot; 349 return db_slot;
338 } 350 }
339 351
352 // If this is set to true NSS is forced to be initialized without a DB.
353 static bool force_nodb_init_;
354
340 PK11SlotInfo* real_db_slot_; // Overrides internal key slot if non-NULL. 355 PK11SlotInfo* real_db_slot_; // Overrides internal key slot if non-NULL.
341 PK11SlotInfo* test_db_slot_; // Overrides internal key slot and real_db_slot_ 356 PK11SlotInfo* test_db_slot_; // Overrides internal key slot and real_db_slot_
342 SECMODModule *root_; 357 SECMODModule *root_;
343 bool chromeos_user_logged_in_; 358 bool chromeos_user_logged_in_;
344 #if defined(USE_NSS) 359 #if defined(USE_NSS)
345 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 360 // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011
346 // is fixed, we will no longer need the lock. 361 // is fixed, we will no longer need the lock.
347 Lock write_lock_; 362 Lock write_lock_;
348 #endif // defined(USE_NSS) 363 #endif // defined(USE_NSS)
349 }; 364 };
350 365
366 bool NSSInitSingleton::force_nodb_init_ = false;
367
351 LazyInstance<NSSInitSingleton, LeakyLazyInstanceTraits<NSSInitSingleton> > 368 LazyInstance<NSSInitSingleton, LeakyLazyInstanceTraits<NSSInitSingleton> >
352 g_nss_singleton(LINKER_INITIALIZED); 369 g_nss_singleton(LINKER_INITIALIZED);
353 370
354 } // namespace 371 } // namespace
355 372
356 #if defined(USE_NSS) 373 #if defined(USE_NSS)
357 void EarlySetupForNSSInit() { 374 void EarlySetupForNSSInit() {
358 FilePath database_dir = GetInitialConfigDirectory(); 375 FilePath database_dir = GetInitialConfigDirectory();
359 if (!database_dir.empty()) 376 if (!database_dir.empty())
360 UseLocalCacheOfNSSDatabaseIfNFS(database_dir); 377 UseLocalCacheOfNSSDatabaseIfNFS(database_dir);
361 } 378 }
362 #endif 379 #endif
363 380
364 void EnsureNSPRInit() { 381 void EnsureNSPRInit() {
365 g_nspr_singleton.Get(); 382 g_nspr_singleton.Get();
366 } 383 }
367 384
368 void EnsureNSSInit() { 385 void EnsureNSSInit() {
369 // Initializing SSL causes us to do blocking IO. 386 // Initializing SSL causes us to do blocking IO.
370 // Temporarily allow it until we fix 387 // Temporarily allow it until we fix
371 // http://code.google.com/p/chromium/issues/detail?id=59847 388 // http://code.google.com/p/chromium/issues/detail?id=59847
372 ThreadRestrictions::ScopedAllowIO allow_io; 389 ThreadRestrictions::ScopedAllowIO allow_io;
373 g_nss_singleton.Get(); 390 g_nss_singleton.Get();
374 } 391 }
375 392
393 void EnsureNSSNoDBInit() {
394 ThreadRestrictions::ScopedAllowIO allow_io;
395
396 // Force NSS to be initialized without a DB.
397 NSSInitSingleton::ForceNoDBInit();
398 g_nss_singleton.Get();
399 }
400
401 void DisableNSSForkCheck() {
402 scoped_ptr<Environment> env(Environment::Create());
403 env->SetVar("NSS_STRICT_NOFORK", "DISABLED");
404 }
405
376 bool CheckNSSVersion(const char* version) { 406 bool CheckNSSVersion(const char* version) {
377 return !!NSS_VersionCheck(version); 407 return !!NSS_VersionCheck(version);
378 } 408 }
379 409
380 #if defined(USE_NSS) 410 #if defined(USE_NSS)
381 bool OpenTestNSSDB(const FilePath& path, const char* description) { 411 bool OpenTestNSSDB(const FilePath& path, const char* description) {
382 return g_nss_singleton.Get().OpenTestNSSDB(path, description); 412 return g_nss_singleton.Get().OpenTestNSSDB(path, description);
383 } 413 }
384 414
385 void CloseTestNSSDB() { 415 void CloseTestNSSDB() {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 exploded.millisecond = prxtime.tm_usec / 1000; 457 exploded.millisecond = prxtime.tm_usec / 1000;
428 458
429 return Time::FromUTCExploded(exploded); 459 return Time::FromUTCExploded(exploded);
430 } 460 }
431 461
432 PK11SlotInfo* GetDefaultNSSKeySlot() { 462 PK11SlotInfo* GetDefaultNSSKeySlot() {
433 return g_nss_singleton.Get().GetDefaultKeySlot(); 463 return g_nss_singleton.Get().GetDefaultKeySlot();
434 } 464 }
435 465
436 } // namespace base 466 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698