1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file. 4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifndef CRYPTO_NSS_UTIL_H_ 6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define CRYPTO_NSS_UTIL_H_ 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#pragma once 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <string> 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/basictypes.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(USE_NSS) 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass FilePath; 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif // defined(USE_NSS) 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace base { 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass Lock; 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass Time; 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace base 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// This file specifically doesn't depend on any NSS or NSPR headers because it 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// is included by various (non-crypto) parts of chrome to call the 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// initialization functions. 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace crypto { 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(USE_NSS) 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// EarlySetupForNSSInit performs lightweight setup which must occur before the 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// process goes multithreaded. This does not initialise NSS. For test, see 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// EnsureNSSInit. 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid EarlySetupForNSSInit(); 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Initialize NRPR if it isn't already initialized. This function is 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// thread-safe, and NSPR will only ever be initialized once. 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid EnsureNSPRInit(); 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Initialize NSS if it isn't already initialized. This must be called before 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// any other NSS functions. This function is thread-safe, and NSS will only 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ever be initialized once. 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid EnsureNSSInit(); 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Call this before calling EnsureNSSInit() will force NSS to initialize 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// without a persistent DB. This is used for the special case where access of 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// persistent DB is prohibited. 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(hclam): Isolate loading default root certs. 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// NSS will be initialized without loading any user security modules, including 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// the built-in root certificates module. User security modules need to be 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// loaded manually after NSS initialization. 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// If EnsureNSSInit() is called before then this function has no effect. 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Calling this method only has effect on Linux. 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// WARNING: Use this with caution. 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ForceNSSNoDBInit(); 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// This methods is used to disable checks in NSS when used in a forked process. 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// NSS checks whether it is running a forked process to avoid problems when 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// using user security modules in a forked process. However if we are sure 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// there are no modules loaded before the process is forked then there is no 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// harm disabling the check. 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// This method must be called before EnsureNSSInit() to take effect. 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// WARNING: Use this with caution. 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid DisableNSSForkCheck(); 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Load NSS library files. This function has no effect on Mac and Windows. 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// This loads the necessary NSS library files so that NSS can be initialized 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// after loading additional library files is disallowed, for example when the 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// sandbox is active. 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Note that this does not load libnssckbi.so which contains the root 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// certificates. 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid LoadNSSLibraries(); 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Check if the current NSS version is greater than or equals to |version|. 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// A sample version string is "3.12.3". 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool CheckNSSVersion(const char* version); 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS) 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Open the r/w nssdb that's stored inside the user's encrypted home 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// directory. This is the default slot returned by 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// GetPublicNSSKeySlot(). 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid OpenPersistentNSSDB(); 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// A delegate class that we can use it to access the cros API for 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// communication with cryptohomed and the TPM. 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass TPMTokenInfoDelegate { 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public: 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TPMTokenInfoDelegate(); 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual ~TPMTokenInfoDelegate(); 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual bool IsTokenReady() const = 0; 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void GetTokenInfo(std::string* token_name, 97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string* user_pin) const = 0; 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Indicates that NSS should load the opencryptoki library so that we 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// can access the TPM through NSS. Once this is called, 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// GetPrivateNSSKeySlot() will return the TPM slot if one was found. 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Takes ownership of the passed-in delegate object so it can access 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// the cros library to talk to cryptohomed. 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid EnableTPMTokenForNSS(TPMTokenInfoDelegate* delegate); 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Get name and user PIN for the built-in TPM token on ChromeOS. 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Either one can safely be NULL. Should only be called after 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// EnableTPMTokenForNSS has been called with a non-null delegate. 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GetTPMTokenInfo(std::string* token_name, std::string* user_pin); 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Returns true if the TPM is owned and PKCS#11 initialized with the 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// user and security officer PINs, and has been enabled in NSS by 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// calling EnableTPMForNSS, and opencryptoki has been successfully 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// loaded into NSS. 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool IsTPMTokenReady(); 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Convert a NSS PRTime value into a base::Time object. 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// We use a int64 instead of PRTime here to avoid depending on NSPR headers. 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbase::Time PRTimeToBaseTime(int64 prtime); 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(USE_NSS) 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Exposed for unittests only. |path| should be an existing directory under 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// which the DB files will be placed. |description| is a user-visible name for 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// the DB, as a utf8 string, which will be truncated at 32 bytes. 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool OpenTestNSSDB(const FilePath& path, const char* description); 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CloseTestNSSDB(); 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// NSS has a bug which can cause a deadlock or stall in some cases when writing 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// to the certDB and keyDB. It also has a bug which causes concurrent key pair 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// generations to scribble over each other. To work around this, we synchronize 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// writes to the NSS databases with a global lock. The lock is hidden beneath a 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// function for easy disabling when the bug is fixed. Callers should allow for 135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// it to return NULL in the future. 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// See https://bugzilla.mozilla.org/show_bug.cgi?id=564011 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbase::Lock* GetNSSWriteLock(); 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// A helper class that acquires the NSS write Lock while the AutoNSSWriteLock 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// is in scope. 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass AutoNSSWriteLock { 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public: 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AutoNSSWriteLock(); 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ~AutoNSSWriteLock(); 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private: 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::Lock *lock_; 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DISALLOW_COPY_AND_ASSIGN(AutoNSSWriteLock); 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif // defined(USE_NSS) 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace crypto 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif // CRYPTO_NSS_UTIL_H_ 156