| OLD | NEW |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 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_init.h" | 5 #include "base/nss_init.h" |
| 6 | 6 |
| 7 #include <nss.h> | 7 #include <nss.h> |
| 8 #include <plarena.h> | 8 #include <plarena.h> |
| 9 #include <prerror.h> | 9 #include <prerror.h> |
| 10 #include <prinit.h> | 10 #include <prinit.h> |
| 11 | 11 |
| 12 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 | 12 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 |
| 13 // until NSS 3.12.2 comes out and we update to it. | 13 // until NSS 3.12.2 comes out and we update to it. |
| 14 #define Lock FOO_NSS_Lock | 14 #define Lock FOO_NSS_Lock |
| 15 #include <secmod.h> | 15 #include <secmod.h> |
| 16 #include <ssl.h> | 16 #include <ssl.h> |
| 17 #undef Lock | 17 #undef Lock |
| 18 | 18 |
| 19 #include "base/file_util.h" | 19 #include "base/file_util.h" |
| 20 #include "base/logging.h" | 20 #include "base/logging.h" |
| 21 #include "base/singleton.h" | 21 #include "base/singleton.h" |
| 22 #include "base/string_util.h" |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 26 std::string GetDefaultConfigDirectory() { |
| 27 const char* home = getenv("HOME"); |
| 28 if (home == NULL) { |
| 29 LOG(ERROR) << "$HOME is not set."; |
| 30 return ""; |
| 31 } |
| 32 FilePath dir(home); |
| 33 dir = dir.AppendASCII(".pki").AppendASCII("nssdb"); |
| 34 if (!file_util::CreateDirectory(dir)) { |
| 35 LOG(ERROR) << "Failed to create ~/.pki/nssdb directory."; |
| 36 return ""; |
| 37 } |
| 38 return dir.value(); |
| 39 } |
| 40 |
| 25 // Load nss's built-in root certs. | 41 // Load nss's built-in root certs. |
| 26 SECMODModule *InitDefaultRootCerts() { | 42 SECMODModule *InitDefaultRootCerts() { |
| 27 const char* kModulePath = "libnssckbi.so"; | 43 const char* kModulePath = "libnssckbi.so"; |
| 28 char modparams[1024]; | 44 char modparams[1024]; |
| 29 snprintf(modparams, sizeof(modparams), | 45 snprintf(modparams, sizeof(modparams), |
| 30 "name=\"Root Certs\" library=\"%s\"", kModulePath); | 46 "name=\"Root Certs\" library=\"%s\"", kModulePath); |
| 31 SECMODModule *root = SECMOD_LoadUserModule(modparams, NULL, PR_FALSE); | 47 SECMODModule *root = SECMOD_LoadUserModule(modparams, NULL, PR_FALSE); |
| 32 if (root) | 48 if (root) |
| 33 return root; | 49 return root; |
| 34 | 50 |
| 35 // Aw, snap. Can't find/load root cert shared library. | 51 // Aw, snap. Can't find/load root cert shared library. |
| 36 // This will make it hard to talk to anybody via https. | 52 // This will make it hard to talk to anybody via https. |
| 37 NOTREACHED(); | 53 NOTREACHED(); |
| 38 return NULL; | 54 return NULL; |
| 39 } | 55 } |
| 40 | 56 |
| 41 class NSSInitSingleton { | 57 class NSSInitSingleton { |
| 42 public: | 58 public: |
| 43 NSSInitSingleton() { | 59 NSSInitSingleton() { |
| 44 // Initialize without using a persistant database (e.g. ~/.netscape) | 60 SECStatus status; |
| 45 SECStatus status = NSS_NoDB_Init("."); | 61 std::string database_dir = GetDefaultConfigDirectory(); |
| 62 if (!database_dir.empty()) { |
| 63 // Initialize with a persistant database (~/.pki/nssdb). |
| 64 // Use "sql:" which can be shared by multiple processes safely. |
| 65 status = NSS_InitReadWrite( |
| 66 StringPrintf("sql:%s", database_dir.c_str()).c_str()); |
| 67 } else { |
| 68 LOG(WARNING) << "Initialize NSS without using a persistent database " |
| 69 << "(~/.pki/nssdb)."; |
| 70 status = NSS_NoDB_Init("."); |
| 71 } |
| 46 if (status != SECSuccess) { | 72 if (status != SECSuccess) { |
| 47 char buffer[513] = "Couldn't retrieve error"; | 73 char buffer[513] = "Couldn't retrieve error"; |
| 48 PRInt32 err_length = PR_GetErrorTextLength(); | 74 PRInt32 err_length = PR_GetErrorTextLength(); |
| 49 if (err_length > 0 && static_cast<size_t>(err_length) < sizeof(buffer)) | 75 if (err_length > 0 && static_cast<size_t>(err_length) < sizeof(buffer)) |
| 50 PR_GetErrorText(buffer); | 76 PR_GetErrorText(buffer); |
| 51 | 77 |
| 52 NOTREACHED() << "Error calling NSS_NoDB_Init: " << buffer; | 78 NOTREACHED() << "Error initializing NSS: " << buffer; |
| 53 } | 79 } |
| 54 | 80 |
| 55 root_ = InitDefaultRootCerts(); | 81 root_ = InitDefaultRootCerts(); |
| 56 | 82 |
| 57 NSS_SetDomesticPolicy(); | 83 NSS_SetDomesticPolicy(); |
| 58 | 84 |
| 59 // Explicitly enable exactly those ciphers with keys of at least 80 bits | 85 // Explicitly enable exactly those ciphers with keys of at least 80 bits |
| 60 for (int i = 0; i < SSL_NumImplementedCiphers; i++) { | 86 for (int i = 0; i < SSL_NumImplementedCiphers; i++) { |
| 61 SSLCipherSuiteInfo info; | 87 SSLCipherSuiteInfo info; |
| 62 if (SSL_GetCipherSuiteInfo(SSL_ImplementedCiphers[i], &info, | 88 if (SSL_GetCipherSuiteInfo(SSL_ImplementedCiphers[i], &info, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 | 126 |
| 101 } // namespace | 127 } // namespace |
| 102 | 128 |
| 103 namespace base { | 129 namespace base { |
| 104 | 130 |
| 105 void EnsureNSSInit() { | 131 void EnsureNSSInit() { |
| 106 Singleton<NSSInitSingleton>::get(); | 132 Singleton<NSSInitSingleton>::get(); |
| 107 } | 133 } |
| 108 | 134 |
| 109 } // namespace base | 135 } // namespace base |
| OLD | NEW |