summaryrefslogtreecommitdiff
path: root/chromium/crypto
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-06-18 14:10:49 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-06-18 13:53:24 +0000
commit813fbf95af77a531c57a8c497345ad2c61d475b3 (patch)
tree821b2c8de8365f21b6c9ba17a236fb3006a1d506 /chromium/crypto
parentaf6588f8d723931a298c995fa97259bb7f7deb55 (diff)
downloadqtwebengine-chromium-813fbf95af77a531c57a8c497345ad2c61d475b3.tar.gz
BASELINE: Update chromium to 44.0.2403.47
Change-Id: Ie056fedba95cf5e5c76b30c4b2c80fca4764aa2f Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/crypto')
-rw-r--r--chromium/crypto/BUILD.gn99
-rw-r--r--chromium/crypto/PRESUBMIT.py17
-rw-r--r--chromium/crypto/aead_openssl.cc125
-rw-r--r--chromium/crypto/aead_openssl.h48
-rw-r--r--chromium/crypto/aead_openssl_unittest.cc54
-rw-r--r--chromium/crypto/crypto.gyp66
-rw-r--r--chromium/crypto/crypto.gypi12
-rw-r--r--chromium/crypto/crypto_nacl.gyp1
-rw-r--r--chromium/crypto/crypto_unittests.isolate70
-rw-r--r--chromium/crypto/ec_private_key.h41
-rw-r--r--chromium/crypto/ec_private_key_nss.cc190
-rw-r--r--chromium/crypto/ec_private_key_openssl.cc13
-rw-r--r--chromium/crypto/ec_private_key_unittest.cc2
-rw-r--r--chromium/crypto/ec_signature_creator_impl.h12
-rw-r--r--chromium/crypto/ec_signature_creator_openssl.cc19
-rw-r--r--chromium/crypto/encryptor.h4
-rw-r--r--chromium/crypto/encryptor_unittest.cc2
-rw-r--r--chromium/crypto/hmac_openssl.cc32
-rw-r--r--chromium/crypto/mock_apple_keychain.cc23
-rw-r--r--chromium/crypto/mock_apple_keychain.h108
-rw-r--r--chromium/crypto/nss_crypto_module_delegate.h2
-rw-r--r--chromium/crypto/nss_key_util.cc163
-rw-r--r--chromium/crypto/nss_key_util.h58
-rw-r--r--chromium/crypto/nss_key_util_unittest.cc87
-rw-r--r--chromium/crypto/nss_util.cc90
-rw-r--r--chromium/crypto/nss_util.h6
-rw-r--r--chromium/crypto/openssl_util.cc24
-rw-r--r--chromium/crypto/p224.cc45
-rw-r--r--chromium/crypto/p224_spake.cc38
-rw-r--r--chromium/crypto/p224_spake.h32
-rw-r--r--chromium/crypto/p224_spake_unittest.cc72
-rw-r--r--chromium/crypto/rsa_private_key.h78
-rw-r--r--chromium/crypto/rsa_private_key_nss.cc222
-rw-r--r--chromium/crypto/rsa_private_key_nss_unittest.cc60
-rw-r--r--chromium/crypto/rsa_private_key_openssl.cc21
-rw-r--r--chromium/crypto/rsa_private_key_unittest.cc45
-rw-r--r--chromium/crypto/scoped_openssl_types.h33
-rw-r--r--chromium/crypto/secure_hash_default.cc12
-rw-r--r--chromium/crypto/secure_hash_openssl.cc12
-rw-r--r--chromium/crypto/signature_creator.h6
-rw-r--r--chromium/crypto/signature_creator_nss.cc6
-rw-r--r--chromium/crypto/signature_creator_openssl.cc22
-rw-r--r--chromium/crypto/signature_verifier_openssl.cc18
-rw-r--r--chromium/crypto/signature_verifier_unittest.cc63
-rw-r--r--chromium/crypto/symmetric_key.h6
45 files changed, 1321 insertions, 838 deletions
diff --git a/chromium/crypto/BUILD.gn b/chromium/crypto/BUILD.gn
index d3d318de50f..f84c4d455d6 100644
--- a/chromium/crypto/BUILD.gn
+++ b/chromium/crypto/BUILD.gn
@@ -3,10 +3,13 @@
# found in the LICENSE file.
import("//build/config/crypto.gni")
+import("//testing/test.gni")
component("crypto") {
output_name = "crcrypto" # Avoid colliding with OpenSSL's libcrypto.
sources = [
+ "aead_openssl.cc",
+ "aead_openssl.h",
"apple_keychain.h",
"apple_keychain_ios.mm",
"apple_keychain_mac.mm",
@@ -15,8 +18,8 @@ component("crypto") {
"crypto_export.h",
"cssm_init.cc",
"cssm_init.h",
- "curve25519.cc",
"curve25519-donna.c",
+ "curve25519.cc",
"curve25519.h",
"ec_private_key.h",
"ec_private_key_nss.cc",
@@ -40,12 +43,15 @@ component("crypto") {
"hmac_openssl.cc",
"mac_security_services_lock.cc",
"mac_security_services_lock.h",
+
# TODO(brettw) these mocks should be moved to a test_support_crypto target
# if possible.
"mock_apple_keychain.cc",
"mock_apple_keychain.h",
"mock_apple_keychain_ios.cc",
"mock_apple_keychain_mac.cc",
+ "nss_key_util.cc",
+ "nss_key_util.h",
"nss_util.cc",
"nss_util.h",
"nss_util_internal.h",
@@ -65,8 +71,8 @@ component("crypto") {
"rsa_private_key_openssl.cc",
"scoped_capi_types.h",
"scoped_nss_types.h",
- "secure_hash_default.cc",
"secure_hash.h",
+ "secure_hash_default.cc",
"secure_hash_openssl.cc",
"secure_util.cc",
"secure_util.h",
@@ -91,6 +97,9 @@ component("crypto") {
"third_party/nss/sha512.cc",
]
+ # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+ configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+
deps = [
":platform",
"//base",
@@ -131,9 +140,6 @@ component("crypto") {
"ec_signature_creator_nss.cc",
"encryptor_nss.cc",
"hmac_nss.cc",
- "nss_util.cc",
- "nss_util.h",
- "nss_util_internal.h",
"rsa_private_key_nss.cc",
"secure_hash_default.cc",
"signature_creator_nss.cc",
@@ -149,6 +155,8 @@ component("crypto") {
} else {
# Remove OpenSSL when using NSS.
sources -= [
+ "aead_openssl.cc",
+ "aead_openssl.h",
"ec_private_key_openssl.cc",
"ec_signature_creator_openssl.cc",
"encryptor_openssl.cc",
@@ -165,10 +173,24 @@ component("crypto") {
]
}
+ # Some files are built when NSS is used at all, either for the internal crypto
+ # library or the platform certificate library.
+ if (use_openssl && !use_nss_certs) {
+ sources -= [
+ "nss_key_util.cc",
+ "nss_key_util.h",
+ "nss_util.cc",
+ "nss_util.h",
+ "nss_util_internal.h",
+ ]
+ }
+
defines = [ "CRYPTO_IMPLEMENTATION" ]
}
-if (is_win) {
+# TODO(GYP): TODO(dpranke), fix the compile errors for this stuff
+# and make it work.
+if (false && is_win) {
# A minimal crypto subset for hmac-related stuff that small standalone
# targets can use to reduce code size on Windows. This does not depend on
# OpenSSL/NSS but will use Windows APIs for that functionality.
@@ -208,13 +230,13 @@ test("crypto_unittests") {
"ghash_unittest.cc",
"hkdf_unittest.cc",
"hmac_unittest.cc",
+ "nss_key_util_unittest.cc",
"nss_util_unittest.cc",
"openssl_bio_string_unittest.cc",
- "p224_unittest.cc",
"p224_spake_unittest.cc",
+ "p224_unittest.cc",
"random_unittest.cc",
"rsa_private_key_unittest.cc",
- "rsa_private_key_nss_unittest.cc",
"secure_hash_unittest.cc",
"sha2_unittest.cc",
"signature_creator_unittest.cc",
@@ -222,18 +244,21 @@ test("crypto_unittests") {
"symmetric_key_unittest.cc",
]
- if (use_openssl || !is_linux) {
+ # Some files are built when NSS is used at all, either for the internal crypto
+ # library or the platform certificate library.
+ if (use_openssl && !use_nss_certs) {
sources -= [
- "rsa_private_key_nss_unittest.cc",
+ "nss_key_util_unittest.cc",
+ "nss_util_unittest.cc",
]
}
- if (use_openssl) {
- sources -= [ "nss_util_unittest.cc" ]
- } else {
+ if (!use_openssl) {
sources -= [ "openssl_bio_string_unittest.cc" ]
}
+ configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+
deps = [
":crypto",
":platform",
@@ -248,10 +273,10 @@ test("crypto_unittests") {
source_set("test_support") {
sources = [
- "scoped_test_nss_db.cc",
- "scoped_test_nss_db.h",
"scoped_test_nss_chromeos_user.cc",
"scoped_test_nss_chromeos_user.h",
+ "scoped_test_nss_db.cc",
+ "scoped_test_nss_db.h",
"scoped_test_system_nss_key_slot.cc",
"scoped_test_system_nss_key_slot.h",
]
@@ -278,28 +303,46 @@ source_set("test_support") {
}
}
+config("platform_config") {
+ if ((!use_openssl || use_nss_certs) && is_clang) {
+ # There is a broken header guard in /usr/include/nss/secmod.h:
+ # https://bugzilla.mozilla.org/show_bug.cgi?id=884072
+ cflags = [ "-Wno-header-guard" ]
+ }
+}
+
# This is a meta-target that forwards to NSS's SSL library or OpenSSL,
# according to the state of the crypto flags. A target just wanting to depend
# on the current SSL library should just depend on this.
group("platform") {
if (use_openssl) {
- deps = [ "//third_party/boringssl" ]
+ deps = [
+ "//third_party/boringssl",
+ ]
} else {
- deps = [ "//net/third_party/nss/ssl:libssl" ]
+ deps = [
+ "//net/third_party/nss/ssl:libssl",
+ ]
+ }
+
+ # Link in NSS if it is used for either the internal crypto library
+ # (!use_openssl) or platform certificate library (use_nss_certs).
+ if (!use_openssl || use_nss_certs) {
if (is_linux) {
# On Linux, we use the system NSS (excepting SSL where we always use our
# own).
- #
- # We always need our SSL header search path to come before the system one
- # so our versions are used. The libssl target will add the search path we
- # want, but according to GN's ordering rules, public_configs' search path
- # will get applied before ones inherited from our dependencies.
- # Therefore, we need to explicitly list our custom libssl's config here
- # before the system one.
- public_configs = [
- "//net/third_party/nss/ssl:ssl_config",
- "//third_party/nss:system_nss_no_ssl_config",
- ]
+ public_configs = [ ":platform_config" ]
+ if (!use_openssl) {
+ # If using a bundled copy of NSS's SSL library, ensure the bundled SSL
+ # header search path comes before the system one so our versions are
+ # used. The libssl target will add the search path we want, but
+ # according to GN's ordering rules, public_configs' search path will get
+ # applied before ones inherited from our dependencies. Therefore, we
+ # need to explicitly list our custom libssl's config here before the
+ # system one.
+ public_configs += [ "//net/third_party/nss/ssl:ssl_config" ]
+ }
+ public_configs += [ "//third_party/nss:system_nss_no_ssl_config" ]
} else {
# Non-Linux platforms use the hermetic NSS from the tree.
deps += [
diff --git a/chromium/crypto/PRESUBMIT.py b/chromium/crypto/PRESUBMIT.py
deleted file mode 100644
index a2a5af9ae7a..00000000000
--- a/chromium/crypto/PRESUBMIT.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Chromium presubmit script for src/net.
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
-for more details on the presubmit API built into gcl.
-"""
-
-def GetPreferredTryMasters(project, change):
- # Changes in crypto often need a corresponding OpenSSL edit.
- return {
- 'tryserver.chromium.linux': {
- 'linux_redux': set(['defaulttests']),
- }
- }
diff --git a/chromium/crypto/aead_openssl.cc b/chromium/crypto/aead_openssl.cc
new file mode 100644
index 00000000000..e32168a576b
--- /dev/null
+++ b/chromium/crypto/aead_openssl.cc
@@ -0,0 +1,125 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "crypto/aead_openssl.h"
+
+#if defined(USE_OPENSSL)
+
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/strings/string_util.h"
+#include "crypto/openssl_util.h"
+
+namespace crypto {
+
+Aead::Aead(AeadAlgorithm algorithm) : key_(nullptr) {
+ EnsureOpenSSLInit();
+ switch (algorithm) {
+ case AES_128_CTR_HMAC_SHA256:
+ aead_ = EVP_aead_aes_128_ctr_hmac_sha256();
+ break;
+ }
+}
+
+Aead::~Aead() {
+}
+
+void Aead::Init(const std::string* key) {
+ DCHECK(!key_);
+ DCHECK_EQ(KeyLength(), key->size());
+ key_ = key;
+}
+
+bool Aead::Seal(const base::StringPiece& plaintext,
+ const base::StringPiece& nonce,
+ const base::StringPiece& additional_data,
+ std::string* ciphertext) const {
+ DCHECK(key_);
+ DCHECK_EQ(NonceLength(), nonce.size());
+ EVP_AEAD_CTX ctx;
+
+ if (!EVP_AEAD_CTX_init(&ctx, aead_,
+ reinterpret_cast<const uint8*>(key_->data()),
+ key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
+ return false;
+ }
+
+ std::string result;
+ const size_t max_output_length =
+ EVP_AEAD_max_overhead(aead_) + plaintext.size();
+ size_t output_length;
+ uint8* out_ptr =
+ reinterpret_cast<uint8*>(WriteInto(&result, max_output_length + 1));
+
+ if (!EVP_AEAD_CTX_seal(
+ &ctx, out_ptr, &output_length, max_output_length,
+ reinterpret_cast<const uint8*>(nonce.data()), nonce.size(),
+ reinterpret_cast<const uint8*>(plaintext.data()), plaintext.size(),
+ reinterpret_cast<const uint8*>(additional_data.data()),
+ additional_data.size())) {
+ EVP_AEAD_CTX_cleanup(&ctx);
+ return false;
+ }
+
+ DCHECK_LE(output_length, max_output_length);
+ result.resize(output_length);
+
+ ciphertext->swap(result);
+ EVP_AEAD_CTX_cleanup(&ctx);
+
+ return true;
+}
+
+bool Aead::Open(const base::StringPiece& ciphertext,
+ const base::StringPiece& nonce,
+ const base::StringPiece& additional_data,
+ std::string* plaintext) const {
+ DCHECK(key_);
+ EVP_AEAD_CTX ctx;
+
+ if (!EVP_AEAD_CTX_init(&ctx, aead_,
+ reinterpret_cast<const uint8*>(key_->data()),
+ key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
+ return false;
+ }
+
+ std::string result;
+ const size_t max_output_length = ciphertext.size();
+ size_t output_length;
+ uint8* out_ptr =
+ reinterpret_cast<uint8*>(WriteInto(&result, max_output_length + 1));
+
+ if (!EVP_AEAD_CTX_open(
+ &ctx, out_ptr, &output_length, max_output_length,
+ reinterpret_cast<const uint8*>(nonce.data()), nonce.size(),
+ reinterpret_cast<const uint8*>(ciphertext.data()), ciphertext.size(),
+ reinterpret_cast<const uint8*>(additional_data.data()),
+ additional_data.size())) {
+ EVP_AEAD_CTX_cleanup(&ctx);
+ return false;
+ }
+
+ DCHECK_LE(output_length, max_output_length);
+ result.resize(output_length);
+
+ plaintext->swap(result);
+ EVP_AEAD_CTX_cleanup(&ctx);
+
+ return true;
+}
+
+size_t Aead::KeyLength() const {
+ return EVP_AEAD_key_length(aead_);
+}
+
+size_t Aead::NonceLength() const {
+ return EVP_AEAD_nonce_length(aead_);
+}
+
+} // namespace
+
+#endif
diff --git a/chromium/crypto/aead_openssl.h b/chromium/crypto/aead_openssl.h
new file mode 100644
index 00000000000..773cce14286
--- /dev/null
+++ b/chromium/crypto/aead_openssl.h
@@ -0,0 +1,48 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CRYPTO_AEAD_H_
+#define CRYPTO_AEAD_H_
+
+#include "base/strings/string_piece.h"
+#include "crypto/crypto_export.h"
+
+struct evp_aead_st;
+
+namespace crypto {
+
+// This class exposes the AES-128-CTR-HMAC-SHA256 AEAD, currently only
+// for OpenSSL builds.
+class CRYPTO_EXPORT Aead {
+ public:
+ enum AeadAlgorithm { AES_128_CTR_HMAC_SHA256 };
+
+ explicit Aead(AeadAlgorithm algorithm);
+
+ ~Aead();
+
+ void Init(const std::string* key);
+
+ bool Seal(const base::StringPiece& plaintext,
+ const base::StringPiece& nonce,
+ const base::StringPiece& additional_data,
+ std::string* ciphertext) const;
+
+ bool Open(const base::StringPiece& ciphertext,
+ const base::StringPiece& nonce,
+ const base::StringPiece& additional_data,
+ std::string* plaintext) const;
+
+ size_t KeyLength() const;
+
+ size_t NonceLength() const;
+
+ private:
+ const std::string* key_;
+ const evp_aead_st* aead_;
+};
+
+} // namespace crypto
+
+#endif // CRYPTO_ENCRYPTOR_H_
diff --git a/chromium/crypto/aead_openssl_unittest.cc b/chromium/crypto/aead_openssl_unittest.cc
new file mode 100644
index 00000000000..446bca2cb02
--- /dev/null
+++ b/chromium/crypto/aead_openssl_unittest.cc
@@ -0,0 +1,54 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "crypto/aead_openssl.h"
+
+#include <string>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+#if defined(USE_OPENSSL)
+
+TEST(AeadTest, SealOpen) {
+ crypto::Aead aead(crypto::Aead::AES_128_CTR_HMAC_SHA256);
+ std::string key(aead.KeyLength(), 0);
+ aead.Init(&key);
+ std::string nonce(aead.NonceLength(), 0);
+ std::string plaintext("this is the plaintext");
+ std::string ad("this is the additional data");
+ std::string ciphertext;
+ EXPECT_TRUE(aead.Seal(plaintext, nonce, ad, &ciphertext));
+ EXPECT_LT(0U, ciphertext.size());
+
+ std::string decrypted;
+ EXPECT_TRUE(aead.Open(ciphertext, nonce, ad, &decrypted));
+
+ EXPECT_EQ(plaintext, decrypted);
+}
+
+TEST(AeadTest, SealOpenWrongKey) {
+ crypto::Aead aead(crypto::Aead::AES_128_CTR_HMAC_SHA256);
+ std::string key(aead.KeyLength(), 0);
+ std::string wrong_key(aead.KeyLength(), 1);
+ aead.Init(&key);
+ crypto::Aead aead_wrong_key(crypto::Aead::AES_128_CTR_HMAC_SHA256);
+ aead_wrong_key.Init(&wrong_key);
+
+ std::string nonce(aead.NonceLength(), 0);
+ std::string plaintext("this is the plaintext");
+ std::string ad("this is the additional data");
+ std::string ciphertext;
+ EXPECT_TRUE(aead.Seal(plaintext, nonce, ad, &ciphertext));
+ EXPECT_LT(0U, ciphertext.size());
+
+ std::string decrypted;
+ EXPECT_FALSE(aead_wrong_key.Open(ciphertext, nonce, ad, &decrypted));
+ EXPECT_EQ(0U, decrypted.size());
+}
+
+#endif
+
+} // namespace
diff --git a/chromium/crypto/crypto.gyp b/chromium/crypto/crypto.gyp
index 6d60f480fed..e6bff0b098b 100644
--- a/chromium/crypto/crypto.gyp
+++ b/chromium/crypto/crypto.gyp
@@ -49,9 +49,9 @@
],
}],
[ 'OS == "android"', {
- 'includes': [
- '../build/android/cpufeatures.gypi',
- ],
+ 'dependencies': [
+ '../build/android/ndk.gyp:cpu_features',
+ ],
}],
[ 'os_bsd==1', {
'link_settings': {
@@ -108,9 +108,6 @@
'ec_signature_creator_nss.cc',
'encryptor_nss.cc',
'hmac_nss.cc',
- 'nss_util.cc',
- 'nss_util.h',
- 'nss_util_internal.h',
'rsa_private_key_nss.cc',
'secure_hash_default.cc',
'signature_creator_nss.cc',
@@ -128,6 +125,8 @@
],
}, {
'sources!': [
+ 'aead_openssl.cc',
+ 'aead_openssl.h',
'ec_private_key_openssl.cc',
'ec_signature_creator_openssl.cc',
'encryptor_openssl.cc',
@@ -143,6 +142,17 @@
'symmetric_key_openssl.cc',
],
},],
+ [ 'use_openssl==1 and use_nss_certs==0', {
+ # Some files are built when NSS is used at all, either for the
+ # internal crypto library or the platform certificate library.
+ 'sources!': [
+ 'nss_key_util.cc',
+ 'nss_key_util.h',
+ 'nss_util.cc',
+ 'nss_util.h',
+ 'nss_util_internal.h',
+ ],
+ },],
],
'sources': [
'<@(crypto_sources)',
@@ -152,6 +162,7 @@
'target_name': 'crypto_unittests',
'type': 'executable',
'sources': [
+ 'aead_openssl_unittest.cc',
'curve25519_unittest.cc',
'ec_private_key_unittest.cc',
'ec_signature_creator_unittest.cc',
@@ -159,13 +170,13 @@
'ghash_unittest.cc',
'hkdf_unittest.cc',
'hmac_unittest.cc',
+ 'nss_key_util_unittest.cc',
'nss_util_unittest.cc',
'openssl_bio_string_unittest.cc',
'p224_unittest.cc',
'p224_spake_unittest.cc',
'random_unittest.cc',
'rsa_private_key_unittest.cc',
- 'rsa_private_key_nss_unittest.cc',
'secure_hash_unittest.cc',
'sha2_unittest.cc',
'signature_creator_unittest.cc',
@@ -182,7 +193,7 @@
'../testing/gtest.gyp:gtest',
],
'conditions': [
- [ 'os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"', {
+ [ 'use_nss_certs == 1', {
'conditions': [
[ 'use_allocator!="none"', {
'dependencies': [
@@ -194,10 +205,14 @@
'dependencies': [
'../build/linux/system.gyp:ssl',
],
- }, { # os_posix != 1 or OS == "mac" or OS == "android" or OS == "ios"
+ }],
+ [ 'use_openssl == 1 and use_nss_certs == 0', {
+ # Some files are built when NSS is used at all, either for the
+ # internal crypto library or the platform certificate library.
'sources!': [
- 'rsa_private_key_nss_unittest.cc',
- ]
+ 'nss_key_util_unittest.cc',
+ 'nss_util_unittest.cc',
+ ],
}],
[ 'use_openssl == 0 and (OS == "mac" or OS == "ios" or OS == "win")', {
'dependencies': [
@@ -212,10 +227,6 @@
'dependencies': [
'../third_party/boringssl/boringssl.gyp:boringssl',
],
- 'sources!': [
- 'nss_util_unittest.cc',
- 'rsa_private_key_nss_unittest.cc',
- ],
}, {
'sources!': [
'openssl_bio_string_unittest.cc',
@@ -238,7 +249,7 @@
'../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations_win64',
],
'sources': [
- '<@(hmac_win64_related_sources)',
+ '<@(nacl_win64_sources)',
],
'defines': [
'CRYPTO_IMPLEMENTATION',
@@ -255,7 +266,7 @@
},
],
}],
- ['use_nss==1', {
+ ['use_nss_certs==1', {
'targets': [
{
'target_name': 'crypto_test_support',
@@ -273,7 +284,7 @@
'scoped_test_system_nss_key_slot.h',
],
'conditions': [
- ['use_nss==0', {
+ ['use_nss_certs==0', {
'sources!': [
'scoped_test_nss_db.cc',
'scoped_test_nss_db.h',
@@ -289,7 +300,7 @@
}],
],
}
- ]}, { # use_nss==0
+ ]}, { # use_nss_certs==0
'targets': [
{
'target_name': 'crypto_test_support',
@@ -297,5 +308,22 @@
'sources': [],
}
]}],
+ ['test_isolation_mode != "noop"', {
+ 'targets': [
+ {
+ 'target_name': 'crypto_unittests_run',
+ 'type': 'none',
+ 'dependencies': [
+ 'crypto_unittests',
+ ],
+ 'includes': [
+ '../build/isolate.gypi',
+ ],
+ 'sources': [
+ 'crypto_unittests.isolate',
+ ],
+ },
+ ],
+ }],
],
}
diff --git a/chromium/crypto/crypto.gypi b/chromium/crypto/crypto.gypi
index 82b5da5dbc8..73b33322605 100644
--- a/chromium/crypto/crypto.gypi
+++ b/chromium/crypto/crypto.gypi
@@ -23,11 +23,12 @@
'wincrypt_shim.h',
],
},
- 'hmac_win64_related_sources': [ '<@(hmac_win64_related_sources)' ],
'crypto_sources': [
# NOTE: all transitive dependencies of HMAC on windows need
# to be placed in the source list above.
'<@(hmac_win64_related_sources)',
+ 'aead_openssl.cc',
+ 'aead_openssl.h',
'apple_keychain.h',
'apple_keychain_ios.mm',
'apple_keychain_mac.mm',
@@ -66,6 +67,8 @@
'p224_spake.cc',
'p224_spake.h',
'nss_crypto_module_delegate.h',
+ 'nss_key_util.cc',
+ 'nss_key_util.h',
'nss_util.cc',
'nss_util.h',
'nss_util_internal.h',
@@ -100,6 +103,11 @@
'third_party/nss/pk11akey.cc',
'third_party/nss/rsawrapr.c',
'third_party/nss/secsign.cc',
- ]
+ ],
+ 'nacl_win64_sources': [
+ '<@(hmac_win64_related_sources)',
+ 'random.cc',
+ 'random.h',
+ ],
}
}
diff --git a/chromium/crypto/crypto_nacl.gyp b/chromium/crypto/crypto_nacl.gyp
index 44516109196..255c42c51d3 100644
--- a/chromium/crypto/crypto_nacl.gyp
+++ b/chromium/crypto/crypto_nacl.gyp
@@ -23,7 +23,6 @@
},
'dependencies': [
'../third_party/boringssl/boringssl_nacl.gyp:boringssl_nacl',
- '../native_client/tools.gyp:prep_toolchain',
'../native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted',
],
'defines': [
diff --git a/chromium/crypto/crypto_unittests.isolate b/chromium/crypto/crypto_unittests.isolate
new file mode 100644
index 00000000000..93272b431ae
--- /dev/null
+++ b/chromium/crypto/crypto_unittests.isolate
@@ -0,0 +1,70 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+{
+ 'conditions': [
+ ['use_x11==0', {
+ 'variables': {
+ 'command': [
+ '../testing/test_env.py',
+ '<(PRODUCT_DIR)/crypto_unittests<(EXECUTABLE_SUFFIX)',
+ '--brave-new-test-launcher',
+ '--test-launcher-bot-mode',
+ '--asan=<(asan)',
+ '--msan=<(msan)',
+ '--tsan=<(tsan)',
+ ],
+ },
+ }],
+ ['use_x11==1', {
+ 'variables': {
+ 'command': [
+ '../testing/xvfb.py',
+ '<(PRODUCT_DIR)',
+ '<(PRODUCT_DIR)/crypto_unittests<(EXECUTABLE_SUFFIX)',
+ '--brave-new-test-launcher',
+ '--test-launcher-bot-mode',
+ '--asan=<(asan)',
+ '--msan=<(msan)',
+ '--tsan=<(tsan)',
+ ],
+ 'files': [
+ '../testing/xvfb.py',
+ ],
+ },
+ }],
+ ['OS=="linux" and use_ozone==0', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/xdisplaycheck<(EXECUTABLE_SUFFIX)',
+ ],
+ },
+ }],
+ ['OS=="linux" or OS=="mac" or OS=="win"', {
+ 'variables': {
+ 'files': [
+ '../testing/test_env.py',
+ '<(PRODUCT_DIR)/crypto_unittests<(EXECUTABLE_SUFFIX)',
+ ],
+ 'read_only': 1,
+ },
+ }],
+ ['OS=="mac" and asan==1 and fastbuild==0', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/crypto_unittests.dSYM/',
+ ],
+ },
+ }],
+ ['OS=="win" and (fastbuild==0 or fastbuild==1)', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/crypto_unittests.exe.pdb',
+ ],
+ },
+ }],
+ ],
+ 'includes': [
+ '../base/base.isolate',
+ ],
+}
diff --git a/chromium/crypto/ec_private_key.h b/chromium/crypto/ec_private_key.h
index 9fd8ffdfb62..87af838904a 100644
--- a/chromium/crypto/ec_private_key.h
+++ b/chromium/crypto/ec_private_key.h
@@ -42,13 +42,6 @@ class CRYPTO_EXPORT ECPrivateKey {
// TODO(mattm): Add a curve parameter.
static ECPrivateKey* Create();
-#if defined(USE_NSS)
- // Creates a new random instance in |slot|. Can return NULL if initialization
- // fails. The created key is permanent and is not exportable in plaintext
- // form.
- static ECPrivateKey* CreateSensitive(PK11SlotInfo* slot);
-#endif
-
// Creates a new instance by importing an existing key pair.
// The key pair is given as an ASN.1-encoded PKCS #8 EncryptedPrivateKeyInfo
// block and an X.509 SubjectPublicKeyInfo block.
@@ -58,19 +51,6 @@ class CRYPTO_EXPORT ECPrivateKey {
const std::vector<uint8>& encrypted_private_key_info,
const std::vector<uint8>& subject_public_key_info);
-#if defined(USE_NSS)
- // Creates a new instance in |slot| by importing an existing key pair.
- // The key pair is given as an ASN.1-encoded PKCS #8 EncryptedPrivateKeyInfo
- // block and an X.509 SubjectPublicKeyInfo block.
- // This can return NULL if initialization fails. The created key is permanent
- // and is not exportable in plaintext form.
- static ECPrivateKey* CreateSensitiveFromEncryptedPrivateKeyInfo(
- PK11SlotInfo* slot,
- const std::string& password,
- const std::vector<uint8>& encrypted_private_key_info,
- const std::vector<uint8>& subject_public_key_info);
-#endif
-
#if !defined(USE_OPENSSL)
// Imports the key pair into |slot| and returns in |public_key| and |key|.
// Shortcut for code that needs to keep a reference directly to NSS types
@@ -86,10 +66,10 @@ class CRYPTO_EXPORT ECPrivateKey {
bool sensitive,
SECKEYPrivateKey** key,
SECKEYPublicKey** public_key);
+#endif
// Returns a copy of the object.
ECPrivateKey* Copy() const;
-#endif
#if defined(USE_OPENSSL)
EVP_PKEY* key() { return key_; }
@@ -122,25 +102,6 @@ class CRYPTO_EXPORT ECPrivateKey {
// Constructor is private. Use one of the Create*() methods above instead.
ECPrivateKey();
-#if !defined(USE_OPENSSL)
- // Shared helper for Create() and CreateSensitive().
- // TODO(cmasone): consider replacing |permanent| and |sensitive| with a
- // flags arg created by ORing together some enumerated values.
- static ECPrivateKey* CreateWithParams(PK11SlotInfo* slot,
- bool permanent,
- bool sensitive);
-
- // Shared helper for CreateFromEncryptedPrivateKeyInfo() and
- // CreateSensitiveFromEncryptedPrivateKeyInfo().
- static ECPrivateKey* CreateFromEncryptedPrivateKeyInfoWithParams(
- PK11SlotInfo* slot,
- const std::string& password,
- const std::vector<uint8>& encrypted_private_key_info,
- const std::vector<uint8>& subject_public_key_info,
- bool permanent,
- bool sensitive);
-#endif
-
#if defined(USE_OPENSSL)
EVP_PKEY* key_;
#else
diff --git a/chromium/crypto/ec_private_key_nss.cc b/chromium/crypto/ec_private_key_nss.cc
index 2daa0c0f4a3..5092010c939 100644
--- a/chromium/crypto/ec_private_key_nss.cc
+++ b/chromium/crypto/ec_private_key_nss.cc
@@ -91,18 +91,47 @@ ECPrivateKey* ECPrivateKey::Create() {
EnsureNSSInit();
ScopedPK11Slot slot(GetTempKeySlot());
- return CreateWithParams(slot.get(),
- false /* not permanent */,
- false /* not sensitive */);
-}
+ if (!slot)
+ return nullptr;
-#if defined(USE_NSS)
-// static
-ECPrivateKey* ECPrivateKey::CreateSensitive(PK11SlotInfo* slot) {
- return CreateWithParams(
- slot, true /* permanent */, true /* sensitive */);
+ scoped_ptr<ECPrivateKey> result(new ECPrivateKey);
+
+ SECOidData* oid_data = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1);
+ if (!oid_data) {
+ DLOG(ERROR) << "SECOID_FindOIDByTag: " << PORT_GetError();
+ return nullptr;
+ }
+
+ // SECKEYECParams is a SECItem containing the DER encoded ASN.1 ECParameters
+ // value. For a named curve, that is just the OBJECT IDENTIFIER of the curve.
+ // In addition to the oid data, the encoding requires one byte for the ASN.1
+ // tag and one byte for the length (assuming the length is <= 127).
+ CHECK_LE(oid_data->oid.len, 127U);
+ std::vector<unsigned char> parameters_buf(2 + oid_data->oid.len);
+ SECKEYECParams ec_parameters = {
+ siDEROID, &parameters_buf[0],
+ static_cast<unsigned>(parameters_buf.size())
+ };
+
+ ec_parameters.data[0] = SEC_ASN1_OBJECT_ID;
+ ec_parameters.data[1] = static_cast<unsigned char>(oid_data->oid.len);
+ memcpy(ec_parameters.data + 2, oid_data->oid.data, oid_data->oid.len);
+
+ result->key_ = PK11_GenerateKeyPair(slot.get(),
+ CKM_EC_KEY_PAIR_GEN,
+ &ec_parameters,
+ &result->public_key_,
+ PR_FALSE /* not permanent */,
+ PR_FALSE /* not sensitive */,
+ NULL);
+ if (!result->key_) {
+ DLOG(ERROR) << "PK11_GenerateKeyPair: " << PORT_GetError();
+ return nullptr;
+ }
+ CHECK_EQ(ecKey, SECKEY_GetPublicKeyType(result->public_key_));
+
+ return result.release();
}
-#endif
// static
ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
@@ -112,31 +141,43 @@ ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
EnsureNSSInit();
ScopedPK11Slot slot(GetTempKeySlot());
- return CreateFromEncryptedPrivateKeyInfoWithParams(
+ if (!slot)
+ return nullptr;
+
+ scoped_ptr<ECPrivateKey> result(new ECPrivateKey);
+
+ SECItem encoded_spki = {
+ siBuffer,
+ const_cast<unsigned char*>(&subject_public_key_info[0]),
+ static_cast<unsigned>(subject_public_key_info.size())
+ };
+ CERTSubjectPublicKeyInfo* decoded_spki = SECKEY_DecodeDERSubjectPublicKeyInfo(
+ &encoded_spki);
+ if (!decoded_spki) {
+ DLOG(ERROR) << "SECKEY_DecodeDERSubjectPublicKeyInfo: " << PORT_GetError();
+ return nullptr;
+ }
+
+ bool success = ImportFromEncryptedPrivateKeyInfo(
slot.get(),
password,
- encrypted_private_key_info,
- subject_public_key_info,
+ &encrypted_private_key_info[0],
+ encrypted_private_key_info.size(),
+ decoded_spki,
false /* not permanent */,
- false /* not sensitive */);
-}
+ false /* not sensitive */,
+ &result->key_,
+ &result->public_key_);
-#if defined(USE_NSS)
-// static
-ECPrivateKey* ECPrivateKey::CreateSensitiveFromEncryptedPrivateKeyInfo(
- PK11SlotInfo* slot,
- const std::string& password,
- const std::vector<uint8>& encrypted_private_key_info,
- const std::vector<uint8>& subject_public_key_info) {
- return CreateFromEncryptedPrivateKeyInfoWithParams(
- slot,
- password,
- encrypted_private_key_info,
- subject_public_key_info,
- true /* permanent */,
- true /* sensitive */);
+ SECKEY_DestroySubjectPublicKeyInfo(decoded_spki);
+
+ if (success) {
+ CHECK_EQ(ecKey, SECKEY_GetPublicKeyType(result->public_key_));
+ return result.release();
+ }
+
+ return nullptr;
}
-#endif
// static
bool ECPrivateKey::ImportFromEncryptedPrivateKeyInfo(
@@ -313,93 +354,4 @@ bool ECPrivateKey::ExportECParams(std::vector<uint8>* output) {
ECPrivateKey::ECPrivateKey() : key_(NULL), public_key_(NULL) {}
-// static
-ECPrivateKey* ECPrivateKey::CreateWithParams(PK11SlotInfo* slot,
- bool permanent,
- bool sensitive) {
- if (!slot)
- return NULL;
-
- scoped_ptr<ECPrivateKey> result(new ECPrivateKey);
-
- SECOidData* oid_data = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1);
- if (!oid_data) {
- DLOG(ERROR) << "SECOID_FindOIDByTag: " << PORT_GetError();
- return NULL;
- }
-
- // SECKEYECParams is a SECItem containing the DER encoded ASN.1 ECParameters
- // value. For a named curve, that is just the OBJECT IDENTIFIER of the curve.
- // In addition to the oid data, the encoding requires one byte for the ASN.1
- // tag and one byte for the length (assuming the length is <= 127).
- DCHECK_LE(oid_data->oid.len, 127U);
- std::vector<unsigned char> parameters_buf(2 + oid_data->oid.len);
- SECKEYECParams ec_parameters = {
- siDEROID, &parameters_buf[0],
- static_cast<unsigned>(parameters_buf.size())
- };
-
- ec_parameters.data[0] = SEC_ASN1_OBJECT_ID;
- ec_parameters.data[1] = static_cast<unsigned char>(oid_data->oid.len);
- memcpy(ec_parameters.data + 2, oid_data->oid.data, oid_data->oid.len);
-
- result->key_ = PK11_GenerateKeyPair(slot,
- CKM_EC_KEY_PAIR_GEN,
- &ec_parameters,
- &result->public_key_,
- permanent,
- sensitive,
- NULL);
- if (!result->key_) {
- DLOG(ERROR) << "PK11_GenerateKeyPair: " << PORT_GetError();
- return NULL;
- }
- CHECK_EQ(ecKey, SECKEY_GetPublicKeyType(result->public_key_));
-
- return result.release();
-}
-
-// static
-ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfoWithParams(
- PK11SlotInfo* slot,
- const std::string& password,
- const std::vector<uint8>& encrypted_private_key_info,
- const std::vector<uint8>& subject_public_key_info,
- bool permanent,
- bool sensitive) {
- scoped_ptr<ECPrivateKey> result(new ECPrivateKey);
-
- SECItem encoded_spki = {
- siBuffer,
- const_cast<unsigned char*>(&subject_public_key_info[0]),
- static_cast<unsigned>(subject_public_key_info.size())
- };
- CERTSubjectPublicKeyInfo* decoded_spki = SECKEY_DecodeDERSubjectPublicKeyInfo(
- &encoded_spki);
- if (!decoded_spki) {
- DLOG(ERROR) << "SECKEY_DecodeDERSubjectPublicKeyInfo: " << PORT_GetError();
- return NULL;
- }
-
- bool success = ImportFromEncryptedPrivateKeyInfo(
- slot,
- password,
- &encrypted_private_key_info[0],
- encrypted_private_key_info.size(),
- decoded_spki,
- permanent,
- sensitive,
- &result->key_,
- &result->public_key_);
-
- SECKEY_DestroySubjectPublicKeyInfo(decoded_spki);
-
- if (success) {
- CHECK_EQ(ecKey, SECKEY_GetPublicKeyType(result->public_key_));
- return result.release();
- }
-
- return NULL;
-}
-
} // namespace crypto
diff --git a/chromium/crypto/ec_private_key_openssl.cc b/chromium/crypto/ec_private_key_openssl.cc
index 2d44759d8b0..35403f39ce8 100644
--- a/chromium/crypto/ec_private_key_openssl.cc
+++ b/chromium/crypto/ec_private_key_openssl.cc
@@ -25,9 +25,9 @@ namespace {
// style guide, hence the unusual parameter placement / types.
typedef int (*ExportBioFunction)(BIO* bio, const void* key);
-typedef ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>::Type
- ScopedPKCS8_PRIV_KEY_INFO;
-typedef ScopedOpenSSL<X509_SIG, X509_SIG_free>::Type ScopedX509_SIG;
+using ScopedPKCS8_PRIV_KEY_INFO =
+ ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>;
+using ScopedX509_SIG = ScopedOpenSSL<X509_SIG, X509_SIG_free>;
// Helper to export |key| into |output| via the specified ExportBioFunction.
bool ExportKeyWithBio(const void* key,
@@ -85,6 +85,13 @@ ECPrivateKey::~ECPrivateKey() {
EVP_PKEY_free(key_);
}
+ECPrivateKey* ECPrivateKey::Copy() const {
+ scoped_ptr<ECPrivateKey> copy(new ECPrivateKey);
+ if (key_)
+ copy->key_ = EVP_PKEY_up_ref(key_);
+ return copy.release();
+}
+
// static
bool ECPrivateKey::IsSupported() { return true; }
diff --git a/chromium/crypto/ec_private_key_unittest.cc b/chromium/crypto/ec_private_key_unittest.cc
index 6993a20b08f..cfd08f2d92b 100644
--- a/chromium/crypto/ec_private_key_unittest.cc
+++ b/chromium/crypto/ec_private_key_unittest.cc
@@ -82,7 +82,6 @@ TEST(ECPrivateKeyUnitTest, InitRandomTest) {
EXPECT_EQ(raw_pubkey2, raw_pubkey4);
}
-#if !defined(USE_OPENSSL)
TEST(ECPrivateKeyUnitTest, Copy) {
scoped_ptr<crypto::ECPrivateKey> keypair1(crypto::ECPrivateKey::Create());
scoped_ptr<crypto::ECPrivateKey> keypair2(keypair1->Copy());
@@ -113,7 +112,6 @@ TEST(ECPrivateKeyUnitTest, Copy) {
EXPECT_TRUE(keypair2->ExportRawPublicKey(&raw_pubkey2));
EXPECT_EQ(raw_pubkey1, raw_pubkey2);
}
-#endif // !defined(USE_OPENSSL)
TEST(ECPrivateKeyUnitTest, BadPasswordTest) {
const std::string password1;
diff --git a/chromium/crypto/ec_signature_creator_impl.h b/chromium/crypto/ec_signature_creator_impl.h
index f2ef9d65795..91a60a89963 100644
--- a/chromium/crypto/ec_signature_creator_impl.h
+++ b/chromium/crypto/ec_signature_creator_impl.h
@@ -13,14 +13,14 @@ namespace crypto {
class ECSignatureCreatorImpl : public ECSignatureCreator {
public:
explicit ECSignatureCreatorImpl(ECPrivateKey* key);
- virtual ~ECSignatureCreatorImpl();
+ ~ECSignatureCreatorImpl() override;
- virtual bool Sign(const uint8* data,
- int data_len,
- std::vector<uint8>* signature) override;
+ bool Sign(const uint8* data,
+ int data_len,
+ std::vector<uint8>* signature) override;
- virtual bool DecodeSignature(const std::vector<uint8>& der_sig,
- std::vector<uint8>* out_raw_sig) override;
+ bool DecodeSignature(const std::vector<uint8>& der_sig,
+ std::vector<uint8>* out_raw_sig) override;
private:
ECPrivateKey* key_;
diff --git a/chromium/crypto/ec_signature_creator_openssl.cc b/chromium/crypto/ec_signature_creator_openssl.cc
index 91e8a6a8d33..c422cef5f27 100644
--- a/chromium/crypto/ec_signature_creator_openssl.cc
+++ b/chromium/crypto/ec_signature_creator_openssl.cc
@@ -60,24 +60,13 @@ bool ECSignatureCreatorImpl::DecodeSignature(const std::vector<uint8>& der_sig,
// The result is made of two 32-byte vectors.
const size_t kMaxBytesPerBN = 32;
- std::vector<uint8> result;
- result.resize(2 * kMaxBytesPerBN);
- memset(&result[0], 0, result.size());
+ std::vector<uint8> result(2 * kMaxBytesPerBN);
- BIGNUM* r = ecdsa_sig.get()->r;
- BIGNUM* s = ecdsa_sig.get()->s;
- int r_bytes = BN_num_bytes(r);
- int s_bytes = BN_num_bytes(s);
- // NOTE: Can't really check for equality here since sometimes the value
- // returned by BN_num_bytes() will be slightly smaller than kMaxBytesPerBN.
- if (r_bytes > static_cast<int>(kMaxBytesPerBN) ||
- s_bytes > static_cast<int>(kMaxBytesPerBN)) {
- DLOG(ERROR) << "Invalid key sizes r(" << r_bytes << ") s(" << s_bytes
- << ")";
+ if (!BN_bn2bin_padded(&result[0], kMaxBytesPerBN, ecdsa_sig->r) ||
+ !BN_bn2bin_padded(&result[kMaxBytesPerBN], kMaxBytesPerBN,
+ ecdsa_sig->s)) {
return false;
}
- BN_bn2bin(ecdsa_sig.get()->r, &result[kMaxBytesPerBN - r_bytes]);
- BN_bn2bin(ecdsa_sig.get()->s, &result[2 * kMaxBytesPerBN - s_bytes]);
out_raw_sig->swap(result);
return true;
}
diff --git a/chromium/crypto/encryptor.h b/chromium/crypto/encryptor.h
index ec1498b66fc..8052a9fd574 100644
--- a/chromium/crypto/encryptor.h
+++ b/chromium/crypto/encryptor.h
@@ -13,7 +13,7 @@
#include "build/build_config.h"
#include "crypto/crypto_export.h"
-#if defined(USE_NSS) || \
+#if defined(USE_NSS_CERTS) || \
(!defined(USE_OPENSSL) && (defined(OS_WIN) || defined(OS_MACOSX)))
#include "crypto/scoped_nss_types.h"
#endif
@@ -122,7 +122,7 @@ class CRYPTO_EXPORT Encryptor {
const base::StringPiece& input,
std::string* output);
std::string iv_;
-#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
+#elif defined(USE_NSS_CERTS) || defined(OS_WIN) || defined(OS_MACOSX)
bool Crypt(PK11Context* context,
const base::StringPiece& input,
std::string* output);
diff --git a/chromium/crypto/encryptor_unittest.cc b/chromium/crypto/encryptor_unittest.cc
index 1a99783679f..79fe2cca1a6 100644
--- a/chromium/crypto/encryptor_unittest.cc
+++ b/chromium/crypto/encryptor_unittest.cc
@@ -92,7 +92,7 @@ TEST(EncryptorTest, DecryptWrongKey) {
// determine the padding length without checking every padding byte,
// Encryptor::Decrypt() will still return true. This is the case for NSS
// (crbug.com/124434).
-#if !defined(USE_NSS) && !defined(OS_WIN) && !defined(OS_MACOSX)
+#if !defined(USE_NSS_CERTS) && !defined(OS_WIN) && !defined(OS_MACOSX)
crypto::Encryptor decryptor;
EXPECT_TRUE(decryptor.Init(wrong_key.get(), crypto::Encryptor::CBC, iv));
EXPECT_FALSE(decryptor.Decrypt(ciphertext, &decrypted));
diff --git a/chromium/crypto/hmac_openssl.cc b/chromium/crypto/hmac_openssl.cc
index 92eea19d780..ef20290e223 100644
--- a/chromium/crypto/hmac_openssl.cc
+++ b/chromium/crypto/hmac_openssl.cc
@@ -20,45 +20,37 @@ struct HMACPlatformData {
std::vector<unsigned char> key;
};
-HMAC::HMAC(HashAlgorithm hash_alg)
- : hash_alg_(hash_alg), plat_(new HMACPlatformData()) {
+HMAC::HMAC(HashAlgorithm hash_alg) : hash_alg_(hash_alg) {
// Only SHA-1 and SHA-256 hash algorithms are supported now.
DCHECK(hash_alg_ == SHA1 || hash_alg_ == SHA256);
}
bool HMAC::Init(const unsigned char* key, size_t key_length) {
// Init must not be called more than once on the same HMAC object.
- DCHECK(plat_->key.empty());
-
+ DCHECK(!plat_);
+ plat_.reset(new HMACPlatformData());
plat_->key.assign(key, key + key_length);
- if (key_length == 0) {
- // Special-case: if the key is empty, use a key with one zero
- // byte. OpenSSL's HMAC function breaks when passed a NULL key. (It calls
- // HMAC_Init_ex which treats a NULL key as having already been initialized
- // with a key previously.) HMAC pads keys with zeros, so this key is
- // equivalent.
- plat_->key.push_back(0);
- }
return true;
}
HMAC::~HMAC() {
- // Zero out key copy.
- plat_->key.assign(plat_->key.size(), 0);
- STLClearObject(&plat_->key);
+ if (plat_) {
+ // Zero out key copy.
+ plat_->key.assign(plat_->key.size(), 0);
+ STLClearObject(&plat_->key);
+ }
}
bool HMAC::Sign(const base::StringPiece& data,
unsigned char* digest,
size_t digest_length) const {
- DCHECK(!plat_->key.empty()); // Init must be called before Sign.
+ DCHECK(plat_); // Init must be called before Sign.
ScopedOpenSSLSafeSizeBuffer<EVP_MAX_MD_SIZE> result(digest, digest_length);
return !!::HMAC(hash_alg_ == SHA1 ? EVP_sha1() : EVP_sha256(),
- &plat_->key[0], plat_->key.size(),
- reinterpret_cast<const unsigned char*>(data.data()),
- data.size(),
- result.safe_buffer(), NULL);
+ vector_as_array(&plat_->key), plat_->key.size(),
+ reinterpret_cast<const unsigned char*>(data.data()),
+ data.size(), result.safe_buffer(), NULL);
}
} // namespace crypto
diff --git a/chromium/crypto/mock_apple_keychain.cc b/chromium/crypto/mock_apple_keychain.cc
index 1ddfc867946..a1faa65382a 100644
--- a/chromium/crypto/mock_apple_keychain.cc
+++ b/chromium/crypto/mock_apple_keychain.cc
@@ -3,9 +3,23 @@
// found in the LICENSE file.
#include "base/logging.h"
+#include "base/metrics/histogram.h"
#include "base/time/time.h"
#include "crypto/mock_apple_keychain.h"
+namespace {
+
+// Adds an entry to a local histogram to indicate that the Apple Keychain would
+// have been accessed, if this class were not a mock of the Apple Keychain.
+void IncrementKeychainAccessHistogram() {
+ // This local histogram is accessed by Telemetry to track the number of times
+ // the keychain is accessed, since keychain access is known to be synchronous
+ // and slow.
+ LOCAL_HISTOGRAM_BOOLEAN("OSX.Keychain.Access", true);
+}
+
+} // namespace
+
namespace crypto {
OSStatus MockAppleKeychain::FindGenericPassword(
@@ -17,6 +31,8 @@ OSStatus MockAppleKeychain::FindGenericPassword(
UInt32* passwordLength,
void** passwordData,
SecKeychainItemRef* itemRef) const {
+ IncrementKeychainAccessHistogram();
+
// When simulating |noErr|, return canned |passwordData| and
// |passwordLength|. Otherwise, just return given code.
if (find_generic_result_ == noErr) {
@@ -48,6 +64,8 @@ OSStatus MockAppleKeychain::AddGenericPassword(
UInt32 passwordLength,
const void* passwordData,
SecKeychainItemRef* itemRef) const {
+ IncrementKeychainAccessHistogram();
+
called_add_generic_ = true;
DCHECK_GT(passwordLength, 0U);
@@ -58,4 +76,9 @@ OSStatus MockAppleKeychain::AddGenericPassword(
return noErr;
}
+std::string MockAppleKeychain::GetEncryptionPassword() const {
+ IncrementKeychainAccessHistogram();
+ return "mock_password";
+}
+
} // namespace crypto
diff --git a/chromium/crypto/mock_apple_keychain.h b/chromium/crypto/mock_apple_keychain.h
index d9573162ee6..3948d489755 100644
--- a/chromium/crypto/mock_apple_keychain.h
+++ b/chromium/crypto/mock_apple_keychain.h
@@ -29,70 +29,70 @@ namespace crypto {
class CRYPTO_EXPORT MockAppleKeychain : public AppleKeychain {
public:
MockAppleKeychain();
- virtual ~MockAppleKeychain();
+ ~MockAppleKeychain() override;
// AppleKeychain implementation.
- virtual OSStatus FindGenericPassword(
- CFTypeRef keychainOrArray,
- UInt32 serviceNameLength,
- const char* serviceName,
- UInt32 accountNameLength,
- const char* accountName,
- UInt32* passwordLength,
- void** passwordData,
- SecKeychainItemRef* itemRef) const override;
- virtual OSStatus ItemFreeContent(SecKeychainAttributeList* attrList,
- void* data) const override;
- virtual OSStatus AddGenericPassword(
- SecKeychainRef keychain,
- UInt32 serviceNameLength,
- const char* serviceName,
- UInt32 accountNameLength,
- const char* accountName,
- UInt32 passwordLength,
- const void* passwordData,
- SecKeychainItemRef* itemRef) const override;
+ OSStatus FindGenericPassword(CFTypeRef keychainOrArray,
+ UInt32 serviceNameLength,
+ const char* serviceName,
+ UInt32 accountNameLength,
+ const char* accountName,
+ UInt32* passwordLength,
+ void** passwordData,
+ SecKeychainItemRef* itemRef) const override;
+ OSStatus ItemFreeContent(SecKeychainAttributeList* attrList,
+ void* data) const override;
+ OSStatus AddGenericPassword(SecKeychainRef keychain,
+ UInt32 serviceNameLength,
+ const char* serviceName,
+ UInt32 accountNameLength,
+ const char* accountName,
+ UInt32 passwordLength,
+ const void* passwordData,
+ SecKeychainItemRef* itemRef) const override;
+
+ // Returns the password that OSCrypt uses to generate its encryption key.
+ std::string GetEncryptionPassword() const;
#if !defined(OS_IOS)
- virtual OSStatus ItemCopyAttributesAndData(
- SecKeychainItemRef itemRef,
- SecKeychainAttributeInfo* info,
- SecItemClass* itemClass,
- SecKeychainAttributeList** attrList,
- UInt32* length,
- void** outData) const override;
+ OSStatus ItemCopyAttributesAndData(SecKeychainItemRef itemRef,
+ SecKeychainAttributeInfo* info,
+ SecItemClass* itemClass,
+ SecKeychainAttributeList** attrList,
+ UInt32* length,
+ void** outData) const override;
// Pass "fail_me" as the data to get errSecAuthFailed.
- virtual OSStatus ItemModifyAttributesAndData(
- SecKeychainItemRef itemRef,
- const SecKeychainAttributeList* attrList,
- UInt32 length,
- const void* data) const override;
- virtual OSStatus ItemFreeAttributesAndData(SecKeychainAttributeList* attrList,
- void* data) const override;
- virtual OSStatus ItemDelete(SecKeychainItemRef itemRef) const override;
- virtual OSStatus SearchCreateFromAttributes(
+ OSStatus ItemModifyAttributesAndData(SecKeychainItemRef itemRef,
+ const SecKeychainAttributeList* attrList,
+ UInt32 length,
+ const void* data) const override;
+ OSStatus ItemFreeAttributesAndData(SecKeychainAttributeList* attrList,
+ void* data) const override;
+ OSStatus ItemDelete(SecKeychainItemRef itemRef) const override;
+ OSStatus SearchCreateFromAttributes(
CFTypeRef keychainOrArray,
SecItemClass itemClass,
const SecKeychainAttributeList* attrList,
SecKeychainSearchRef* searchRef) const override;
- virtual OSStatus SearchCopyNext(SecKeychainSearchRef searchRef,
- SecKeychainItemRef* itemRef) const override;
+ OSStatus SearchCopyNext(SecKeychainSearchRef searchRef,
+ SecKeychainItemRef* itemRef) const override;
// Pass "some.domain.com" as the serverName to get errSecDuplicateItem.
- virtual OSStatus AddInternetPassword(
- SecKeychainRef keychain,
- UInt32 serverNameLength,
- const char* serverName,
- UInt32 securityDomainLength,
- const char* securityDomain,
- UInt32 accountNameLength,
- const char* accountName,
- UInt32 pathLength, const char* path,
- UInt16 port, SecProtocolType protocol,
- SecAuthenticationType authenticationType,
- UInt32 passwordLength,
- const void* passwordData,
- SecKeychainItemRef* itemRef) const override;
- virtual void Free(CFTypeRef ref) const override;
+ OSStatus AddInternetPassword(SecKeychainRef keychain,
+ UInt32 serverNameLength,
+ const char* serverName,
+ UInt32 securityDomainLength,
+ const char* securityDomain,
+ UInt32 accountNameLength,
+ const char* accountName,
+ UInt32 pathLength,
+ const char* path,
+ UInt16 port,
+ SecProtocolType protocol,
+ SecAuthenticationType authenticationType,
+ UInt32 passwordLength,
+ const void* passwordData,
+ SecKeychainItemRef* itemRef) const override;
+ void Free(CFTypeRef ref) const override;
// Return the counts of objects returned by Create/Copy functions but never
// Free'd as they should have been.
diff --git a/chromium/crypto/nss_crypto_module_delegate.h b/chromium/crypto/nss_crypto_module_delegate.h
index 00b2b75335f..6c1da68161d 100644
--- a/chromium/crypto/nss_crypto_module_delegate.h
+++ b/chromium/crypto/nss_crypto_module_delegate.h
@@ -42,7 +42,7 @@ class CryptoModuleBlockingPasswordDelegate {
// slot in which to act. (Eg, which slot to store a generated key in.)
class NSSCryptoModuleDelegate : public CryptoModuleBlockingPasswordDelegate {
public:
- virtual ~NSSCryptoModuleDelegate() {}
+ ~NSSCryptoModuleDelegate() override {}
// Get the slot to store the generated key.
virtual ScopedPK11Slot RequestSlot() = 0;
diff --git a/chromium/crypto/nss_key_util.cc b/chromium/crypto/nss_key_util.cc
new file mode 100644
index 00000000000..77435fba361
--- /dev/null
+++ b/chromium/crypto/nss_key_util.cc
@@ -0,0 +1,163 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "crypto/nss_key_util.h"
+
+#include <cryptohi.h>
+#include <keyhi.h>
+#include <pk11pub.h>
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "crypto/nss_util.h"
+
+#if defined(USE_NSS_CERTS)
+#include <secmod.h>
+#include "crypto/nss_util_internal.h"
+#endif
+
+namespace crypto {
+
+namespace {
+
+#if defined(USE_NSS_CERTS)
+
+struct PublicKeyInfoDeleter {
+ inline void operator()(CERTSubjectPublicKeyInfo* spki) {
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+ }
+};
+
+typedef scoped_ptr<CERTSubjectPublicKeyInfo, PublicKeyInfoDeleter>
+ ScopedPublicKeyInfo;
+
+// Decodes |input| as a SubjectPublicKeyInfo and returns a SECItem containing
+// the CKA_ID of that public key or nullptr on error.
+ScopedSECItem MakeIDFromSPKI(const std::vector<uint8_t>& input) {
+ // First, decode and save the public key.
+ SECItem key_der;
+ key_der.type = siBuffer;
+ key_der.data = const_cast<unsigned char*>(vector_as_array(&input));
+ key_der.len = input.size();
+
+ ScopedPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der));
+ if (!spki)
+ return nullptr;
+
+ ScopedSECKEYPublicKey result(SECKEY_ExtractPublicKey(spki.get()));
+ if (!result)
+ return nullptr;
+
+ // See pk11_MakeIDFromPublicKey from NSS. For now, only RSA keys are
+ // supported.
+ if (SECKEY_GetPublicKeyType(result.get()) != rsaKey)
+ return nullptr;
+
+ return ScopedSECItem(PK11_MakeIDFromPubKey(&result->u.rsa.modulus));
+}
+
+#endif // defined(USE_NSS_CERTS)
+
+} // namespace
+
+bool GenerateRSAKeyPairNSS(PK11SlotInfo* slot,
+ uint16_t num_bits,
+ bool permanent,
+ ScopedSECKEYPublicKey* public_key,
+ ScopedSECKEYPrivateKey* private_key) {
+ DCHECK(slot);
+
+ PK11RSAGenParams param;
+ param.keySizeInBits = num_bits;
+ param.pe = 65537L;
+ SECKEYPublicKey* public_key_raw = nullptr;
+ private_key->reset(PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN,
+ &param, &public_key_raw, permanent,
+ permanent /* sensitive */, nullptr));
+ if (!*private_key)
+ return false;
+
+ public_key->reset(public_key_raw);
+ return true;
+}
+
+ScopedSECKEYPrivateKey ImportNSSKeyFromPrivateKeyInfo(
+ PK11SlotInfo* slot,
+ const std::vector<uint8_t>& input,
+ bool permanent) {
+ DCHECK(slot);
+
+ ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ DCHECK(arena);
+
+ // Excess data is illegal, but NSS silently accepts it, so first ensure that
+ // |input| consists of a single ASN.1 element.
+ SECItem input_item;
+ input_item.data = const_cast<unsigned char*>(vector_as_array(&input));
+ input_item.len = input.size();
+ SECItem der_private_key_info;
+ SECStatus rv =
+ SEC_QuickDERDecodeItem(arena.get(), &der_private_key_info,
+ SEC_ASN1_GET(SEC_AnyTemplate), &input_item);
+ if (rv != SECSuccess)
+ return nullptr;
+
+ // Allow the private key to be used for key unwrapping, data decryption,
+ // and signature generation.
+ const unsigned int key_usage =
+ KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | KU_DIGITAL_SIGNATURE;
+ SECKEYPrivateKey* key_raw = nullptr;
+ rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
+ slot, &der_private_key_info, nullptr, nullptr, permanent,
+ permanent /* sensitive */, key_usage, &key_raw, nullptr);
+ if (rv != SECSuccess)
+ return nullptr;
+ return ScopedSECKEYPrivateKey(key_raw);
+}
+
+#if defined(USE_NSS_CERTS)
+
+ScopedSECKEYPrivateKey FindNSSKeyFromPublicKeyInfo(
+ const std::vector<uint8_t>& input) {
+ EnsureNSSInit();
+
+ ScopedSECItem cka_id(MakeIDFromSPKI(input));
+ if (!cka_id)
+ return nullptr;
+
+ // Search all slots in all modules for the key with the given ID.
+ AutoSECMODListReadLock auto_lock;
+ const SECMODModuleList* head = SECMOD_GetDefaultModuleList();
+ for (const SECMODModuleList* item = head; item != nullptr;
+ item = item->next) {
+ int slot_count = item->module->loaded ? item->module->slotCount : 0;
+ for (int i = 0; i < slot_count; i++) {
+ // Look for the key in slot |i|.
+ ScopedSECKEYPrivateKey key(
+ PK11_FindKeyByKeyID(item->module->slots[i], cka_id.get(), nullptr));
+ if (key)
+ return key.Pass();
+ }
+ }
+
+ // The key wasn't found in any module.
+ return nullptr;
+}
+
+ScopedSECKEYPrivateKey FindNSSKeyFromPublicKeyInfoInSlot(
+ const std::vector<uint8_t>& input,
+ PK11SlotInfo* slot) {
+ DCHECK(slot);
+
+ ScopedSECItem cka_id(MakeIDFromSPKI(input));
+ if (!cka_id)
+ return nullptr;
+
+ return ScopedSECKEYPrivateKey(
+ PK11_FindKeyByKeyID(slot, cka_id.get(), nullptr));
+}
+
+#endif // defined(USE_NSS_CERTS)
+
+} // namespace crypto
diff --git a/chromium/crypto/nss_key_util.h b/chromium/crypto/nss_key_util.h
new file mode 100644
index 00000000000..12b948d25bb
--- /dev/null
+++ b/chromium/crypto/nss_key_util.h
@@ -0,0 +1,58 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CRYPTO_NSS_KEY_UTIL_H_
+#define CRYPTO_NSS_KEY_UTIL_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "build/build_config.h"
+#include "crypto/crypto_export.h"
+#include "crypto/scoped_nss_types.h"
+
+typedef struct PK11SlotInfoStr PK11SlotInfo;
+
+namespace crypto {
+
+// Generates a new RSA keypair of size |num_bits| in |slot|. Returns true on
+// success and false on failure. If |permanent| is true, the resulting key is
+// permanent and is not exportable in plaintext form.
+CRYPTO_EXPORT bool GenerateRSAKeyPairNSS(
+ PK11SlotInfo* slot,
+ uint16_t num_bits,
+ bool permanent,
+ ScopedSECKEYPublicKey* out_public_key,
+ ScopedSECKEYPrivateKey* out_private_key);
+
+// Imports a private key from |input| into |slot|. |input| is interpreted as a
+// DER-encoded PrivateKeyInfo block from PKCS #8. Returns nullptr on error. If
+// |permanent| is true, the resulting key is permanent and is not exportable in
+// plaintext form.
+CRYPTO_EXPORT ScopedSECKEYPrivateKey
+ImportNSSKeyFromPrivateKeyInfo(PK11SlotInfo* slot,
+ const std::vector<uint8_t>& input,
+ bool permanent);
+
+#if defined(USE_NSS_CERTS)
+
+// Decodes |input| as a DER-encoded X.509 SubjectPublicKeyInfo and searches for
+// the private key half in the key database. Returns the private key on success
+// or nullptr on error.
+CRYPTO_EXPORT ScopedSECKEYPrivateKey
+FindNSSKeyFromPublicKeyInfo(const std::vector<uint8_t>& input);
+
+// Decodes |input| as a DER-encoded X.509 SubjectPublicKeyInfo and searches for
+// the private key half in the slot specified by |slot|. Returns the private key
+// on success or nullptr on error.
+CRYPTO_EXPORT ScopedSECKEYPrivateKey
+FindNSSKeyFromPublicKeyInfoInSlot(const std::vector<uint8_t>& input,
+ PK11SlotInfo* slot);
+
+#endif // defined(USE_NSS_CERTS)
+
+} // namespace crypto
+
+#endif // CRYPTO_NSS_KEY_UTIL_H_
diff --git a/chromium/crypto/nss_key_util_unittest.cc b/chromium/crypto/nss_key_util_unittest.cc
new file mode 100644
index 00000000000..f8de8e236bb
--- /dev/null
+++ b/chromium/crypto/nss_key_util_unittest.cc
@@ -0,0 +1,87 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "crypto/nss_key_util.h"
+
+#include <keyhi.h>
+#include <pk11pub.h>
+
+#include <vector>
+
+#include "crypto/nss_util.h"
+#include "crypto/scoped_nss_types.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace crypto {
+
+class NSSKeyUtilTest : public testing::Test {
+ public:
+ void SetUp() override {
+ EnsureNSSInit();
+
+ internal_slot_.reset(PK11_GetInternalSlot());
+ ASSERT_TRUE(internal_slot_);
+ }
+
+ PK11SlotInfo* internal_slot() { return internal_slot_.get(); }
+
+ private:
+ ScopedPK11Slot internal_slot_;
+};
+
+TEST_F(NSSKeyUtilTest, GenerateRSAKeyPairNSS) {
+ const int kKeySizeBits = 1024;
+
+ ScopedSECKEYPublicKey public_key;
+ ScopedSECKEYPrivateKey private_key;
+ ASSERT_TRUE(GenerateRSAKeyPairNSS(internal_slot(), kKeySizeBits,
+ false /* not permanent */, &public_key,
+ &private_key));
+
+ EXPECT_EQ(rsaKey, SECKEY_GetPublicKeyType(public_key.get()));
+ EXPECT_EQ(rsaKey, SECKEY_GetPrivateKeyType(private_key.get()));
+ EXPECT_EQ((kKeySizeBits + 7) / 8,
+ PK11_GetPrivateModulusLen(private_key.get()));
+}
+
+#if defined(USE_NSS_CERTS)
+TEST_F(NSSKeyUtilTest, FindNSSKeyFromPublicKeyInfo) {
+ // Create an NSS keypair, which will put the keys in the user's NSSDB.
+ ScopedSECKEYPublicKey public_key;
+ ScopedSECKEYPrivateKey private_key;
+ ASSERT_TRUE(GenerateRSAKeyPairNSS(internal_slot(), 256,
+ false /* not permanent */, &public_key,
+ &private_key));
+
+ ScopedSECItem item(SECKEY_EncodeDERSubjectPublicKeyInfo(public_key.get()));
+ ASSERT_TRUE(item);
+ std::vector<uint8_t> public_key_der(item->data, item->data + item->len);
+
+ ScopedSECKEYPrivateKey private_key2 =
+ FindNSSKeyFromPublicKeyInfo(public_key_der);
+ ASSERT_TRUE(private_key2);
+ EXPECT_EQ(private_key->pkcs11ID, private_key2->pkcs11ID);
+}
+
+TEST_F(NSSKeyUtilTest, FailedFindNSSKeyFromPublicKeyInfo) {
+ // Create an NSS keypair, which will put the keys in the user's NSSDB.
+ ScopedSECKEYPublicKey public_key;
+ ScopedSECKEYPrivateKey private_key;
+ ASSERT_TRUE(GenerateRSAKeyPairNSS(internal_slot(), 256,
+ false /* not permanent */, &public_key,
+ &private_key));
+
+ ScopedSECItem item(SECKEY_EncodeDERSubjectPublicKeyInfo(public_key.get()));
+ ASSERT_TRUE(item);
+ std::vector<uint8_t> public_key_der(item->data, item->data + item->len);
+
+ // Remove the keys from the DB, and make sure we can't find them again.
+ PK11_DestroyTokenObject(private_key->pkcs11Slot, private_key->pkcs11ID);
+ PK11_DestroyTokenObject(public_key->pkcs11Slot, public_key->pkcs11ID);
+
+ EXPECT_FALSE(FindNSSKeyFromPublicKeyInfo(public_key_der));
+}
+#endif // defined(USE_NSS_CERTS)
+
+} // namespace crypto
diff --git a/chromium/crypto/nss_util.cc b/chromium/crypto/nss_util.cc
index 8f9865a3c6c..df9316054e7 100644
--- a/chromium/crypto/nss_util.cc
+++ b/chromium/crypto/nss_util.cc
@@ -18,6 +18,10 @@
#include <sys/param.h>
#endif
+#if defined(OS_CHROMEOS)
+#include <dlfcn.h>
+#endif
+
#include <map>
#include <vector>
@@ -43,14 +47,13 @@
#include "base/threading/worker_pool.h"
#include "build/build_config.h"
-// USE_NSS means we use NSS for everything crypto-related. If USE_NSS is not
-// defined, such as on Mac and Windows, we use NSS for SSL only -- we don't
-// use NSS for crypto or certificate verification, and we don't use the NSS
-// certificate and key databases.
-#if defined(USE_NSS)
+// USE_NSS_CERTS means NSS is used for certificates and platform integration.
+// This requires additional support to manage the platform certificate and key
+// stores.
+#if defined(USE_NSS_CERTS)
#include "base/synchronization/lock.h"
#include "crypto/nss_crypto_module_delegate.h"
-#endif // defined(USE_NSS)
+#endif // defined(USE_NSS_CERTS)
namespace crypto {
@@ -80,7 +83,7 @@ std::string GetNSSErrorMessage() {
return result;
}
-#if defined(USE_NSS)
+#if defined(USE_NSS_CERTS)
#if !defined(OS_CHROMEOS)
base::FilePath GetDefaultConfigDirectory() {
base::FilePath dir;
@@ -142,8 +145,8 @@ char* PKCS11PasswordFunc(PK11SlotInfo* slot, PRBool retry, void* arg) {
// the NSS environment variable NSS_SDB_USE_CACHE to "yes" to override NSS's
// detection when database_dir is on NFS. See http://crbug.com/48585.
//
-// TODO(wtc): port this function to other USE_NSS platforms. It is defined
-// only for OS_LINUX and OS_OPENBSD simply because the statfs structure
+// TODO(wtc): port this function to other USE_NSS_CERTS platforms. It is
+// defined only for OS_LINUX and OS_OPENBSD simply because the statfs structure
// is OS-specific.
//
// Because this function sets an environment variable it must be run before we
@@ -170,7 +173,7 @@ void UseLocalCacheOfNSSDatabaseIfNFS(const base::FilePath& database_dir) {
}
}
-#endif // defined(USE_NSS)
+#endif // defined(USE_NSS_CERTS)
// A singleton to initialize/deinitialize NSPR.
// Separate from the NSS singleton because we initialize NSPR on the UI thread.
@@ -268,6 +271,38 @@ class ChromeOSUserData {
SlotReadyCallbackList;
SlotReadyCallbackList tpm_ready_callback_list_;
};
+
+class ScopedChapsLoadFixup {
+ public:
+ ScopedChapsLoadFixup();
+ ~ScopedChapsLoadFixup();
+
+ private:
+#if defined(COMPONENT_BUILD)
+ void *chaps_handle_;
+#endif
+};
+
+#if defined(COMPONENT_BUILD)
+
+ScopedChapsLoadFixup::ScopedChapsLoadFixup() {
+ // HACK: libchaps links the system protobuf and there are symbol conflicts
+ // with the bundled copy. Load chaps with RTLD_DEEPBIND to workaround.
+ chaps_handle_ = dlopen(kChapsPath, RTLD_LOCAL | RTLD_NOW | RTLD_DEEPBIND);
+}
+
+ScopedChapsLoadFixup::~ScopedChapsLoadFixup() {
+ // LoadModule() will have taken a 2nd reference.
+ if (chaps_handle_)
+ dlclose(chaps_handle_);
+}
+
+#else
+
+ScopedChapsLoadFixup::ScopedChapsLoadFixup() {}
+ScopedChapsLoadFixup::~ScopedChapsLoadFixup() {}
+
+#endif // defined(COMPONENT_BUILD)
#endif // defined(OS_CHROMEOS)
class NSSInitSingleton {
@@ -361,6 +396,8 @@ class NSSInitSingleton {
// This tries to load the Chaps module so NSS can talk to the hardware
// TPM.
if (!tpm_args->chaps_module) {
+ ScopedChapsLoadFixup chaps_loader;
+
DVLOG(3) << "Loading chaps...";
tpm_args->chaps_module = LoadModule(
kChapsModuleName,
@@ -628,11 +665,11 @@ class NSSInitSingleton {
}
#endif
-#if defined(USE_NSS)
+#if defined(USE_NSS_CERTS)
base::Lock* write_lock() {
return &write_lock_;
}
-#endif // defined(USE_NSS)
+#endif // defined(USE_NSS_CERTS)
// This method is used to force NSS to be initialized without a DB.
// Call this method before NSSInitSingleton() is constructed.
@@ -659,11 +696,11 @@ class NSSInitSingleton {
EnsureNSPRInit();
// We *must* have NSS >= 3.14.3.
- COMPILE_ASSERT(
+ static_assert(
(NSS_VMAJOR == 3 && NSS_VMINOR == 14 && NSS_VPATCH >= 3) ||
(NSS_VMAJOR == 3 && NSS_VMINOR > 14) ||
(NSS_VMAJOR > 3),
- nss_version_check_failed);
+ "nss version check failed");
// Also check the run-time NSS version.
// NSS_VersionCheck is a >= check, not strict equality.
if (!NSS_VersionCheck("3.14.3")) {
@@ -676,7 +713,7 @@ class NSSInitSingleton {
SECStatus status = SECFailure;
bool nodb_init = force_nodb_init_;
-#if !defined(USE_NSS)
+#if !defined(USE_NSS_CERTS)
// Use the system certificate store, so initialize NSS without database.
nodb_init = true;
#endif
@@ -691,7 +728,7 @@ class NSSInitSingleton {
root_ = InitDefaultRootCerts();
#endif // defined(OS_IOS)
} else {
-#if defined(USE_NSS)
+#if defined(USE_NSS_CERTS)
base::FilePath database_dir = GetInitialConfigDirectory();
if (!database_dir.empty()) {
// This duplicates the work which should have been done in
@@ -738,7 +775,7 @@ class NSSInitSingleton {
}
root_ = InitDefaultRootCerts();
-#endif // defined(USE_NSS)
+#endif // defined(USE_NSS_CERTS)
}
// Disable MD5 certificate signatures. (They are disabled by default in
@@ -783,7 +820,7 @@ class NSSInitSingleton {
}
}
-#if defined(USE_NSS) || defined(OS_IOS)
+#if defined(USE_NSS_CERTS) || defined(OS_IOS)
// Load nss's built-in root certs.
SECMODModule* InitDefaultRootCerts() {
SECMODModule* root = LoadModule("Root Certs", "libnssckbi.so", NULL);
@@ -835,7 +872,8 @@ class NSSInitSingleton {
base::CPU cpu;
if (cpu.has_avx_hardware() && !cpu.has_avx()) {
- base::Environment::Create()->SetVar("NSS_DISABLE_HW_AES", "1");
+ scoped_ptr<base::Environment> env(base::Environment::Create());
+ env->SetVar("NSS_DISABLE_HW_AES", "1");
}
}
}
@@ -855,11 +893,11 @@ class NSSInitSingleton {
ChromeOSUserMap chromeos_user_map_;
ScopedPK11Slot test_system_slot_;
#endif
-#if defined(USE_NSS)
+#if defined(USE_NSS_CERTS)
// TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011
// is fixed, we will no longer need the lock.
base::Lock write_lock_;
-#endif // defined(USE_NSS)
+#endif // defined(USE_NSS_CERTS)
base::ThreadChecker thread_checker_;
};
@@ -871,7 +909,7 @@ base::LazyInstance<NSSInitSingleton>::Leaky
g_nss_singleton = LAZY_INSTANCE_INITIALIZER;
} // namespace
-#if defined(USE_NSS)
+#if defined(USE_NSS_CERTS)
ScopedPK11Slot OpenSoftwareNSSDB(const base::FilePath& path,
const std::string& description) {
const std::string modspec =
@@ -930,7 +968,7 @@ void DisableNSSForkCheck() {
void LoadNSSLibraries() {
// Some NSS libraries are linked dynamically so load them here.
-#if defined(USE_NSS)
+#if defined(USE_NSS_CERTS)
// Try to search for multiple directories to load the libraries.
std::vector<base::FilePath> paths;
@@ -979,14 +1017,14 @@ void LoadNSSLibraries() {
} else {
LOG(ERROR) << "Failed to load NSS libraries.";
}
-#endif // defined(USE_NSS)
+#endif // defined(USE_NSS_CERTS)
}
bool CheckNSSVersion(const char* version) {
return !!NSS_VersionCheck(version);
}
-#if defined(USE_NSS)
+#if defined(USE_NSS_CERTS)
base::Lock* GetNSSWriteLock() {
return g_nss_singleton.Get().write_lock();
}
@@ -1012,7 +1050,7 @@ AutoSECMODListReadLock::AutoSECMODListReadLock()
AutoSECMODListReadLock::~AutoSECMODListReadLock() {
SECMOD_ReleaseReadLock(lock_);
}
-#endif // defined(USE_NSS)
+#endif // defined(USE_NSS_CERTS)
#if defined(OS_CHROMEOS)
ScopedPK11Slot GetSystemNSSKeySlot(
diff --git a/chromium/crypto/nss_util.h b/chromium/crypto/nss_util.h
index 56fdfa6b659..1ca0de3e777 100644
--- a/chromium/crypto/nss_util.h
+++ b/chromium/crypto/nss_util.h
@@ -22,7 +22,7 @@ class Time;
// initialization functions.
namespace crypto {
-#if defined(USE_NSS)
+#if defined(USE_NSS_CERTS)
// EarlySetupForNSSInit performs lightweight setup which must occur before the
// process goes multithreaded. This does not initialise NSS. For test, see
// EnsureNSSInit.
@@ -127,7 +127,7 @@ CRYPTO_EXPORT base::Time PRTimeToBaseTime(int64 prtime);
// We use a int64 instead of PRTime here to avoid depending on NSPR headers.
CRYPTO_EXPORT int64 BaseTimeToPRTime(base::Time time);
-#if defined(USE_NSS)
+#if defined(USE_NSS_CERTS)
// NSS has a bug which can cause a deadlock or stall in some cases when writing
// to the certDB and keyDB. It also has a bug which causes concurrent key pair
// generations to scribble over each other. To work around this, we synchronize
@@ -148,7 +148,7 @@ class CRYPTO_EXPORT AutoNSSWriteLock {
base::Lock *lock_;
DISALLOW_COPY_AND_ASSIGN(AutoNSSWriteLock);
};
-#endif // defined(USE_NSS)
+#endif // defined(USE_NSS_CERTS)
} // namespace crypto
diff --git a/chromium/crypto/openssl_util.cc b/chromium/crypto/openssl_util.cc
index f41b55a8fff..964d83b8433 100644
--- a/chromium/crypto/openssl_util.cc
+++ b/chromium/crypto/openssl_util.cc
@@ -48,6 +48,18 @@ class OpenSSLInitSingleton {
private:
friend struct DefaultSingletonTraits<OpenSSLInitSingleton>;
OpenSSLInitSingleton() {
+#if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
+ const bool has_neon =
+ (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
+ // CRYPTO_set_NEON_capable is called before |SSL_library_init| because this
+ // stops BoringSSL from probing for NEON support via SIGILL in the case
+ // that getauxval isn't present.
+ CRYPTO_set_NEON_capable(has_neon);
+ // See https://code.google.com/p/chromium/issues/detail?id=341598
+ base::CPU cpu;
+ CRYPTO_set_NEON_functional(!cpu.has_broken_neon());
+#endif
+
SSL_load_error_strings();
SSL_library_init();
int num_locks = CRYPTO_num_locks();
@@ -56,16 +68,6 @@ class OpenSSLInitSingleton {
locks_.push_back(new base::Lock());
CRYPTO_set_locking_callback(LockingCallback);
CRYPTO_THREADID_set_callback(CurrentThreadId);
-
-#if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
- const bool has_neon =
- (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
- if (has_neon)
- CRYPTO_set_NEON_capable(1);
- // See https://code.google.com/p/chromium/issues/detail?id=341598
- base::CPU cpu;
- CRYPTO_set_NEON_functional(!cpu.has_broken_neon());
-#endif
}
~OpenSSLInitSingleton() {
@@ -114,7 +116,7 @@ void EnsureOpenSSLInit() {
void ClearOpenSSLERRStack(const tracked_objects::Location& location) {
if (logging::DEBUG_MODE && VLOG_IS_ON(1)) {
- int error_num = ERR_peek_error();
+ uint32_t error_num = ERR_peek_error();
if (error_num == 0)
return;
diff --git a/chromium/crypto/p224.cc b/chromium/crypto/p224.cc
index 5f76fbc259b..11946a9413c 100644
--- a/chromium/crypto/p224.cc
+++ b/chromium/crypto/p224.cc
@@ -123,6 +123,15 @@ typedef uint64 LargeFieldElement[15];
// ReduceLarge converts a LargeFieldElement to a FieldElement.
//
// in[i] < 2**62
+
+// GCC 4.9 incorrectly vectorizes the first coefficient elimination loop, so
+// disable that optimization via pragma. Don't use the pragma under Clang, since
+// clang doesn't understand it.
+// TODO(wez): Remove this when crbug.com/439566 is fixed.
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC optimize("no-tree-vectorize")
+#endif
+
void ReduceLarge(FieldElement* out, LargeFieldElement* inptr) {
LargeFieldElement& in(*inptr);
@@ -164,6 +173,12 @@ void ReduceLarge(FieldElement* out, LargeFieldElement* inptr) {
// out[5..7] < 2**28
}
+// TODO(wez): Remove this when crbug.com/439566 is fixed.
+#if defined(__GNUC__) && !defined(__clang__)
+// Reenable "tree-vectorize" optimization if it got disabled for ReduceLarge.
+#pragma GCC reset_options
+#endif
+
// Mul computes *out = a*b
//
// a[i] < 2**29, b[i] < 2**30 (or vice versa)
@@ -460,8 +475,8 @@ void AddJacobian(Point *out,
uint32 x_equal = IsZero(h);
// I = (2*H)²
- for (int j = 0; j < 8; j++) {
- i[j] = h[j] << 1;
+ for (int k = 0; k < 8; k++) {
+ i[k] = h[k] << 1;
}
Reduce(&i);
Square(&i, i);
@@ -480,8 +495,8 @@ void AddJacobian(Point *out,
return;
}
- for (int i = 0; i < 8; i++) {
- r[i] <<= 1;
+ for (int k = 0; k < 8; k++) {
+ r[k] <<= 1;
}
Reduce(&r);
@@ -498,8 +513,8 @@ void AddJacobian(Point *out,
Mul(&out->z, out->z, h);
// X3 = r²-J-2*V
- for (int i = 0; i < 8; i++) {
- z1z1[i] = v[i] << 1;
+ for (int k = 0; k < 8; k++) {
+ z1z1[k] = v[k] << 1;
}
Add(&z1z1, j, z1z1);
Reduce(&z1z1);
@@ -508,8 +523,8 @@ void AddJacobian(Point *out,
Reduce(&out->x);
// Y3 = r*(V-X3)-2*S1*J
- for (int i = 0; i < 8; i++) {
- s1[i] <<= 1;
+ for (int k = 0; k < 8; k++) {
+ s1[k] <<= 1;
}
Mul(&s1, s1, j);
Subtract(&z1z1, v, out->x);
@@ -676,7 +691,7 @@ bool Point::SetFromString(const base::StringPiece& in) {
}
std::string Point::ToString() const {
- FieldElement zinv, zinv_sq, x, y;
+ FieldElement zinv, zinv_sq, xx, yy;
// If this is the point at infinity we return a string of all zeros.
if (IsZero(this->z)) {
@@ -686,16 +701,16 @@ std::string Point::ToString() const {
Invert(&zinv, this->z);
Square(&zinv_sq, zinv);
- Mul(&x, this->x, zinv_sq);
+ Mul(&xx, x, zinv_sq);
Mul(&zinv_sq, zinv_sq, zinv);
- Mul(&y, this->y, zinv_sq);
+ Mul(&yy, y, zinv_sq);
- Contract(&x);
- Contract(&y);
+ Contract(&xx);
+ Contract(&yy);
uint32 outwords[14];
- Put224Bits(outwords, x);
- Put224Bits(outwords + 7, y);
+ Put224Bits(outwords, xx);
+ Put224Bits(outwords + 7, yy);
return std::string(reinterpret_cast<const char*>(outwords), sizeof(outwords));
}
diff --git a/chromium/crypto/p224_spake.cc b/chromium/crypto/p224_spake.cc
index 31109a43503..a6dec40568a 100644
--- a/chromium/crypto/p224_spake.cc
+++ b/chromium/crypto/p224_spake.cc
@@ -7,6 +7,8 @@
#include <crypto/p224_spake.h>
+#include <algorithm>
+
#include <base/logging.h>
#include <crypto/p224.h>
#include <crypto/random.h>
@@ -80,7 +82,7 @@ const crypto::p224::Point kM = {
33188520, 48266885, 177021753, 81038478},
{104523827, 245682244, 266509668, 236196369,
28372046, 145351378, 198520366, 113345994},
- {1, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0},
};
const crypto::p224::Point kN = {
@@ -88,7 +90,7 @@ const crypto::p224::Point kN = {
5034302, 185981975, 171998428, 11653062},
{197567436, 51226044, 60372156, 175772188,
42075930, 8083165, 160827401, 65097570},
- {1, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0},
};
} // anonymous namespace
@@ -105,14 +107,18 @@ P224EncryptedKeyExchange::P224EncryptedKeyExchange(
// x_ is a random scalar.
RandBytes(x_, sizeof(x_));
- // X = g**x_
- p224::Point X;
- p224::ScalarBaseMult(x_, &X);
-
// Calculate |password| hash to get SPAKE password value.
SHA256HashString(std::string(password.data(), password.length()),
pw_, sizeof(pw_));
+ Init();
+}
+
+void P224EncryptedKeyExchange::Init() {
+ // X = g**x_
+ p224::Point X;
+ p224::ScalarBaseMult(x_, &X);
+
// The client masks the Diffie-Hellman value, X, by adding M**pw and the
// server uses N**pw.
p224::Point MNpw;
@@ -125,7 +131,7 @@ P224EncryptedKeyExchange::P224EncryptedKeyExchange(
next_message_ = Xstar.ToString();
}
-const std::string& P224EncryptedKeyExchange::GetMessage() {
+const std::string& P224EncryptedKeyExchange::GetNextMessage() {
if (state_ == kStateInitial) {
state_ = kStateRecvDH;
return next_message_;
@@ -134,7 +140,7 @@ const std::string& P224EncryptedKeyExchange::GetMessage() {
return next_message_;
}
- LOG(FATAL) << "P224EncryptedKeyExchange::GetMessage called in"
+ LOG(FATAL) << "P224EncryptedKeyExchange::GetNextMessage called in"
" bad state " << state_;
next_message_ = "";
return next_message_;
@@ -240,9 +246,23 @@ const std::string& P224EncryptedKeyExchange::error() const {
return error_;
}
-const std::string& P224EncryptedKeyExchange::GetKey() {
+const std::string& P224EncryptedKeyExchange::GetKey() const {
DCHECK_EQ(state_, kStateDone);
+ return GetUnverifiedKey();
+}
+
+const std::string& P224EncryptedKeyExchange::GetUnverifiedKey() const {
+ // Key is already final when state is kStateSendHash. Subsequent states are
+ // used only for verification of the key. Some users may combine verification
+ // with sending verifiable data instead of |expected_authenticator_|.
+ DCHECK_GE(state_, kStateSendHash);
return key_;
}
+void P224EncryptedKeyExchange::SetXForTesting(const std::string& x) {
+ memset(&x_, 0, sizeof(x_));
+ memcpy(&x_, x.data(), std::min(x.size(), sizeof(x_)));
+ Init();
+}
+
} // namespace crypto
diff --git a/chromium/crypto/p224_spake.h b/chromium/crypto/p224_spake.h
index 6905ef2c220..556b15cd09f 100644
--- a/chromium/crypto/p224_spake.h
+++ b/chromium/crypto/p224_spake.h
@@ -5,6 +5,7 @@
#ifndef CRYPTO_P224_SPAKE_H_
#define CRYPTO_P224_SPAKE_H_
+#include <base/gtest_prod_util.h>
#include <base/strings/string_piece.h>
#include <crypto/p224.h>
#include <crypto/sha2.h>
@@ -14,7 +15,7 @@ namespace crypto {
// P224EncryptedKeyExchange implements SPAKE2, a variant of Encrypted
// Key Exchange. It allows two parties that have a secret common
// password to establish a common secure key by exchanging messages
-// over unsecure channel without disclosing the password.
+// over an insecure channel without disclosing the password.
//
// The password can be low entropy as authenticating with an attacker only
// gives the attacker a one-shot password oracle. No other information about
@@ -22,10 +23,10 @@ namespace crypto {
// permitted authentication attempts otherwise they get many one-shot oracles.)
//
// The protocol requires several RTTs (actually two, but you shouldn't assume
-// that.) To use the object, call GetMessage() and pass that message to the
+// that.) To use the object, call GetNextMessage() and pass that message to the
// peer. Get a message from the peer and feed it into ProcessMessage. Then
// examine the return value of ProcessMessage:
-// kResultPending: Another round is required. Call GetMessage and repeat.
+// kResultPending: Another round is required. Call GetNextMessage and repeat.
// kResultFailed: The authentication has failed. You can get a human readable
// error message by calling error().
// kResultSuccess: The authentication was successful.
@@ -54,12 +55,12 @@ class CRYPTO_EXPORT P224EncryptedKeyExchange {
P224EncryptedKeyExchange(PeerType peer_type,
const base::StringPiece& password);
- // GetMessage returns a byte string which must be passed to the other party
- // in the authentication.
- const std::string& GetMessage();
+ // GetNextMessage returns a byte string which must be passed to the other
+ // party in the authentication.
+ const std::string& GetNextMessage();
// ProcessMessage processes a message which must have been generated by a
- // call to GetMessage() by the other party.
+ // call to GetNextMessage() by the other party.
Result ProcessMessage(const base::StringPiece& message);
// In the event that ProcessMessage() returns kResultFailed, error will
@@ -68,7 +69,11 @@ class CRYPTO_EXPORT P224EncryptedKeyExchange {
// The key established as result of the key exchange. Must be called
// at then end after ProcessMessage() returns kResultSuccess.
- const std::string& GetKey();
+ const std::string& GetKey() const;
+
+ // The key established as result of the key exchange. Can be called after
+ // the first ProcessMessage()
+ const std::string& GetUnverifiedKey() const;
private:
// The authentication state machine is very simple and each party proceeds
@@ -81,9 +86,16 @@ class CRYPTO_EXPORT P224EncryptedKeyExchange {
kStateDone,
};
+ FRIEND_TEST_ALL_PREFIXES(MutualAuth, ExpectedValues);
+
+ void Init();
+
+ // Sets internal random scalar. Should be used by tests only.
+ void SetXForTesting(const std::string& x);
+
State state_;
const bool is_server_;
- // next_message_ contains a value for GetMessage() to return.
+ // next_message_ contains a value for GetNextMessage() to return.
std::string next_message_;
std::string error_;
@@ -100,7 +112,7 @@ class CRYPTO_EXPORT P224EncryptedKeyExchange {
// file).
uint8 x_[p224::kScalarBytes];
// pw_ is SHA256(P(password), P(session))[:28] where P() prepends a uint32,
- // big-endian length prefix (see paper refereneced in .cc file).
+ // big-endian length prefix (see paper referenced in .cc file).
uint8 pw_[p224::kScalarBytes];
// expected_authenticator_ is used to store the hash value expected from the
// other party.
diff --git a/chromium/crypto/p224_spake_unittest.cc b/chromium/crypto/p224_spake_unittest.cc
index 589cdbfcf0d..15b5be26841 100644
--- a/chromium/crypto/p224_spake_unittest.cc
+++ b/chromium/crypto/p224_spake_unittest.cc
@@ -2,45 +2,53 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "crypto/p224_spake.h"
+
#include <string>
-#include <crypto/p224_spake.h>
#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace crypto {
namespace {
+std::string HexEncodeString(const std::string& binary_data) {
+ return base::HexEncode(binary_data.c_str(), binary_data.size());
+}
+
bool RunExchange(P224EncryptedKeyExchange* client,
- P224EncryptedKeyExchange* server) {
+ P224EncryptedKeyExchange* server,
+ bool is_password_same) {
for (;;) {
std::string client_message, server_message;
- client_message = client->GetMessage();
- server_message = server->GetMessage();
+ client_message = client->GetNextMessage();
+ server_message = server->GetNextMessage();
P224EncryptedKeyExchange::Result client_result, server_result;
client_result = client->ProcessMessage(server_message);
server_result = server->ProcessMessage(client_message);
// Check that we never hit the case where only one succeeds.
- if ((client_result == P224EncryptedKeyExchange::kResultSuccess) ^
- (server_result == P224EncryptedKeyExchange::kResultSuccess)) {
- CHECK(false) << "Parties differ on whether authentication was successful";
- }
+ EXPECT_EQ(client_result == P224EncryptedKeyExchange::kResultSuccess,
+ server_result == P224EncryptedKeyExchange::kResultSuccess);
if (client_result == P224EncryptedKeyExchange::kResultFailed ||
server_result == P224EncryptedKeyExchange::kResultFailed) {
return false;
}
+ EXPECT_EQ(is_password_same,
+ client->GetUnverifiedKey() == server->GetUnverifiedKey());
+
if (client_result == P224EncryptedKeyExchange::kResultSuccess &&
server_result == P224EncryptedKeyExchange::kResultSuccess) {
return true;
}
- CHECK_EQ(P224EncryptedKeyExchange::kResultPending, client_result);
- CHECK_EQ(P224EncryptedKeyExchange::kResultPending, server_result);
+ EXPECT_EQ(P224EncryptedKeyExchange::kResultPending, client_result);
+ EXPECT_EQ(P224EncryptedKeyExchange::kResultPending, server_result);
}
}
@@ -54,7 +62,7 @@ TEST(MutualAuth, CorrectAuth) {
P224EncryptedKeyExchange server(
P224EncryptedKeyExchange::kPeerTypeServer, kPassword);
- EXPECT_TRUE(RunExchange(&client, &server));
+ EXPECT_TRUE(RunExchange(&client, &server, true));
EXPECT_EQ(client.GetKey(), server.GetKey());
}
@@ -66,7 +74,43 @@ TEST(MutualAuth, IncorrectPassword) {
P224EncryptedKeyExchange::kPeerTypeServer,
"wrongpassword");
- EXPECT_FALSE(RunExchange(&client, &server));
+ EXPECT_FALSE(RunExchange(&client, &server, false));
+}
+
+TEST(MutualAuth, ExpectedValues) {
+ P224EncryptedKeyExchange client(P224EncryptedKeyExchange::kPeerTypeClient,
+ kPassword);
+ client.SetXForTesting("Client x");
+ P224EncryptedKeyExchange server(P224EncryptedKeyExchange::kPeerTypeServer,
+ kPassword);
+ server.SetXForTesting("Server x");
+
+ std::string client_message = client.GetNextMessage();
+ EXPECT_EQ(
+ "3508EF7DECC8AB9F9C439FBB0154288BBECC0A82E8448F4CF29554EB"
+ "BE9D486686226255EAD1D077C635B1A41F46AC91D7F7F32CED9EC3E0",
+ HexEncodeString(client_message));
+
+ std::string server_message = server.GetNextMessage();
+ EXPECT_EQ(
+ "A3088C18B75D2C2B107105661AEC85424777475EB29F1DDFB8C14AFB"
+ "F1603D0DF38413A00F420ACF2059E7997C935F5A957A193D09A2B584",
+ HexEncodeString(server_message));
+
+ EXPECT_EQ(P224EncryptedKeyExchange::kResultPending,
+ client.ProcessMessage(server_message));
+ EXPECT_EQ(P224EncryptedKeyExchange::kResultPending,
+ server.ProcessMessage(client_message));
+
+ EXPECT_EQ(client.GetUnverifiedKey(), server.GetUnverifiedKey());
+ // Must stay the same. External implementations should be able to pair with.
+ EXPECT_EQ(
+ "CE7CCFC435CDA4F01EC8826788B1F8B82EF7D550A34696B371096E64"
+ "C487D4FE193F7D1A6FF6820BC7F807796BA3889E8F999BBDEFC32FFA",
+ HexEncodeString(server.GetUnverifiedKey()));
+
+ EXPECT_TRUE(RunExchange(&client, &server, true));
+ EXPECT_EQ(client.GetKey(), server.GetKey());
}
TEST(MutualAuth, Fuzz) {
@@ -85,8 +129,8 @@ TEST(MutualAuth, Fuzz) {
for (unsigned round = 0;; round++) {
std::string client_message, server_message;
- client_message = client.GetMessage();
- server_message = server.GetMessage();
+ client_message = client.GetNextMessage();
+ server_message = server.GetNextMessage();
if ((rand & 1) == round) {
const bool server_or_client = rand & 2;
diff --git a/chromium/crypto/rsa_private_key.h b/chromium/crypto/rsa_private_key.h
index 221e341a6fe..637be38836f 100644
--- a/chromium/crypto/rsa_private_key.h
+++ b/chromium/crypto/rsa_private_key.h
@@ -13,7 +13,7 @@
#include "base/basictypes.h"
#include "crypto/crypto_export.h"
-#if defined(USE_NSS)
+#if defined(USE_NSS_CERTS)
#include "base/gtest_prod_util.h"
#endif
@@ -180,48 +180,15 @@ class CRYPTO_EXPORT RSAPrivateKey {
static RSAPrivateKey* CreateFromPrivateKeyInfo(
const std::vector<uint8>& input);
-#if defined(USE_NSS)
- // Create a new random instance in |slot|. Can return NULL if initialization
- // fails. The created key is permanent and is not exportable in plaintext
- // form.
- static RSAPrivateKey* CreateSensitive(PK11SlotInfo* slot, uint16 num_bits);
-
- // Create a new instance in |slot| by importing an existing private key. The
- // format is an ASN.1-encoded PrivateKeyInfo block from PKCS #8. This can
- // return NULL if initialization fails.
- // The created key is permanent and is not exportable in plaintext form.
- static RSAPrivateKey* CreateSensitiveFromPrivateKeyInfo(
- PK11SlotInfo* slot,
- const std::vector<uint8>& input);
-
- // Create a new instance by referencing an existing private key
- // structure. Does not import the key.
- static RSAPrivateKey* CreateFromKey(SECKEYPrivateKey* key);
-
- // Import an existing public key, and then search for the private
- // half in the key database. The format of the public key blob is is
- // an X509 SubjectPublicKeyInfo block. This can return NULL if
- // initialization fails or the private key cannot be found. The
- // caller takes ownership of the returned object, but nothing new is
- // created in the key database.
- static RSAPrivateKey* FindFromPublicKeyInfo(
- const std::vector<uint8>& input);
-
- // Import an existing public key, and then search for the private
- // half in the slot specified by |slot|. The format of the public
- // key blob is is an X509 SubjectPublicKeyInfo block. This can return
- // NULL if initialization fails or the private key cannot be found.
- // The caller takes ownership of the returned object, but nothing new
- // is created in the slot.
- static RSAPrivateKey* FindFromPublicKeyInfoInSlot(
- const std::vector<uint8>& input,
- PK11SlotInfo* slot);
-#elif defined(USE_OPENSSL)
+#if defined(USE_OPENSSL)
// Create a new instance from an existing EVP_PKEY, taking a
// reference to it. |key| must be an RSA key. Returns NULL on
// failure.
static RSAPrivateKey* CreateFromKey(EVP_PKEY* key);
-
+#else
+ // Create a new instance by referencing an existing private key
+ // structure. Does not import the key.
+ static RSAPrivateKey* CreateFromKey(SECKEYPrivateKey* key);
#endif
#if defined(USE_OPENSSL)
@@ -241,43 +208,14 @@ class CRYPTO_EXPORT RSAPrivateKey {
bool ExportPublicKey(std::vector<uint8>* output) const;
private:
-#if defined(USE_NSS)
+#if defined(USE_NSS_CERTS)
FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FindFromPublicKey);
FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FailedFindFromPublicKey);
#endif
- // Constructor is private. Use one of the Create*() or Find*()
- // methods above instead.
+ // Constructor is private. Use one of the Create*() methods above instead.
RSAPrivateKey();
-#if !defined(USE_OPENSSL)
- // Shared helper for Create() and CreateSensitive().
- // TODO(cmasone): consider replacing |permanent| and |sensitive| with a
- // flags arg created by ORing together some enumerated values.
- // Note: |permanent| is only supported when USE_NSS is defined.
- static RSAPrivateKey* CreateWithParams(PK11SlotInfo* slot,
- uint16 num_bits,
- bool permanent,
- bool sensitive);
-
- // Shared helper for CreateFromPrivateKeyInfo() and
- // CreateSensitiveFromPrivateKeyInfo().
- // Note: |permanent| is only supported when USE_NSS is defined.
- static RSAPrivateKey* CreateFromPrivateKeyInfoWithParams(
- PK11SlotInfo* slot,
- const std::vector<uint8>& input,
- bool permanent,
- bool sensitive);
-#endif
-
-#if defined(USE_NSS)
- // Import an existing public key. The format of the public key blob
- // is an X509 SubjectPublicKeyInfo block. This can return NULL if
- // initialization fails. The caller takes ownership of the returned
- // object. Note that this method doesn't initialize the |key_| member.
- static RSAPrivateKey* InitPublicPart(const std::vector<uint8>& input);
-#endif
-
#if defined(USE_OPENSSL)
EVP_PKEY* key_;
#else
diff --git a/chromium/crypto/rsa_private_key_nss.cc b/chromium/crypto/rsa_private_key_nss.cc
index 078544de0c3..88e55fa5768 100644
--- a/chromium/crypto/rsa_private_key_nss.cc
+++ b/chromium/crypto/rsa_private_key_nss.cc
@@ -7,7 +7,6 @@
#include <cryptohi.h>
#include <keyhi.h>
#include <pk11pub.h>
-#include <secmod.h>
#include <list>
@@ -15,8 +14,8 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_util.h"
+#include "crypto/nss_key_util.h"
#include "crypto/nss_util.h"
-#include "crypto/nss_util_internal.h"
#include "crypto/scoped_nss_types.h"
// TODO(rafaelw): Consider using NSS's ASN.1 encoder.
@@ -38,37 +37,6 @@ static bool ReadAttribute(SECKEYPrivateKey* key,
return true;
}
-#if defined(USE_NSS)
-struct PublicKeyInfoDeleter {
- inline void operator()(CERTSubjectPublicKeyInfo* spki) {
- SECKEY_DestroySubjectPublicKeyInfo(spki);
- }
-};
-
-typedef scoped_ptr<CERTSubjectPublicKeyInfo, PublicKeyInfoDeleter>
- ScopedPublicKeyInfo;
-
-// The function decodes RSA public key from the |input|.
-crypto::ScopedSECKEYPublicKey GetRSAPublicKey(const std::vector<uint8>& input) {
- // First, decode and save the public key.
- SECItem key_der;
- key_der.type = siBuffer;
- key_der.data = const_cast<unsigned char*>(&input[0]);
- key_der.len = input.size();
-
- ScopedPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der));
- if (!spki)
- return crypto::ScopedSECKEYPublicKey();
-
- crypto::ScopedSECKEYPublicKey result(SECKEY_ExtractPublicKey(spki.get()));
-
- // Make sure the key is an RSA key.. If not, that's an error.
- if (!result || result->keyType != rsaKey)
- return crypto::ScopedSECKEYPublicKey();
- return result.Pass();
-}
-#endif // defined(USE_NSS)
-
} // namespace
namespace crypto {
@@ -85,10 +53,22 @@ RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) {
EnsureNSSInit();
ScopedPK11Slot slot(PK11_GetInternalSlot());
- return CreateWithParams(slot.get(),
- num_bits,
- false /* not permanent */,
- false /* not sensitive */);
+ if (!slot) {
+ NOTREACHED();
+ return nullptr;
+ }
+
+ ScopedSECKEYPublicKey public_key;
+ ScopedSECKEYPrivateKey private_key;
+ if (!GenerateRSAKeyPairNSS(slot.get(), num_bits, false /* not permanent */,
+ &public_key, &private_key)) {
+ return nullptr;
+ }
+
+ RSAPrivateKey* rsa_key = new RSAPrivateKey;
+ rsa_key->public_key_ = public_key.release();
+ rsa_key->key_ = private_key.release();
+ return rsa_key;
}
// static
@@ -97,31 +77,15 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
EnsureNSSInit();
ScopedPK11Slot slot(PK11_GetInternalSlot());
- return CreateFromPrivateKeyInfoWithParams(
- slot.get(),
- input,
- false /* not permanent */,
- false /* not sensitive */);
-}
-
-#if defined(USE_NSS)
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitive(PK11SlotInfo* slot,
- uint16 num_bits) {
- return CreateWithParams(slot,
- num_bits,
- true /* permanent */,
- true /* sensitive */);
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(
- PK11SlotInfo* slot,
- const std::vector<uint8>& input) {
- return CreateFromPrivateKeyInfoWithParams(slot,
- input,
- true /* permanent */,
- true /* sensitive */);
+ if (!slot) {
+ NOTREACHED();
+ return nullptr;
+ }
+ ScopedSECKEYPrivateKey key(ImportNSSKeyFromPrivateKeyInfo(
+ slot.get(), input, false /* not permanent */));
+ if (!key || SECKEY_GetPrivateKeyType(key.get()) != rsaKey)
+ return nullptr;
+ return RSAPrivateKey::CreateFromKey(key.get());
}
// static
@@ -140,63 +104,6 @@ RSAPrivateKey* RSAPrivateKey::CreateFromKey(SECKEYPrivateKey* key) {
return copy;
}
-// static
-RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo(
- const std::vector<uint8>& input) {
- scoped_ptr<RSAPrivateKey> result(InitPublicPart(input));
- if (!result)
- return NULL;
-
- ScopedSECItem ck_id(
- PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus)));
- if (!ck_id.get()) {
- NOTREACHED();
- return NULL;
- }
-
- // Search all slots in all modules for the key with the given ID.
- AutoSECMODListReadLock auto_lock;
- SECMODModuleList* head = SECMOD_GetDefaultModuleList();
- for (SECMODModuleList* item = head; item != NULL; item = item->next) {
- int slot_count = item->module->loaded ? item->module->slotCount : 0;
- for (int i = 0; i < slot_count; i++) {
- // Finally...Look for the key!
- result->key_ = PK11_FindKeyByKeyID(item->module->slots[i],
- ck_id.get(), NULL);
- if (result->key_)
- return result.release();
- }
- }
-
- // We didn't find the key.
- return NULL;
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfoInSlot(
- const std::vector<uint8>& input,
- PK11SlotInfo* slot) {
- if (!slot)
- return NULL;
-
- scoped_ptr<RSAPrivateKey> result(InitPublicPart(input));
- if (!result)
- return NULL;
-
- ScopedSECItem ck_id(
- PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus)));
- if (!ck_id.get()) {
- NOTREACHED();
- return NULL;
- }
-
- result->key_ = PK11_FindKeyByKeyID(slot, ck_id.get(), NULL);
- if (!result->key_)
- return NULL;
- return result.release();
-}
-#endif
-
RSAPrivateKey* RSAPrivateKey::Copy() const {
RSAPrivateKey* copy = new RSAPrivateKey();
copy->key_ = SECKEY_CopyPrivateKey(key_);
@@ -241,81 +148,4 @@ RSAPrivateKey::RSAPrivateKey() : key_(NULL), public_key_(NULL) {
EnsureNSSInit();
}
-// static
-RSAPrivateKey* RSAPrivateKey::CreateWithParams(PK11SlotInfo* slot,
- uint16 num_bits,
- bool permanent,
- bool sensitive) {
- if (!slot)
- return NULL;
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
-
- PK11RSAGenParams param;
- param.keySizeInBits = num_bits;
- param.pe = 65537L;
- result->key_ = PK11_GenerateKeyPair(slot,
- CKM_RSA_PKCS_KEY_PAIR_GEN,
- &param,
- &result->public_key_,
- permanent,
- sensitive,
- NULL);
- if (!result->key_)
- return NULL;
-
- return result.release();
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams(
- PK11SlotInfo* slot,
- const std::vector<uint8>& input,
- bool permanent,
- bool sensitive) {
- if (!slot)
- return NULL;
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
-
- SECItem der_private_key_info;
- der_private_key_info.data = const_cast<unsigned char*>(&input.front());
- der_private_key_info.len = input.size();
- // Allow the private key to be used for key unwrapping, data decryption,
- // and signature generation.
- const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT |
- KU_DIGITAL_SIGNATURE;
- SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
- slot, &der_private_key_info, NULL, NULL, permanent, sensitive,
- key_usage, &result->key_, NULL);
- if (rv != SECSuccess) {
- NOTREACHED();
- return NULL;
- }
-
- result->public_key_ = SECKEY_ConvertToPublicKey(result->key_);
- if (!result->public_key_) {
- NOTREACHED();
- return NULL;
- }
-
- return result.release();
-}
-
-#if defined(USE_NSS)
-// static
-RSAPrivateKey* RSAPrivateKey::InitPublicPart(const std::vector<uint8>& input) {
- EnsureNSSInit();
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey());
- result->public_key_ = GetRSAPublicKey(input).release();
- if (!result->public_key_) {
- NOTREACHED();
- return NULL;
- }
-
- return result.release();
-}
-#endif // defined(USE_NSS)
-
} // namespace crypto
diff --git a/chromium/crypto/rsa_private_key_nss_unittest.cc b/chromium/crypto/rsa_private_key_nss_unittest.cc
deleted file mode 100644
index b91b431c3ee..00000000000
--- a/chromium/crypto/rsa_private_key_nss_unittest.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "crypto/rsa_private_key.h"
-
-#include <keyhi.h>
-#include <pk11pub.h>
-
-#include "base/memory/scoped_ptr.h"
-#include "crypto/scoped_test_nss_db.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace crypto {
-
-class RSAPrivateKeyNSSTest : public testing::Test {
- public:
- RSAPrivateKeyNSSTest() {}
- virtual ~RSAPrivateKeyNSSTest() {}
-
- private:
- ScopedTestNSSDB test_nssdb_;
-
- DISALLOW_COPY_AND_ASSIGN(RSAPrivateKeyNSSTest);
-};
-
-TEST_F(RSAPrivateKeyNSSTest, FindFromPublicKey) {
- // Create a keypair, which will put the keys in the user's NSSDB.
- scoped_ptr<crypto::RSAPrivateKey> key_pair(RSAPrivateKey::Create(256));
-
- std::vector<uint8> public_key;
- ASSERT_TRUE(key_pair->ExportPublicKey(&public_key));
-
- scoped_ptr<crypto::RSAPrivateKey> key_pair_2(
- crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
-
- EXPECT_EQ(key_pair->key_->pkcs11ID, key_pair_2->key_->pkcs11ID);
-}
-
-TEST_F(RSAPrivateKeyNSSTest, FailedFindFromPublicKey) {
- // Create a keypair, which will put the keys in the user's NSSDB.
- scoped_ptr<crypto::RSAPrivateKey> key_pair(RSAPrivateKey::Create(256));
-
- std::vector<uint8> public_key;
- ASSERT_TRUE(key_pair->ExportPublicKey(&public_key));
-
- // Remove the keys from the DB, and make sure we can't find them again.
- if (key_pair->key_) {
- PK11_DestroyTokenObject(key_pair->key_->pkcs11Slot,
- key_pair->key_->pkcs11ID);
- }
- if (key_pair->public_key_) {
- PK11_DestroyTokenObject(key_pair->public_key_->pkcs11Slot,
- key_pair->public_key_->pkcs11ID);
- }
-
- EXPECT_EQ(NULL, crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
-}
-
-} // namespace crypto
diff --git a/chromium/crypto/rsa_private_key_openssl.cc b/chromium/crypto/rsa_private_key_openssl.cc
index 053c4a2f930..52a0a7a1815 100644
--- a/chromium/crypto/rsa_private_key_openssl.cc
+++ b/chromium/crypto/rsa_private_key_openssl.cc
@@ -19,10 +19,13 @@ namespace crypto {
namespace {
+using ScopedPKCS8_PRIV_KEY_INFO =
+ ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>;
+
// Function pointer definition, for injecting the required key export function
// into ExportKey, below. The supplied function should export EVP_PKEY into
// the supplied BIO, returning 1 on success or 0 on failure.
-typedef int (ExportFunction)(BIO*, EVP_PKEY*);
+using ExportFunction = int (*)(BIO*, EVP_PKEY*);
// Helper to export |key| into |output| via the specified ExportFunction.
bool ExportKey(EVP_PKEY* key,
@@ -76,23 +79,19 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
return NULL;
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- // BIO_new_mem_buf is not const aware, but it does not modify the buffer.
- char* data = reinterpret_cast<char*>(const_cast<uint8*>(&input[0]));
- ScopedBIO bio(BIO_new_mem_buf(data, input.size()));
- if (!bio.get())
- return NULL;
// Importing is a little more involved than exporting, as we must first
// PKCS#8 decode the input, and then import the EVP_PKEY from Private Key
// Info structure returned.
- ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>::Type p8inf(
- d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL));
- if (!p8inf.get())
+ const uint8_t* ptr = &input[0];
+ ScopedPKCS8_PRIV_KEY_INFO p8inf(
+ d2i_PKCS8_PRIV_KEY_INFO(nullptr, &ptr, input.size()));
+ if (!p8inf.get() || ptr != &input[0] + input.size())
return NULL;
scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
result->key_ = EVP_PKCS82PKEY(p8inf.get());
- if (!result->key_)
+ if (!result->key_ || EVP_PKEY_id(result->key_) != EVP_PKEY_RSA)
return NULL;
return result.release();
@@ -104,7 +103,7 @@ RSAPrivateKey* RSAPrivateKey::CreateFromKey(EVP_PKEY* key) {
if (EVP_PKEY_type(key->type) != EVP_PKEY_RSA)
return NULL;
RSAPrivateKey* copy = new RSAPrivateKey();
- copy->key_ = EVP_PKEY_dup(key);
+ copy->key_ = EVP_PKEY_up_ref(key);
return copy;
}
diff --git a/chromium/crypto/rsa_private_key_unittest.cc b/chromium/crypto/rsa_private_key_unittest.cc
index d53d50228d2..b231cac6cc3 100644
--- a/chromium/crypto/rsa_private_key_unittest.cc
+++ b/chromium/crypto/rsa_private_key_unittest.cc
@@ -150,6 +150,47 @@ TEST(RSAPrivateKeyUnitTest, CopyTest) {
ASSERT_EQ(input, privkey_copy);
}
+// Test that CreateFromPrivateKeyInfo fails if there is extra data after the RSA
+// key.
+TEST(RSAPrivateKeyUnitTest, ExtraData) {
+ std::vector<uint8> input(
+ kTestPrivateKeyInfo, kTestPrivateKeyInfo + sizeof(kTestPrivateKeyInfo));
+ input.push_back(0);
+
+ scoped_ptr<crypto::RSAPrivateKey> key(
+ crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(input));
+
+ // Import should fail.
+ EXPECT_FALSE(key);
+}
+
+TEST(RSAPrivateKeyUnitTest, NotRsaKey) {
+ // Defines a valid P-256 private key.
+ const uint8 kTestEcPrivateKeyInfo[] = {
+ 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86,
+ 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
+ 0x03, 0x01, 0x07, 0x04, 0x6D, 0x30, 0x6B, 0x02, 0x01, 0x01, 0x04, 0x20,
+ 0x1F, 0xE3, 0x39, 0x50, 0xC5, 0xF4, 0x61, 0x12, 0x4A, 0xE9, 0x92, 0xC2,
+ 0xBD, 0xFD, 0xF1, 0xC7, 0x3B, 0x16, 0x15, 0xF5, 0x71, 0xBD, 0x56, 0x7E,
+ 0x60, 0xD1, 0x9A, 0xA1, 0xF4, 0x8C, 0xDF, 0x42, 0xA1, 0x44, 0x03, 0x42,
+ 0x00, 0x04, 0x7C, 0x11, 0x0C, 0x66, 0xDC, 0xFD, 0xA8, 0x07, 0xF6, 0xE6,
+ 0x9E, 0x45, 0xDD, 0xB3, 0xC7, 0x4F, 0x69, 0xA1, 0x48, 0x4D, 0x20, 0x3E,
+ 0x8D, 0xC5, 0xAD, 0xA8, 0xE9, 0xA9, 0xDD, 0x7C, 0xB3, 0xC7, 0x0D, 0xF4,
+ 0x48, 0x98, 0x6E, 0x51, 0xBD, 0xE5, 0xD1, 0x57, 0x6F, 0x99, 0x90, 0x1F,
+ 0x9C, 0x2C, 0x6A, 0x80, 0x6A, 0x47, 0xFD, 0x90, 0x76, 0x43, 0xA7, 0x2B,
+ 0x83, 0x55, 0x97, 0xEF, 0xC8, 0xC6
+ };
+
+ std::vector<uint8> input(
+ kTestEcPrivateKeyInfo,
+ kTestEcPrivateKeyInfo + sizeof(kTestEcPrivateKeyInfo));
+
+ scoped_ptr<crypto::RSAPrivateKey> key(
+ crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(input));
+
+ // Import should fail as the given PKCS8 bytes were for an EC key not RSA key.
+ EXPECT_FALSE(key);
+}
// Verify that generated public keys look good. This test data was generated
// with the openssl command line tool.
@@ -404,9 +445,6 @@ TEST(RSAPrivateKeyUnitTest, ShortIntegers) {
input2.size()));
}
-// The following test can run if either USE_NSS or USE_OPENSSL is defined, but
-// not otherwise (since it uses crypto::RSAPrivateKey::CreateFromKey).
-#if defined(USE_NSS) || defined(USE_OPENSSL)
TEST(RSAPrivateKeyUnitTest, CreateFromKeyTest) {
scoped_ptr<crypto::RSAPrivateKey> key_pair(
crypto::RSAPrivateKey::Create(256));
@@ -428,5 +466,4 @@ TEST(RSAPrivateKeyUnitTest, CreateFromKeyTest) {
ASSERT_EQ(privkey, privkey_copy);
ASSERT_EQ(pubkey, pubkey_copy);
}
-#endif
diff --git a/chromium/crypto/scoped_openssl_types.h b/chromium/crypto/scoped_openssl_types.h
index cc056e49efe..73f763271bb 100644
--- a/chromium/crypto/scoped_openssl_types.h
+++ b/chromium/crypto/scoped_openssl_types.h
@@ -11,6 +11,7 @@
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
+#include <openssl/mem.h>
#include <openssl/rsa.h>
#include "base/memory/scoped_ptr.h"
@@ -22,15 +23,13 @@ namespace crypto {
// base::internal::RunnableAdapter<>, but that's far too heavy weight.
template <typename Type, void (*Destroyer)(Type*)>
struct OpenSSLDestroyer {
- typedef void AllowSelfReset;
+ using AllowSelfReset = void;
void operator()(Type* ptr) const { Destroyer(ptr); }
};
template <typename PointerType, void (*Destroyer)(PointerType*)>
-struct ScopedOpenSSL {
- typedef scoped_ptr<PointerType, OpenSSLDestroyer<PointerType, Destroyer> >
- Type;
-};
+using ScopedOpenSSL =
+ scoped_ptr<PointerType, OpenSSLDestroyer<PointerType, Destroyer>>;
struct OpenSSLFree {
void operator()(uint8_t* ptr) const { OPENSSL_free(ptr); }
@@ -40,19 +39,21 @@ struct OpenSSLFree {
// short-hand and prevalence. Note that OpenSSL types related to X.509 are
// intentionally not included, as crypto/ does not generally deal with
// certificates or PKI.
-typedef ScopedOpenSSL<BIGNUM, BN_free>::Type ScopedBIGNUM;
-typedef ScopedOpenSSL<EC_KEY, EC_KEY_free>::Type ScopedEC_KEY;
-typedef ScopedOpenSSL<BIO, BIO_free_all>::Type ScopedBIO;
-typedef ScopedOpenSSL<DSA, DSA_free>::Type ScopedDSA;
-typedef ScopedOpenSSL<ECDSA_SIG, ECDSA_SIG_free>::Type ScopedECDSA_SIG;
-typedef ScopedOpenSSL<EC_KEY, EC_KEY_free>::Type ScopedEC_KEY;
-typedef ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy>::Type ScopedEVP_MD_CTX;
-typedef ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free>::Type ScopedEVP_PKEY;
-typedef ScopedOpenSSL<EVP_PKEY_CTX, EVP_PKEY_CTX_free>::Type ScopedEVP_PKEY_CTX;
-typedef ScopedOpenSSL<RSA, RSA_free>::Type ScopedRSA;
+using ScopedBIGNUM = ScopedOpenSSL<BIGNUM, BN_free>;
+using ScopedEC_Key = ScopedOpenSSL<EC_KEY, EC_KEY_free>;
+using ScopedBIO = ScopedOpenSSL<BIO, BIO_free_all>;
+using ScopedDSA = ScopedOpenSSL<DSA, DSA_free>;
+using ScopedECDSA_SIG = ScopedOpenSSL<ECDSA_SIG, ECDSA_SIG_free>;
+using ScopedEC_GROUP = ScopedOpenSSL<EC_GROUP, EC_GROUP_free>;
+using ScopedEC_KEY = ScopedOpenSSL<EC_KEY, EC_KEY_free>;
+using ScopedEC_POINT = ScopedOpenSSL<EC_POINT, EC_POINT_free>;
+using ScopedEVP_MD_CTX = ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy>;
+using ScopedEVP_PKEY = ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free>;
+using ScopedEVP_PKEY_CTX = ScopedOpenSSL<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
+using ScopedRSA = ScopedOpenSSL<RSA, RSA_free>;
// The bytes must have been allocated with OPENSSL_malloc.
-typedef scoped_ptr<uint8_t, OpenSSLFree> ScopedOpenSSLBytes;
+using ScopedOpenSSLBytes = scoped_ptr<uint8_t, OpenSSLFree>;
} // namespace crypto
diff --git a/chromium/crypto/secure_hash_default.cc b/chromium/crypto/secure_hash_default.cc
index 1f5e59ba2ab..262beb7fd18 100644
--- a/chromium/crypto/secure_hash_default.cc
+++ b/chromium/crypto/secure_hash_default.cc
@@ -23,22 +23,20 @@ class SecureHashSHA256NSS : public SecureHash {
SHA256_Begin(&ctx_);
}
- virtual ~SecureHashSHA256NSS() {
- memset(&ctx_, 0, sizeof(ctx_));
- }
+ ~SecureHashSHA256NSS() override { memset(&ctx_, 0, sizeof(ctx_)); }
// SecureHash implementation:
- virtual void Update(const void* input, size_t len) override {
+ void Update(const void* input, size_t len) override {
SHA256_Update(&ctx_, static_cast<const unsigned char*>(input), len);
}
- virtual void Finish(void* output, size_t len) override {
+ void Finish(void* output, size_t len) override {
SHA256_End(&ctx_, static_cast<unsigned char*>(output), NULL,
static_cast<unsigned int>(len));
}
- virtual bool Serialize(Pickle* pickle) override;
- virtual bool Deserialize(PickleIterator* data_iterator) override;
+ bool Serialize(Pickle* pickle) override;
+ bool Deserialize(PickleIterator* data_iterator) override;
private:
SHA256Context ctx_;
diff --git a/chromium/crypto/secure_hash_openssl.cc b/chromium/crypto/secure_hash_openssl.cc
index 61946a8da81..ee1993c58e4 100644
--- a/chromium/crypto/secure_hash_openssl.cc
+++ b/chromium/crypto/secure_hash_openssl.cc
@@ -4,7 +4,7 @@
#include "crypto/secure_hash.h"
-#include <openssl/crypto.h>
+#include <openssl/mem.h>
#include <openssl/sha.h>
#include "base/basictypes.h"
@@ -26,22 +26,22 @@ class SecureHashSHA256OpenSSL : public SecureHash {
SHA256_Init(&ctx_);
}
- virtual ~SecureHashSHA256OpenSSL() {
+ ~SecureHashSHA256OpenSSL() override {
OPENSSL_cleanse(&ctx_, sizeof(ctx_));
}
- virtual void Update(const void* input, size_t len) override {
+ void Update(const void* input, size_t len) override {
SHA256_Update(&ctx_, static_cast<const unsigned char*>(input), len);
}
- virtual void Finish(void* output, size_t len) override {
+ void Finish(void* output, size_t len) override {
ScopedOpenSSLSafeSizeBuffer<SHA256_DIGEST_LENGTH> result(
static_cast<unsigned char*>(output), len);
SHA256_Final(result.safe_buffer(), &ctx_);
}
- virtual bool Serialize(Pickle* pickle) override;
- virtual bool Deserialize(PickleIterator* data_iterator) override;
+ bool Serialize(Pickle* pickle) override;
+ bool Deserialize(PickleIterator* data_iterator) override;
private:
SHA256_CTX ctx_;
diff --git a/chromium/crypto/signature_creator.h b/chromium/crypto/signature_creator.h
index 840d1ff0b80..ab9d2c1a21b 100644
--- a/chromium/crypto/signature_creator.h
+++ b/chromium/crypto/signature_creator.h
@@ -14,7 +14,7 @@
#if defined(USE_OPENSSL)
// Forward declaration for openssl/*.h
typedef struct env_md_ctx_st EVP_MD_CTX;
-#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
+#elif defined(USE_NSS_CERTS) || defined(OS_WIN) || defined(OS_MACOSX)
// Forward declaration.
struct SGNContextStr;
#endif
@@ -59,11 +59,9 @@ class CRYPTO_EXPORT SignatureCreator {
// Private constructor. Use the Create() method instead.
SignatureCreator();
- RSAPrivateKey* key_;
-
#if defined(USE_OPENSSL)
EVP_MD_CTX* sign_context_;
-#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
+#elif defined(USE_NSS_CERTS) || defined(OS_WIN) || defined(OS_MACOSX)
SGNContextStr* sign_context_;
#endif
diff --git a/chromium/crypto/signature_creator_nss.cc b/chromium/crypto/signature_creator_nss.cc
index 47728b07563..da03312881d 100644
--- a/chromium/crypto/signature_creator_nss.cc
+++ b/chromium/crypto/signature_creator_nss.cc
@@ -50,8 +50,6 @@ SignatureCreator::~SignatureCreator() {
SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key,
HashAlgorithm hash_alg) {
scoped_ptr<SignatureCreator> result(new SignatureCreator);
- result->key_ = key;
-
result->sign_context_ = SGN_NewContext(ToNSSSigOid(hash_alg), key->key());
if (!result->sign_context_) {
NOTREACHED();
@@ -113,9 +111,7 @@ bool SignatureCreator::Final(std::vector<uint8>* signature) {
return true;
}
-SignatureCreator::SignatureCreator()
- : key_(NULL),
- sign_context_(NULL) {
+SignatureCreator::SignatureCreator() : sign_context_(NULL) {
EnsureNSSInit();
}
diff --git a/chromium/crypto/signature_creator_openssl.cc b/chromium/crypto/signature_creator_openssl.cc
index 7a1349b5a5a..0d90d50044d 100644
--- a/chromium/crypto/signature_creator_openssl.cc
+++ b/chromium/crypto/signature_creator_openssl.cc
@@ -45,14 +45,15 @@ SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key,
HashAlgorithm hash_alg) {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
scoped_ptr<SignatureCreator> result(new SignatureCreator);
- result->key_ = key;
const EVP_MD* const digest = ToOpenSSLDigest(hash_alg);
DCHECK(digest);
if (!digest) {
return NULL;
}
- if (!EVP_SignInit_ex(result->sign_context_, digest, NULL))
+ if (!EVP_DigestSignInit(result->sign_context_, NULL, digest, NULL,
+ key->key())) {
return NULL;
+ }
return result.release();
}
@@ -87,17 +88,22 @@ SignatureCreator::~SignatureCreator() {
bool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- return EVP_SignUpdate(sign_context_, data_part, data_part_len) == 1;
+ return !!EVP_DigestSignUpdate(sign_context_, data_part, data_part_len);
}
bool SignatureCreator::Final(std::vector<uint8>* signature) {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- EVP_PKEY* key = key_->key();
- signature->resize(EVP_PKEY_size(key));
- unsigned int len = 0;
- int rv = EVP_SignFinal(sign_context_, vector_as_array(signature), &len, key);
- if (!rv) {
+ // Determine the maximum length of the signature.
+ size_t len = 0;
+ if (!EVP_DigestSignFinal(sign_context_, NULL, &len)) {
+ signature->clear();
+ return false;
+ }
+ signature->resize(len);
+
+ // Sign it.
+ if (!EVP_DigestSignFinal(sign_context_, vector_as_array(signature), &len)) {
signature->clear();
return false;
}
diff --git a/chromium/crypto/signature_verifier_openssl.cc b/chromium/crypto/signature_verifier_openssl.cc
index a855120ef83..a33d665ec13 100644
--- a/chromium/crypto/signature_verifier_openssl.cc
+++ b/chromium/crypto/signature_verifier_openssl.cc
@@ -50,7 +50,7 @@ bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm,
const uint8* public_key_info,
int public_key_info_len) {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- ScopedOpenSSL<X509_ALGOR, X509_ALGOR_free>::Type algorithm(
+ ScopedOpenSSL<X509_ALGOR, X509_ALGOR_free> algorithm(
d2i_X509_ALGOR(NULL, &signature_algorithm, signature_algorithm_len));
if (!algorithm.get())
return false;
@@ -122,8 +122,7 @@ bool SignatureVerifier::VerifyFinal() {
int rv = EVP_DigestVerifyFinal(verify_context_->ctx.get(),
vector_as_array(&signature_),
signature_.size());
- // rv is -1 if a DER-encoded ECDSA signature cannot be decoded correctly.
- DCHECK_GE(rv, -1);
+ DCHECK_EQ(static_cast<int>(!!rv), rv);
Reset();
return rv == 1;
}
@@ -141,19 +140,14 @@ bool SignatureVerifier::CommonInit(const EVP_MD* digest,
signature_.assign(signature, signature + signature_len);
- // BIO_new_mem_buf is not const aware, but it does not modify the buffer.
- char* data = reinterpret_cast<char*>(const_cast<uint8*>(public_key_info));
- ScopedBIO bio(BIO_new_mem_buf(data, public_key_info_len));
- if (!bio.get())
- return false;
-
- ScopedEVP_PKEY public_key(d2i_PUBKEY_bio(bio.get(), NULL));
- if (!public_key.get())
+ const uint8_t* ptr = public_key_info;
+ ScopedEVP_PKEY public_key(d2i_PUBKEY(nullptr, &ptr, public_key_info_len));
+ if (!public_key.get() || ptr != public_key_info + public_key_info_len)
return false;
verify_context_->ctx.reset(EVP_MD_CTX_create());
int rv = EVP_DigestVerifyInit(verify_context_->ctx.get(), pkey_ctx,
- digest, NULL, public_key.get());
+ digest, nullptr, public_key.get());
return rv == 1;
}
diff --git a/chromium/crypto/signature_verifier_unittest.cc b/chromium/crypto/signature_verifier_unittest.cc
index f6c42e0fdc7..a661ff7f8ab 100644
--- a/chromium/crypto/signature_verifier_unittest.cc
+++ b/chromium/crypto/signature_verifier_unittest.cc
@@ -258,6 +258,26 @@ TEST(SignatureVerifierTest, BasicTest) {
ok = verifier.VerifyFinal();
EXPECT_FALSE(ok);
}
+
+ // Test 5: import an invalid key.
+ uint8_t bad_public_key_info[sizeof(public_key_info)];
+ memcpy(bad_public_key_info, public_key_info, sizeof(public_key_info));
+ bad_public_key_info[0] += 1; // Corrupt part of the SPKI syntax.
+ ok = verifier.VerifyInit(signature_algorithm,
+ sizeof(signature_algorithm),
+ signature, sizeof(signature),
+ bad_public_key_info, sizeof(bad_public_key_info));
+ EXPECT_FALSE(ok);
+
+ // Test 6: import a key with extra data.
+ uint8_t long_public_key_info[sizeof(public_key_info) + 5];
+ memset(long_public_key_info, 0, sizeof(long_public_key_info));
+ memcpy(long_public_key_info, public_key_info, sizeof(public_key_info));
+ ok = verifier.VerifyInit(signature_algorithm,
+ sizeof(signature_algorithm),
+ signature, sizeof(signature),
+ long_public_key_info, sizeof(long_public_key_info));
+ EXPECT_FALSE(ok);
}
//////////////////////////////////////////////////////////////////////
@@ -980,6 +1000,23 @@ static bool DecodeTestInput(const char* in, std::vector<uint8>* out) {
return true;
}
+// PrependASN1Length prepends an ASN.1 serialized length to the beginning of
+// |out|.
+static void PrependASN1Length(std::vector<uint8>* out, size_t len) {
+ if (len < 128) {
+ out->insert(out->begin(), static_cast<uint8>(len));
+ } else if (len < 256) {
+ out->insert(out->begin(), static_cast<uint8>(len));
+ out->insert(out->begin(), 0x81);
+ } else if (len < 0x10000) {
+ out->insert(out->begin(), static_cast<uint8>(len));
+ out->insert(out->begin(), static_cast<uint8>(len >> 8));
+ out->insert(out->begin(), 0x82);
+ } else {
+ CHECK(false) << "ASN.1 length not handled: " << len;
+ }
+}
+
static bool EncodeRSAPublicKey(const std::vector<uint8>& modulus_n,
const std::vector<uint8>& public_exponent_e,
std::vector<uint8>* public_key_info) {
@@ -1007,37 +1044,28 @@ static bool EncodeRSAPublicKey(const std::vector<uint8>& modulus_n,
public_key_info->insert(public_key_info->begin(),
public_exponent_e.begin(),
public_exponent_e.end());
- uint8 exponent_size = base::checked_cast<uint8>(public_exponent_e.size());
- public_key_info->insert(public_key_info->begin(), exponent_size);
+ PrependASN1Length(public_key_info, public_exponent_e.size());
public_key_info->insert(public_key_info->begin(), kIntegerTag);
// Encode the modulus n as an INTEGER.
public_key_info->insert(public_key_info->begin(),
modulus_n.begin(), modulus_n.end());
- uint16 modulus_size = base::checked_cast<uint16>(modulus_n.size());
+ size_t modulus_size = modulus_n.size();
if (modulus_n[0] & 0x80) {
public_key_info->insert(public_key_info->begin(), 0x00);
modulus_size++;
}
- public_key_info->insert(public_key_info->begin(), modulus_size & 0xff);
- public_key_info->insert(public_key_info->begin(), (modulus_size >> 8) & 0xff);
- public_key_info->insert(public_key_info->begin(), 0x82);
+ PrependASN1Length(public_key_info, modulus_size);
public_key_info->insert(public_key_info->begin(), kIntegerTag);
// Encode the RSAPublicKey SEQUENCE.
- uint16 info_size = base::checked_cast<uint16>(public_key_info->size());
- public_key_info->insert(public_key_info->begin(), info_size & 0xff);
- public_key_info->insert(public_key_info->begin(), (info_size >> 8) & 0xff);
- public_key_info->insert(public_key_info->begin(), 0x82);
+ PrependASN1Length(public_key_info, public_key_info->size());
public_key_info->insert(public_key_info->begin(), kSequenceTag);
// Encode the BIT STRING.
// Number of unused bits.
public_key_info->insert(public_key_info->begin(), 0x00);
- info_size = base::checked_cast<uint16>(public_key_info->size());
- public_key_info->insert(public_key_info->begin(), info_size & 0xff);
- public_key_info->insert(public_key_info->begin(), (info_size >> 8) & 0xff);
- public_key_info->insert(public_key_info->begin(), 0x82);
+ PrependASN1Length(public_key_info, public_key_info->size());
public_key_info->insert(public_key_info->begin(), kBitStringTag);
// Encode the AlgorithmIdentifier.
@@ -1051,10 +1079,7 @@ static bool EncodeRSAPublicKey(const std::vector<uint8>& modulus_n,
algorithm, algorithm + sizeof(algorithm));
// Encode the outermost SEQUENCE.
- info_size = base::checked_cast<uint16>(public_key_info->size());
- public_key_info->insert(public_key_info->begin(), info_size & 0xff);
- public_key_info->insert(public_key_info->begin(), (info_size >> 8) & 0xff);
- public_key_info->insert(public_key_info->begin(), 0x82);
+ PrependASN1Length(public_key_info, public_key_info->size());
public_key_info->insert(public_key_info->begin(), kSequenceTag);
return true;
@@ -1062,6 +1087,7 @@ static bool EncodeRSAPublicKey(const std::vector<uint8>& modulus_n,
TEST(SignatureVerifierTest, VerifyRSAPSS) {
for (unsigned int i = 0; i < arraysize(pss_test); i++) {
+ SCOPED_TRACE(i);
std::vector<uint8> modulus_n;
std::vector<uint8> public_exponent_e;
ASSERT_TRUE(DecodeTestInput(pss_test[i].modulus_n, &modulus_n));
@@ -1072,6 +1098,7 @@ TEST(SignatureVerifierTest, VerifyRSAPSS) {
&public_key_info));
for (unsigned int j = 0; j < arraysize(pss_test[i].example); j++) {
+ SCOPED_TRACE(j);
std::vector<uint8> message;
std::vector<uint8> salt;
std::vector<uint8> signature;
diff --git a/chromium/crypto/symmetric_key.h b/chromium/crypto/symmetric_key.h
index ab105c1754c..996c5923b18 100644
--- a/chromium/crypto/symmetric_key.h
+++ b/chromium/crypto/symmetric_key.h
@@ -14,7 +14,7 @@
// See comments for crypto_nacl_win64 in crypto.gyp.
// Must test for NACL_WIN64 before OS_WIN since former is a subset of latter.
#include "crypto/scoped_capi_types.h"
-#elif defined(USE_NSS) || \
+#elif defined(USE_NSS_CERTS) || \
(!defined(USE_OPENSSL) && (defined(OS_WIN) || defined(OS_MACOSX)))
#include "crypto/scoped_nss_types.h"
#endif
@@ -61,7 +61,7 @@ class CRYPTO_EXPORT SymmetricKey {
HCRYPTKEY key() const { return key_.get(); }
#elif defined(USE_OPENSSL)
const std::string& key() { return key_; }
-#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
+#elif defined(USE_NSS_CERTS) || defined(OS_WIN) || defined(OS_MACOSX)
PK11SymKey* key() const { return key_.get(); }
#endif
@@ -88,7 +88,7 @@ class CRYPTO_EXPORT SymmetricKey {
#elif defined(USE_OPENSSL)
SymmetricKey() {}
std::string key_;
-#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
+#elif defined(USE_NSS_CERTS) || defined(OS_WIN) || defined(OS_MACOSX)
explicit SymmetricKey(PK11SymKey* key);
ScopedPK11SymKey key_;
#endif