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