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