summaryrefslogtreecommitdiff
path: root/chromium/crypto
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-05-17 17:24:03 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-06-22 07:51:41 +0000
commit774f54339e5db91f785733232d3950366db65d07 (patch)
tree068e1b47bd1af94d77094ed12b604a6b83d9c22a /chromium/crypto
parentf7eaed5286974984ba5f9e3189d8f49d03e99f81 (diff)
downloadqtwebengine-chromium-774f54339e5db91f785733232d3950366db65d07.tar.gz
BASELINE: Update Chromium to 102.0.5005.57
Change-Id: I885f714bb40ee724c28f94ca6bd8dbdb39915158 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/crypto')
-rw-r--r--chromium/crypto/OWNERS2
-rw-r--r--chromium/crypto/apple_keychain.h2
-rw-r--r--chromium/crypto/ec_private_key_unittest.cc3
-rw-r--r--chromium/crypto/encryptor_unittest.cc37
-rw-r--r--chromium/crypto/hmac_unittest.cc10
-rw-r--r--chromium/crypto/mock_apple_keychain.cc3
-rw-r--r--chromium/crypto/nss_util.cc119
-rw-r--r--chromium/crypto/nss_util.h16
-rw-r--r--chromium/crypto/nss_util_chromeos.cc89
-rw-r--r--chromium/crypto/nss_util_internal.h16
-rw-r--r--chromium/crypto/scoped_test_nss_db.cc4
-rw-r--r--chromium/crypto/sha2.cc2
-rw-r--r--chromium/crypto/symmetric_key.cc15
13 files changed, 233 insertions, 85 deletions
diff --git a/chromium/crypto/OWNERS b/chromium/crypto/OWNERS
index e3db9edc74e..d9697bd1607 100644
--- a/chromium/crypto/OWNERS
+++ b/chromium/crypto/OWNERS
@@ -1,4 +1,4 @@
set noparent
agl@chromium.org
davidben@chromium.org
-rsleevi@chromium.org
+mattm@chromium.org
diff --git a/chromium/crypto/apple_keychain.h b/chromium/crypto/apple_keychain.h
index df10a4f9956..62149c70f82 100644
--- a/chromium/crypto/apple_keychain.h
+++ b/chromium/crypto/apple_keychain.h
@@ -7,8 +7,6 @@
#include <Security/Security.h>
-#include <optional>
-
#include "build/build_config.h"
#include "crypto/crypto_export.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chromium/crypto/ec_private_key_unittest.cc b/chromium/crypto/ec_private_key_unittest.cc
index 20249aac694..50ba4d51552 100644
--- a/chromium/crypto/ec_private_key_unittest.cc
+++ b/chromium/crypto/ec_private_key_unittest.cc
@@ -9,7 +9,6 @@
#include <memory>
#include <vector>
-#include "base/cxx17_backports.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -266,7 +265,7 @@ TEST(ECPrivateKeyUnitTest, LoadOpenSSLKeyTest) {
std::string raw_public_key;
EXPECT_TRUE(keypair_openssl->ExportRawPublicKey(&raw_public_key));
EXPECT_EQ(std::string(reinterpret_cast<const char*>(kOpenSSLRawPublicKey),
- base::size(kOpenSSLRawPublicKey)),
+ std::size(kOpenSSLRawPublicKey)),
raw_public_key);
}
diff --git a/chromium/crypto/encryptor_unittest.cc b/chromium/crypto/encryptor_unittest.cc
index 95c9cc5871a..93f8447d711 100644
--- a/chromium/crypto/encryptor_unittest.cc
+++ b/chromium/crypto/encryptor_unittest.cc
@@ -9,7 +9,6 @@
#include <memory>
#include <string>
-#include "base/cxx17_backports.h"
#include "base/strings/string_number_conversions.h"
#include "crypto/symmetric_key.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -89,7 +88,7 @@ TEST(EncryptorTest, DecryptWrongKey) {
0x48, 0x1D, 0x42, 0xB0, 0xBA, 0x21, 0xB2, 0x0C
};
- ASSERT_EQ(base::size(expected_ciphertext), ciphertext.size());
+ ASSERT_EQ(std::size(expected_ciphertext), ciphertext.size());
for (size_t i = 0; i < ciphertext.size(); ++i) {
ASSERT_EQ(expected_ciphertext[i],
static_cast<unsigned char>(ciphertext[i]));
@@ -262,7 +261,7 @@ void TestAESCTRMultipleDecrypt(
int kTestDecryptSizes[] = { 32, 16, 8 };
int offset = 0;
- for (size_t i = 0; i < base::size(kTestDecryptSizes); ++i) {
+ for (size_t i = 0; i < std::size(kTestDecryptSizes); ++i) {
std::string decrypted;
size_t len = kTestDecryptSizes[i];
EXPECT_TRUE(
@@ -276,33 +275,33 @@ void TestAESCTRMultipleDecrypt(
} // namespace
TEST(EncryptorTest, EncryptAES128CTR) {
- TestAESCTREncrypt(kAES128CTRKey, base::size(kAES128CTRKey),
- kAESCTRInitCounter, base::size(kAESCTRInitCounter),
- kAESCTRPlaintext, base::size(kAESCTRPlaintext),
- kAES128CTRCiphertext, base::size(kAES128CTRCiphertext));
+ TestAESCTREncrypt(kAES128CTRKey, std::size(kAES128CTRKey), kAESCTRInitCounter,
+ std::size(kAESCTRInitCounter), kAESCTRPlaintext,
+ std::size(kAESCTRPlaintext), kAES128CTRCiphertext,
+ std::size(kAES128CTRCiphertext));
}
TEST(EncryptorTest, EncryptAES256CTR) {
- TestAESCTREncrypt(kAES256CTRKey, base::size(kAES256CTRKey),
- kAESCTRInitCounter, base::size(kAESCTRInitCounter),
- kAESCTRPlaintext, base::size(kAESCTRPlaintext),
- kAES256CTRCiphertext, base::size(kAES256CTRCiphertext));
+ TestAESCTREncrypt(kAES256CTRKey, std::size(kAES256CTRKey), kAESCTRInitCounter,
+ std::size(kAESCTRInitCounter), kAESCTRPlaintext,
+ std::size(kAESCTRPlaintext), kAES256CTRCiphertext,
+ std::size(kAES256CTRCiphertext));
}
TEST(EncryptorTest, EncryptAES128CTR_MultipleDecrypt) {
- TestAESCTRMultipleDecrypt(kAES128CTRKey, base::size(kAES128CTRKey),
- kAESCTRInitCounter, base::size(kAESCTRInitCounter),
- kAESCTRPlaintext, base::size(kAESCTRPlaintext),
+ TestAESCTRMultipleDecrypt(kAES128CTRKey, std::size(kAES128CTRKey),
+ kAESCTRInitCounter, std::size(kAESCTRInitCounter),
+ kAESCTRPlaintext, std::size(kAESCTRPlaintext),
kAES128CTRCiphertext,
- base::size(kAES128CTRCiphertext));
+ std::size(kAES128CTRCiphertext));
}
TEST(EncryptorTest, EncryptAES256CTR_MultipleDecrypt) {
- TestAESCTRMultipleDecrypt(kAES256CTRKey, base::size(kAES256CTRKey),
- kAESCTRInitCounter, base::size(kAESCTRInitCounter),
- kAESCTRPlaintext, base::size(kAESCTRPlaintext),
+ TestAESCTRMultipleDecrypt(kAES256CTRKey, std::size(kAES256CTRKey),
+ kAESCTRInitCounter, std::size(kAESCTRInitCounter),
+ kAESCTRPlaintext, std::size(kAESCTRPlaintext),
kAES256CTRCiphertext,
- base::size(kAES256CTRCiphertext));
+ std::size(kAES256CTRCiphertext));
}
TEST(EncryptorTest, EncryptDecryptCTR) {
diff --git a/chromium/crypto/hmac_unittest.cc b/chromium/crypto/hmac_unittest.cc
index 783aaf1850b..3fc05246649 100644
--- a/chromium/crypto/hmac_unittest.cc
+++ b/chromium/crypto/hmac_unittest.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "crypto/hmac.h"
+
#include <stddef.h>
#include <string.h>
#include <string>
-#include "base/cxx17_backports.h"
-#include "crypto/hmac.h"
#include "testing/gtest/include/gtest/gtest.h"
static const size_t kSHA1DigestSize = 20;
@@ -146,7 +146,7 @@ TEST(HMACTest, RFC2202TestCases) {
"\xBB\xFF\x1A\x91" }
};
- for (size_t i = 0; i < base::size(cases); ++i) {
+ for (size_t i = 0; i < std::size(cases); ++i) {
crypto::HMAC hmac(crypto::HMAC::SHA1);
ASSERT_TRUE(hmac.Init(reinterpret_cast<const unsigned char*>(cases[i].key),
cases[i].key_len));
@@ -243,7 +243,7 @@ TEST(HMACTest, HMACObjectReuse) {
ASSERT_TRUE(
hmac.Init(reinterpret_cast<const unsigned char*>(kSimpleKey),
kSimpleKeyLength));
- for (size_t i = 0; i < base::size(kSimpleHmacCases); ++i) {
+ for (size_t i = 0; i < std::size(kSimpleHmacCases); ++i) {
std::string data_string(kSimpleHmacCases[i].data,
kSimpleHmacCases[i].data_len);
unsigned char digest[kSHA1DigestSize];
@@ -258,7 +258,7 @@ TEST(HMACTest, Verify) {
hmac.Init(reinterpret_cast<const unsigned char*>(kSimpleKey),
kSimpleKeyLength));
const char empty_digest[kSHA1DigestSize] = { 0 };
- for (size_t i = 0; i < base::size(kSimpleHmacCases); ++i) {
+ for (size_t i = 0; i < std::size(kSimpleHmacCases); ++i) {
// Expected results
EXPECT_TRUE(hmac.Verify(
base::StringPiece(kSimpleHmacCases[i].data,
diff --git a/chromium/crypto/mock_apple_keychain.cc b/chromium/crypto/mock_apple_keychain.cc
index f67b397fbe1..d37d732a508 100644
--- a/chromium/crypto/mock_apple_keychain.cc
+++ b/chromium/crypto/mock_apple_keychain.cc
@@ -5,7 +5,6 @@
#include "crypto/mock_apple_keychain.h"
#include "base/check_op.h"
-#include "base/cxx17_backports.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
@@ -42,7 +41,7 @@ OSStatus MockAppleKeychain::FindGenericPassword(
// The function to free this data is mocked so the cast is fine.
*passwordData = const_cast<char*>(kPassword);
DCHECK(passwordLength);
- *passwordLength = base::size(kPassword);
+ *passwordLength = std::size(kPassword);
password_data_count_++;
}
diff --git a/chromium/crypto/nss_util.cc b/chromium/crypto/nss_util.cc
index ad5fb8a87ae..084cd2fd792 100644
--- a/chromium/crypto/nss_util.cc
+++ b/chromium/crypto/nss_util.cc
@@ -16,6 +16,7 @@
#include <utility>
#include "base/base_paths.h"
+#include "base/containers/flat_map.h"
#include "base/debug/alias.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -23,7 +24,6 @@
#include "base/logging.h"
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
-#include "base/task/post_task.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
@@ -84,9 +84,8 @@ char* PKCS11PasswordFunc(PK11SlotInfo* slot, PRBool retry, void* arg) {
reinterpret_cast<crypto::CryptoModuleBlockingPasswordDelegate*>(arg);
if (delegate) {
bool cancelled = false;
- std::string password = delegate->RequestPassword(PK11_GetTokenName(slot),
- retry != PR_FALSE,
- &cancelled);
+ std::string password = delegate->RequestPassword(
+ PK11_GetTokenName(slot), retry != PR_FALSE, &cancelled);
if (cancelled)
return nullptr;
char* result = PORT_Strdup(password.c_str());
@@ -105,9 +104,7 @@ class NSPRInitSingleton {
private:
friend struct base::LazyInstanceTraitsBase<NSPRInitSingleton>;
- NSPRInitSingleton() {
- PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
- }
+ NSPRInitSingleton() { PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); }
// NOTE(willchan): We don't actually cleanup on destruction since we leak NSS
// to prevent non-joinable threads from using NSS after it's already been
@@ -115,8 +112,8 @@ class NSPRInitSingleton {
~NSPRInitSingleton() = delete;
};
-base::LazyInstance<NSPRInitSingleton>::Leaky
- g_nspr_singleton = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<NSPRInitSingleton>::Leaky g_nspr_singleton =
+ LAZY_INSTANCE_INITIALIZER;
// Force a crash with error info on NSS_NoDB_Init failure.
void CrashOnNSSInitFailure() {
@@ -130,6 +127,58 @@ void CrashOnNSSInitFailure() {
}
class NSSInitSingleton {
+ public:
+ // NOTE(willchan): We don't actually cleanup on destruction since we leak NSS
+ // to prevent non-joinable threads from using NSS after it's already been
+ // shut down.
+ ~NSSInitSingleton() = delete;
+
+ ScopedPK11Slot OpenSoftwareNSSDB(const base::FilePath& path,
+ const std::string& description) {
+ base::AutoLock lock(slot_map_lock_);
+
+ auto slot_map_iter = slot_map_.find(path);
+ if (slot_map_iter != slot_map_.end()) {
+ // PK11_ReferenceSlot returns a new PK11Slot instance which refers
+ // to the same slot.
+ return ScopedPK11Slot(PK11_ReferenceSlot(slot_map_iter->second.get()));
+ }
+
+ const std::string modspec =
+ base::StringPrintf("configDir='sql:%s' tokenDescription='%s'",
+ path.value().c_str(), description.c_str());
+ PK11SlotInfo* db_slot_info = SECMOD_OpenUserDB(modspec.c_str());
+ if (db_slot_info) {
+ if (PK11_NeedUserInit(db_slot_info))
+ PK11_InitPin(db_slot_info, nullptr, nullptr);
+ slot_map_[path] = ScopedPK11Slot(PK11_ReferenceSlot(db_slot_info));
+ } else {
+ LOG(ERROR) << "Error opening persistent database (" << modspec
+ << "): " << GetNSSErrorMessage();
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+ DiagnosePublicSlotAndCrash(path);
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+ }
+
+ return ScopedPK11Slot(db_slot_info);
+ }
+
+ SECStatus CloseSoftwareNSSDB(PK11SlotInfo* slot) {
+ if (!slot) {
+ return SECFailure;
+ }
+
+ base::AutoLock lock(slot_map_lock_);
+ CK_SLOT_ID slot_id = PK11_GetSlotID(slot);
+ for (auto const& [stored_path, stored_slot] : slot_map_) {
+ if (PK11_GetSlotID(stored_slot.get()) == slot_id) {
+ slot_map_.erase(stored_path);
+ return SECMOD_CloseUserDB(slot);
+ }
+ }
+ return SECFailure;
+ }
+
private:
friend struct base::LazyInstanceTraitsBase<NSSInitSingleton>;
@@ -167,8 +216,8 @@ class NSSInitSingleton {
#endif
if (status != SECSuccess) {
LOG(ERROR) << "Error initializing NSS with a persistent "
- "database (" << nss_config_dir
- << "): " << GetNSSErrorMessage();
+ "database ("
+ << nss_config_dir << "): " << GetNSSErrorMessage();
}
}
if (status != SECSuccess) {
@@ -203,35 +252,35 @@ class NSSInitSingleton {
// Disable MD5 certificate signatures. (They are disabled by default in
// NSS 3.14.)
NSS_SetAlgorithmPolicy(SEC_OID_MD5, 0, NSS_USE_ALG_IN_CERT_SIGNATURE);
- NSS_SetAlgorithmPolicy(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,
- 0, NSS_USE_ALG_IN_CERT_SIGNATURE);
+ NSS_SetAlgorithmPolicy(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, 0,
+ NSS_USE_ALG_IN_CERT_SIGNATURE);
}
- // NOTE(willchan): We don't actually cleanup on destruction since we leak NSS
- // to prevent non-joinable threads from using NSS after it's already been
- // shut down.
- ~NSSInitSingleton() = delete;
+ // Stores opened software NSS databases.
+ base::flat_map<base::FilePath, /*slot=*/ScopedPK11Slot> slot_map_
+ GUARDED_BY(slot_map_lock_);
+ // Ensures thread-safety for the methods that modify slot_map_.
+ // Performance considerations:
+ // Opening/closing a database is a rare operation in Chrome. Actually opening
+ // a database is a blocking I/O operation. Chrome doesn't open a lot of
+ // different databases in parallel. So, waiting for another thread to finish
+ // opening a database and (almost certainly) reusing the result is comparable
+ // to opening the same database twice in parallel (but the latter is not
+ // supported by NSS).
+ base::Lock slot_map_lock_;
};
-base::LazyInstance<NSSInitSingleton>::Leaky
- g_nss_singleton = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<NSSInitSingleton>::Leaky g_nss_singleton =
+ LAZY_INSTANCE_INITIALIZER;
} // namespace
ScopedPK11Slot OpenSoftwareNSSDB(const base::FilePath& path,
const std::string& description) {
- const std::string modspec =
- base::StringPrintf("configDir='sql:%s' tokenDescription='%s'",
- path.value().c_str(),
- description.c_str());
- PK11SlotInfo* db_slot = SECMOD_OpenUserDB(modspec.c_str());
- if (db_slot) {
- if (PK11_NeedUserInit(db_slot))
- PK11_InitPin(db_slot, nullptr, nullptr);
- } else {
- LOG(ERROR) << "Error opening persistent database (" << modspec
- << "): " << GetNSSErrorMessage();
- }
- return ScopedPK11Slot(db_slot);
+ return g_nss_singleton.Get().OpenSoftwareNSSDB(path, description);
+}
+
+SECStatus CloseSoftwareNSSDB(PK11SlotInfo* slot) {
+ return g_nss_singleton.Get().CloseSoftwareNSSDB(slot);
}
void EnsureNSPRInit() {
@@ -247,9 +296,9 @@ bool CheckNSSVersion(const char* version) {
}
AutoSECMODListReadLock::AutoSECMODListReadLock()
- : lock_(SECMOD_GetDefaultModuleListLock()) {
- SECMOD_GetReadLock(lock_);
- }
+ : lock_(SECMOD_GetDefaultModuleListLock()) {
+ SECMOD_GetReadLock(lock_);
+}
AutoSECMODListReadLock::~AutoSECMODListReadLock() {
SECMOD_ReleaseReadLock(lock_);
diff --git a/chromium/crypto/nss_util.h b/chromium/crypto/nss_util.h
index f2aecc524cc..77f2fc4f6a7 100644
--- a/chromium/crypto/nss_util.h
+++ b/chromium/crypto/nss_util.h
@@ -9,6 +9,7 @@
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
+#include "base/files/file_path.h"
#include "build/chromeos_buildflags.h"
#include "crypto/crypto_export.h"
@@ -56,7 +57,20 @@ CRYPTO_EXPORT void InitializeTPMTokenAndSystemSlot(
// those methods. If neither of those methods have been called, this signals
// that no TPM system slot will be available.
CRYPTO_EXPORT void FinishInitializingTPMTokenAndSystemSlot();
-#endif
+
+// TODO(crbug.com/1163303) Remove when the bug is fixed.
+// Can be used to collect additional information when public slot fails to open.
+// Mainly checks the access permissions on the files and tries to read them.
+// Crashes Chrome because it will crash anyway when it tries to instantiate
+// NSSCertDatabase with a nullptr public slot, crashing early can provide better
+// logs/stacktraces for diagnosing.
+// Takes `nss_path` where NSS is supposed to be (or created). Will attempt
+// creating the path if it doesn't exist (to check that it can be done).
+// Theoretically the path should already exist because it's created when Chrome
+// tries to open the public slot.
+CRYPTO_EXPORT void DiagnosePublicSlotAndCrash(const base::FilePath& nss_path);
+
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
// Convert a NSS PRTime value into a base::Time object.
// We use a int64_t instead of PRTime here to avoid depending on NSPR headers.
diff --git a/chromium/crypto/nss_util_chromeos.cc b/chromium/crypto/nss_util_chromeos.cc
index 6ccc9d3a013..5592607cd02 100644
--- a/chromium/crypto/nss_util_chromeos.cc
+++ b/chromium/crypto/nss_util_chromeos.cc
@@ -19,6 +19,7 @@
#include "base/bind.h"
#include "base/callback_list.h"
#include "base/debug/stack_trace.h"
+#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
@@ -28,7 +29,6 @@
#include "base/path_service.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
-#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread_checker.h"
@@ -53,9 +53,9 @@ class ChromeOSUserData {
~ChromeOSUserData() {
if (public_slot_) {
- SECStatus status = SECMOD_CloseUserDB(public_slot_.get());
+ SECStatus status = CloseSoftwareNSSDB(public_slot_.get());
if (status != SECSuccess)
- PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError();
+ PLOG(ERROR) << "CloseSoftwareNSSDB failed: " << PORT_GetError();
}
}
@@ -591,4 +591,87 @@ void SetPrivateSoftwareSlotForChromeOSUserForTesting(ScopedPK11Slot slot) {
std::move(slot));
}
+namespace {
+void PrintDirectoryInfo(std::stringstream& ss, const base::FilePath& path) {
+ base::stat_wrapper_t file_stat;
+ base::File::Error error_code = base::File::Error::FILE_OK;
+ if (base::File::Stat(path.value().c_str(), &file_stat) == -1) {
+ error_code = base::File::OSErrorToFileError(errno);
+ }
+ ss << path << ", ";
+ ss << std::oct << file_stat.st_mode << std::dec << ", ";
+ ss << "uid " << file_stat.st_uid << ", ";
+ ss << "gid " << file_stat.st_gid << std::endl;
+
+ ss << "Enumerate error code: " << error_code << std::endl;
+}
+} // namespace
+
+// TODO(crbug.com/1163303): Remove when the bug is fixed.
+void DiagnosePublicSlotAndCrash(const base::FilePath& nss_path) {
+ std::stringstream ss;
+ ss << "Public slot is invalid." << std::endl;
+ // Should be something like /home/chronos/u-<hash>/.pki/nssdb .
+ ss << "NSS path: " << nss_path << std::endl;
+
+ {
+ // NSS files like pkcs11.txt, cert9.db, key4.db .
+ base::FileEnumerator files(
+ nss_path, /*recursive=*/false,
+ /*file_type=*/base::FileEnumerator::FILES,
+ /*pattern=*/base::FilePath::StringType(),
+ base::FileEnumerator::FolderSearchPolicy::MATCH_ONLY,
+ base::FileEnumerator::ErrorPolicy::STOP_ENUMERATION);
+ ss << "Public slot database files:" << std::endl;
+ for (base::FilePath path = files.Next(); !path.empty();
+ path = files.Next()) {
+ base::FileEnumerator::FileInfo file_info = files.GetInfo();
+ ss << file_info.GetName() << ", ";
+ ss << std::oct << file_info.stat().st_mode << std::dec << ", ";
+ ss << "uid " << file_info.stat().st_uid << ", ";
+ ss << "gid " << file_info.stat().st_gid << ", ";
+ ss << file_info.stat().st_size << " bytes, ";
+
+ char buf[16];
+ int read_result = base::ReadFile(path, buf, sizeof(buf) - 1);
+ ss << ((read_result > 0) ? "readable" : "not readable");
+
+ ss << std::endl;
+ }
+ ss << "Enumerate error code: " << files.GetError() << std::endl;
+ }
+
+ // NSS directory might not be created yet, also check parent directories.
+ // Use u-hash directory as a comparison point for user and group ids and
+ // access permissions.
+
+ base::FilePath nssdb_path = nss_path.Append(base::FilePath::kParentDirectory);
+ PrintDirectoryInfo(ss, nssdb_path);
+
+ base::FilePath pki_path = nssdb_path.Append(base::FilePath::kParentDirectory);
+ PrintDirectoryInfo(ss, pki_path);
+
+ base::FilePath u_hash_path =
+ pki_path.Append(base::FilePath::kParentDirectory);
+ PrintDirectoryInfo(ss, u_hash_path);
+
+ {
+ // Check whether the NSS path exists, and if not, check whether it's
+ // possible to create it.
+ if (base::DirectoryExists(nss_path)) {
+ ss << "NSS path exists." << std::endl;
+ } else {
+ base::File::Error error = base::File::Error::FILE_OK;
+ if (base::CreateDirectoryAndGetError(nss_path, &error)) {
+ ss << "NSS path didn't exist. Created successfully." << std::endl;
+ } else {
+ ss << "NSS path didn't exist. Failed to create, error: " << error
+ << std::endl;
+ }
+ }
+ }
+
+ CHECK(false) << ss.str();
+}
+
} // namespace crypto
diff --git a/chromium/crypto/nss_util_internal.h b/chromium/crypto/nss_util_internal.h
index ae2e7845d18..24fa80c780a 100644
--- a/chromium/crypto/nss_util_internal.h
+++ b/chromium/crypto/nss_util_internal.h
@@ -23,12 +23,22 @@ class FilePath;
namespace crypto {
-// Opens an NSS software database in folder |path|, with the (potentially)
-// user-visible description |description|. Returns the slot for the opened
-// database, or nullptr if the database could not be opened.
+// Opens an NSS software database in folder `path`, with the (potentially)
+// user-visible description `description`. Returns the slot for the opened
+// database, or nullptr if the database could not be opened. Can be called
+// multiple times for the same `path`, thread-safe.
CRYPTO_EXPORT ScopedPK11Slot OpenSoftwareNSSDB(const base::FilePath& path,
const std::string& description);
+// Closes the underlying database for the `slot`. All remaining slots
+// referencing the same database will remain valid objects, but won't be able to
+// successfully retrieve certificates, etc. Should be used for all databases
+// that were opened with `OpenSoftwareNSSDB` (instead of `SECMOD_CloseUserDB`).
+// Can be called multiple times. Returns `SECSuccess` if the database was
+// successfully closed, returns `SECFailure` if it was never opened, was already
+// closed by an earlier call, or failed to close. Thread-safe.
+CRYPTO_EXPORT SECStatus CloseSoftwareNSSDB(PK11SlotInfo* slot);
+
// A helper class that acquires the SECMOD list read lock while the
// AutoSECMODListReadLock is in scope.
class CRYPTO_EXPORT AutoSECMODListReadLock {
diff --git a/chromium/crypto/scoped_test_nss_db.cc b/chromium/crypto/scoped_test_nss_db.cc
index f3bc4d19498..3edbcb5d9d9 100644
--- a/chromium/crypto/scoped_test_nss_db.cc
+++ b/chromium/crypto/scoped_test_nss_db.cc
@@ -38,9 +38,9 @@ ScopedTestNSSDB::~ScopedTestNSSDB() {
base::ScopedAllowBlockingForTesting allow_blocking;
if (slot_) {
- SECStatus status = SECMOD_CloseUserDB(slot_.get());
+ SECStatus status = CloseSoftwareNSSDB(slot_.get());
if (status != SECSuccess)
- PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError();
+ PLOG(ERROR) << "CloseSoftwareNSSDB failed: " << PORT_GetError();
}
if (!temp_dir_.Delete())
diff --git a/chromium/crypto/sha2.cc b/chromium/crypto/sha2.cc
index b69add6efd2..33663c6d05b 100644
--- a/chromium/crypto/sha2.cc
+++ b/chromium/crypto/sha2.cc
@@ -27,7 +27,7 @@ void SHA256HashString(base::StringPiece str, void* output, size_t len) {
std::string SHA256HashString(base::StringPiece str) {
std::string output(kSHA256Length, 0);
- SHA256HashString(str, base::data(output), output.size());
+ SHA256HashString(str, std::data(output), output.size());
return output;
}
diff --git a/chromium/crypto/symmetric_key.cc b/chromium/crypto/symmetric_key.cc
index 63e070dfe3e..9dc71e9e43c 100644
--- a/chromium/crypto/symmetric_key.cc
+++ b/chromium/crypto/symmetric_key.cc
@@ -25,9 +25,8 @@ bool CheckDerivationParameters(SymmetricKey::Algorithm algorithm,
size_t key_size_in_bits) {
switch (algorithm) {
case SymmetricKey::AES:
- // Whitelist supported key sizes to avoid accidentally relying on
- // algorithms available in NSS but not BoringSSL and vice
- // versa. Note that BoringSSL does not support AES-192.
+ // Check for supported key sizes. Historically, NSS supported AES-192
+ // while BoringSSL did not and this check aligned their behavior.
return key_size_in_bits == 128 || key_size_in_bits == 256;
case SymmetricKey::HMAC_SHA1:
return key_size_in_bits % 8 == 0 && key_size_in_bits != 0;
@@ -49,9 +48,8 @@ std::unique_ptr<SymmetricKey> SymmetricKey::GenerateRandomKey(
size_t key_size_in_bits) {
DCHECK_EQ(AES, algorithm);
- // Whitelist supported key sizes to avoid accidentaly relying on
- // algorithms available in NSS but not BoringSSL and vice
- // versa. Note that BoringSSL does not support AES-192.
+ // Check for supported key sizes. Historically, NSS supported AES-192 while
+ // BoringSSL did not and this check aligned their behavior.
if (key_size_in_bits != 128 && key_size_in_bits != 256)
return nullptr;
@@ -127,9 +125,8 @@ std::unique_ptr<SymmetricKey> SymmetricKey::DeriveKeyFromPasswordUsingScrypt(
std::unique_ptr<SymmetricKey> SymmetricKey::Import(Algorithm algorithm,
const std::string& raw_key) {
if (algorithm == AES) {
- // Whitelist supported key sizes to avoid accidentaly relying on
- // algorithms available in NSS but not BoringSSL and vice
- // versa. Note that BoringSSL does not support AES-192.
+ // Check for supported key sizes. Historically, NSS supported AES-192 while
+ // BoringSSL did not and this check aligned their behavior.
if (raw_key.size() != 128/8 && raw_key.size() != 256/8)
return nullptr;
}