summaryrefslogtreecommitdiff
path: root/chromium/crypto
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@theqtcompany.com>2014-12-05 15:04:29 +0100
committerAndras Becsi <andras.becsi@theqtcompany.com>2014-12-09 10:49:28 +0100
commitaf6588f8d723931a298c995fa97259bb7f7deb55 (patch)
tree060ca707847ba1735f01af2372e0d5e494dc0366 /chromium/crypto
parent2fff84d821cc7b1c785f6404e0f8091333283e74 (diff)
downloadqtwebengine-chromium-af6588f8d723931a298c995fa97259bb7f7deb55.tar.gz
BASELINE: Update chromium to 40.0.2214.28 and ninja to 1.5.3.
Change-Id: I759465284fd64d59ad120219cbe257f7402c4181 Reviewed-by: Andras Becsi <andras.becsi@theqtcompany.com>
Diffstat (limited to 'chromium/crypto')
-rw-r--r--chromium/crypto/BUILD.gn53
-rw-r--r--chromium/crypto/OWNERS1
-rw-r--r--chromium/crypto/PRESUBMIT.py2
-rw-r--r--chromium/crypto/capi_util.h2
-rw-r--r--chromium/crypto/crypto.gyp57
-rw-r--r--chromium/crypto/crypto.gypi1
-rw-r--r--chromium/crypto/crypto_nacl.gyp2
-rw-r--r--chromium/crypto/ec_private_key.h6
-rw-r--r--chromium/crypto/ec_private_key_nss.cc50
-rw-r--r--chromium/crypto/ec_private_key_openssl.cc100
-rw-r--r--chromium/crypto/ec_private_key_unittest.cc115
-rw-r--r--chromium/crypto/ec_signature_creator_impl.h4
-rw-r--r--chromium/crypto/ec_signature_creator_openssl.cc5
-rw-r--r--chromium/crypto/encryptor_openssl.cc5
-rw-r--r--chromium/crypto/encryptor_unittest.cc37
-rw-r--r--chromium/crypto/hkdf.cc14
-rw-r--r--chromium/crypto/hkdf.h19
-rw-r--r--chromium/crypto/hkdf_unittest.cc2
-rw-r--r--chromium/crypto/hmac_openssl.cc2
-rw-r--r--chromium/crypto/hmac_unittest.cc6
-rw-r--r--chromium/crypto/hmac_win.cc2
-rw-r--r--chromium/crypto/mock_apple_keychain.h23
-rw-r--r--chromium/crypto/nss_util.cc413
-rw-r--r--chromium/crypto/nss_util.h67
-rw-r--r--chromium/crypto/nss_util_internal.h59
-rw-r--r--chromium/crypto/nss_util_unittest.cc15
-rw-r--r--chromium/crypto/openssl_bio_string_unittest.cc17
-rw-r--r--chromium/crypto/openssl_util.cc13
-rw-r--r--chromium/crypto/openssl_util.h30
-rw-r--r--chromium/crypto/p224.cc4
-rw-r--r--chromium/crypto/p224_spake_unittest.cc2
-rw-r--r--chromium/crypto/rsa_private_key.h6
-rw-r--r--chromium/crypto/rsa_private_key_nss_unittest.cc29
-rw-r--r--chromium/crypto/rsa_private_key_openssl.cc27
-rw-r--r--chromium/crypto/rsa_private_key_unittest.cc343
-rw-r--r--chromium/crypto/scoped_capi_types.h2
-rw-r--r--chromium/crypto/scoped_nss_types.h8
-rw-r--r--chromium/crypto/scoped_openssl_types.h59
-rw-r--r--chromium/crypto/scoped_test_nss_chromeos_user.cc37
-rw-r--r--chromium/crypto/scoped_test_nss_chromeos_user.h43
-rw-r--r--chromium/crypto/scoped_test_nss_db.cc53
-rw-r--r--chromium/crypto/scoped_test_nss_db.h35
-rw-r--r--chromium/crypto/scoped_test_system_nss_key_slot.cc32
-rw-r--r--chromium/crypto/scoped_test_system_nss_key_slot.h43
-rw-r--r--chromium/crypto/secure_hash_default.cc8
-rw-r--r--chromium/crypto/secure_hash_openssl.cc8
-rw-r--r--chromium/crypto/secure_hash_unittest.cc2
-rw-r--r--chromium/crypto/signature_creator.h20
-rw-r--r--chromium/crypto/signature_creator_nss.cc33
-rw-r--r--chromium/crypto/signature_creator_openssl.cc45
-rw-r--r--chromium/crypto/signature_creator_unittest.cc49
-rw-r--r--chromium/crypto/signature_verifier.h3
-rw-r--r--chromium/crypto/signature_verifier_openssl.cc26
-rw-r--r--chromium/crypto/signature_verifier_unittest.cc32
-rw-r--r--chromium/crypto/symmetric_key.h14
-rw-r--r--chromium/crypto/symmetric_key_nss.cc23
-rw-r--r--chromium/crypto/symmetric_key_openssl.cc24
-rw-r--r--chromium/crypto/symmetric_key_unittest.cc4
-rw-r--r--chromium/crypto/wincrypt_shim.h25
59 files changed, 1397 insertions, 764 deletions
diff --git a/chromium/crypto/BUILD.gn b/chromium/crypto/BUILD.gn
index 307842084cb..d3d318de50f 100644
--- a/chromium/crypto/BUILD.gn
+++ b/chromium/crypto/BUILD.gn
@@ -49,6 +49,8 @@ component("crypto") {
"nss_util.cc",
"nss_util.h",
"nss_util_internal.h",
+ "openssl_bio_string.cc",
+ "openssl_bio_string.h",
"openssl_util.cc",
"openssl_util.h",
"p224.cc",
@@ -131,6 +133,7 @@ component("crypto") {
"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",
@@ -150,6 +153,8 @@ component("crypto") {
"ec_signature_creator_openssl.cc",
"encryptor_openssl.cc",
"hmac_openssl.cc",
+ "openssl_bio_string.cc",
+ "openssl_bio_string.h",
"openssl_util.cc",
"openssl_util.h",
"rsa_private_key_openssl.cc",
@@ -204,6 +209,7 @@ test("crypto_unittests") {
"hkdf_unittest.cc",
"hmac_unittest.cc",
"nss_util_unittest.cc",
+ "openssl_bio_string_unittest.cc",
"p224_unittest.cc",
"p224_spake_unittest.cc",
"random_unittest.cc",
@@ -224,11 +230,14 @@ test("crypto_unittests") {
if (use_openssl) {
sources -= [ "nss_util_unittest.cc" ]
+ } else {
+ sources -= [ "openssl_bio_string_unittest.cc" ]
}
deps = [
":crypto",
":platform",
+ ":test_support",
"//base",
"//base/test:run_all_unittests",
"//base/test:test_support",
@@ -237,12 +246,44 @@ 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_system_nss_key_slot.cc",
+ "scoped_test_system_nss_key_slot.h",
+ ]
+ deps = [
+ ":crypto",
+ ":platform",
+ "//base",
+ ]
+
+ if (!use_nss_certs) {
+ sources -= [
+ "scoped_test_nss_db.cc",
+ "scoped_test_nss_db.h",
+ ]
+ }
+
+ if (!is_chromeos) {
+ sources -= [
+ "scoped_test_nss_chromeos_user.cc",
+ "scoped_test_nss_chromeos_user.h",
+ "scoped_test_system_nss_key_slot.cc",
+ "scoped_test_system_nss_key_slot.h",
+ ]
+ }
+}
+
# 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/openssl" ]
+ deps = [ "//third_party/boringssl" ]
} else {
deps = [ "//net/third_party/nss/ssl:libssl" ]
if (is_linux) {
@@ -251,11 +292,11 @@ group("platform") {
#
# 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, direct_dependent_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.
- direct_dependent_configs = [
+ # 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",
]
diff --git a/chromium/crypto/OWNERS b/chromium/crypto/OWNERS
index 6f5cc98b802..bde32a088b4 100644
--- a/chromium/crypto/OWNERS
+++ b/chromium/crypto/OWNERS
@@ -1,4 +1,5 @@
agl@chromium.org
+davidben@chromium.org
rsleevi@chromium.org
rvargas@chromium.org
wtc@chromium.org
diff --git a/chromium/crypto/PRESUBMIT.py b/chromium/crypto/PRESUBMIT.py
index ce3988e50c6..a2a5af9ae7a 100644
--- a/chromium/crypto/PRESUBMIT.py
+++ b/chromium/crypto/PRESUBMIT.py
@@ -11,7 +11,7 @@ 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': {
+ 'tryserver.chromium.linux': {
'linux_redux': set(['defaulttests']),
}
}
diff --git a/chromium/crypto/capi_util.h b/chromium/crypto/capi_util.h
index 09a44e7634c..9d43293e231 100644
--- a/chromium/crypto/capi_util.h
+++ b/chromium/crypto/capi_util.h
@@ -6,9 +6,9 @@
#define CRYPTO_CAPI_UTIL_H_
#include <windows.h>
-#include <wincrypt.h>
#include "crypto/crypto_export.h"
+#include "crypto/wincrypt_shim.h"
namespace crypto {
diff --git a/chromium/crypto/crypto.gyp b/chromium/crypto/crypto.gyp
index 0c472ffc2eb..6d60f480fed 100644
--- a/chromium/crypto/crypto.gyp
+++ b/chromium/crypto/crypto.gyp
@@ -21,9 +21,6 @@
'defines': [
'CRYPTO_IMPLEMENTATION',
],
- 'msvs_disabled_warnings': [
- 4018,
- ],
'conditions': [
[ 'os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android"', {
'dependencies': [
@@ -95,12 +92,14 @@
],
}],
[ 'OS == "win"', {
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- 'msvs_disabled_warnings': [4267, ],
+ 'msvs_disabled_warnings': [
+ 4267, # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+ 4018,
+ ],
}],
[ 'use_openssl==1', {
'dependencies': [
- '../third_party/openssl/openssl.gyp:openssl',
+ '../third_party/boringssl/boringssl.gyp:boringssl',
],
# TODO(joth): Use a glob to match exclude patterns once the
# OpenSSL file set is complete.
@@ -111,6 +110,7 @@
'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',
@@ -174,6 +174,7 @@
],
'dependencies': [
'crypto',
+ 'crypto_test_support',
'../base/base.gyp:base',
'../base/base.gyp:run_all_unittests',
'../base/base.gyp:test_support_base',
@@ -209,7 +210,7 @@
}],
[ 'use_openssl==1', {
'dependencies': [
- '../third_party/openssl/openssl.gyp:openssl',
+ '../third_party/boringssl/boringssl.gyp:boringssl',
],
'sources!': [
'nss_util_unittest.cc',
@@ -254,5 +255,47 @@
},
],
}],
+ ['use_nss==1', {
+ 'targets': [
+ {
+ 'target_name': 'crypto_test_support',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ 'crypto',
+ ],
+ '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_system_nss_key_slot.cc',
+ 'scoped_test_system_nss_key_slot.h',
+ ],
+ 'conditions': [
+ ['use_nss==0', {
+ 'sources!': [
+ 'scoped_test_nss_db.cc',
+ 'scoped_test_nss_db.h',
+ ],
+ }],
+ [ 'chromeos==0', {
+ 'sources!': [
+ 'scoped_test_nss_chromeos_user.cc',
+ 'scoped_test_nss_chromeos_user.h',
+ 'scoped_test_system_nss_key_slot.cc',
+ 'scoped_test_system_nss_key_slot.h',
+ ],
+ }],
+ ],
+ }
+ ]}, { # use_nss==0
+ 'targets': [
+ {
+ 'target_name': 'crypto_test_support',
+ 'type': 'none',
+ 'sources': [],
+ }
+ ]}],
],
}
diff --git a/chromium/crypto/crypto.gypi b/chromium/crypto/crypto.gypi
index de65e198ebb..82b5da5dbc8 100644
--- a/chromium/crypto/crypto.gypi
+++ b/chromium/crypto/crypto.gypi
@@ -20,6 +20,7 @@
'third_party/nss/chromium-prtypes.h',
'third_party/nss/chromium-sha256.h',
'third_party/nss/sha512.cc',
+ 'wincrypt_shim.h',
],
},
'hmac_win64_related_sources': [ '<@(hmac_win64_related_sources)' ],
diff --git a/chromium/crypto/crypto_nacl.gyp b/chromium/crypto/crypto_nacl.gyp
index 6ec5e830ced..44516109196 100644
--- a/chromium/crypto/crypto_nacl.gyp
+++ b/chromium/crypto/crypto_nacl.gyp
@@ -22,7 +22,7 @@
'build_pnacl_newlib': 1,
},
'dependencies': [
- '../third_party/openssl/openssl_nacl.gyp:openssl_nacl',
+ '../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',
],
diff --git a/chromium/crypto/ec_private_key.h b/chromium/crypto/ec_private_key.h
index 28701635d50..9fd8ffdfb62 100644
--- a/chromium/crypto/ec_private_key.h
+++ b/chromium/crypto/ec_private_key.h
@@ -86,6 +86,9 @@ class CRYPTO_EXPORT ECPrivateKey {
bool sensitive,
SECKEYPrivateKey** key,
SECKEYPublicKey** public_key);
+
+ // Returns a copy of the object.
+ ECPrivateKey* Copy() const;
#endif
#if defined(USE_OPENSSL)
@@ -107,6 +110,9 @@ class CRYPTO_EXPORT ECPrivateKey {
// Exports the public key to an X.509 SubjectPublicKeyInfo block.
bool ExportPublicKey(std::vector<uint8>* output);
+ // Exports the public key as an EC point in the uncompressed point format.
+ bool ExportRawPublicKey(std::string* output);
+
// Exports private key data for testing. The format of data stored into output
// doesn't matter other than that it is consistent for the same key.
bool ExportValue(std::vector<uint8>* output);
diff --git a/chromium/crypto/ec_private_key_nss.cc b/chromium/crypto/ec_private_key_nss.cc
index 1d3bf889204..2daa0c0f4a3 100644
--- a/chromium/crypto/ec_private_key_nss.cc
+++ b/chromium/crypto/ec_private_key_nss.cc
@@ -159,6 +159,13 @@ bool ECPrivateKey::ImportFromEncryptedPrivateKeyInfo(
return false;
}
+ if (SECKEY_GetPublicKeyType(*public_key) != ecKey) {
+ DLOG(ERROR) << "The public key is not an EC key";
+ SECKEY_DestroyPublicKey(*public_key);
+ *public_key = NULL;
+ return false;
+ }
+
SECItem encoded_epki = {
siBuffer,
const_cast<unsigned char*>(encrypted_private_key_info),
@@ -208,6 +215,21 @@ bool ECPrivateKey::ImportFromEncryptedPrivateKeyInfo(
return true;
}
+ECPrivateKey* ECPrivateKey::Copy() const {
+ scoped_ptr<ECPrivateKey> copy(new ECPrivateKey);
+ if (key_) {
+ copy->key_ = SECKEY_CopyPrivateKey(key_);
+ if (!copy->key_)
+ return NULL;
+ }
+ if (public_key_) {
+ copy->public_key_ = SECKEY_CopyPublicKey(public_key_);
+ if (!copy->public_key_)
+ return NULL;
+ }
+ return copy.release();
+}
+
bool ECPrivateKey::ExportEncryptedPrivateKey(
const std::string& password,
int iterations,
@@ -223,12 +245,12 @@ bool ECPrivateKey::ExportEncryptedPrivateKey(
};
SECKEYEncryptedPrivateKeyInfo* encrypted = PK11_ExportEncryptedPrivKeyInfo(
- NULL, // Slot, optional.
+ NULL, // Slot, optional.
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC,
&password_item,
key_,
iterations,
- NULL); // wincx.
+ NULL); // wincx.
if (!encrypted) {
DLOG(ERROR) << "PK11_ExportEncryptedPrivKeyInfo: " << PORT_GetError();
@@ -264,6 +286,23 @@ bool ECPrivateKey::ExportPublicKey(std::vector<uint8>* output) {
return true;
}
+bool ECPrivateKey::ExportRawPublicKey(std::string* output) {
+ // public_key_->u.ec.publicValue is an ANSI X9.62 public key which, for
+ // a P-256 key, is 0x04 (meaning uncompressed) followed by the x and y field
+ // elements as 32-byte, big-endian numbers.
+ static const unsigned int kExpectedKeyLength = 65;
+
+ CHECK_EQ(ecKey, SECKEY_GetPublicKeyType(public_key_));
+ const unsigned char* const data = public_key_->u.ec.publicValue.data;
+ const unsigned int len = public_key_->u.ec.publicValue.len;
+ if (len != kExpectedKeyLength || data[0] != 0x04)
+ return false;
+
+ output->assign(reinterpret_cast<const char*>(data + 1),
+ kExpectedKeyLength - 1);
+ return true;
+}
+
bool ECPrivateKey::ExportValue(std::vector<uint8>* output) {
return ReadAttribute(key_, CKA_VALUE, output);
}
@@ -301,7 +340,7 @@ ECPrivateKey* ECPrivateKey::CreateWithParams(PK11SlotInfo* slot,
};
ec_parameters.data[0] = SEC_ASN1_OBJECT_ID;
- ec_parameters.data[1] = oid_data->oid.len;
+ 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,
@@ -315,6 +354,7 @@ ECPrivateKey* ECPrivateKey::CreateWithParams(PK11SlotInfo* slot,
DLOG(ERROR) << "PK11_GenerateKeyPair: " << PORT_GetError();
return NULL;
}
+ CHECK_EQ(ecKey, SECKEY_GetPublicKeyType(result->public_key_));
return result.release();
}
@@ -354,8 +394,10 @@ ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfoWithParams(
SECKEY_DestroySubjectPublicKeyInfo(decoded_spki);
- if (success)
+ if (success) {
+ CHECK_EQ(ecKey, SECKEY_GetPublicKeyType(result->public_key_));
return result.release();
+ }
return NULL;
}
diff --git a/chromium/crypto/ec_private_key_openssl.cc b/chromium/crypto/ec_private_key_openssl.cc
index 8504ab50c35..2d44759d8b0 100644
--- a/chromium/crypto/ec_private_key_openssl.cc
+++ b/chromium/crypto/ec_private_key_openssl.cc
@@ -12,6 +12,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "crypto/openssl_util.h"
+#include "crypto/scoped_openssl_types.h"
namespace crypto {
@@ -24,6 +25,10 @@ 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;
+
// Helper to export |key| into |output| via the specified ExportBioFunction.
bool ExportKeyWithBio(const void* key,
ExportBioFunction export_fn,
@@ -31,7 +36,7 @@ bool ExportKeyWithBio(const void* key,
if (!key)
return false;
- ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new(BIO_s_mem()));
+ ScopedBIO bio(BIO_new(BIO_s_mem()));
if (!bio.get())
return false;
@@ -87,8 +92,7 @@ bool ECPrivateKey::IsSupported() { return true; }
ECPrivateKey* ECPrivateKey::Create() {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- ScopedOpenSSL<EC_KEY, EC_KEY_free> ec_key(
- EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+ ScopedEC_KEY ec_key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
if (!ec_key.get() || !EC_KEY_generate_key(ec_key.get()))
return NULL;
@@ -97,6 +101,7 @@ ECPrivateKey* ECPrivateKey::Create() {
if (!result->key_ || !EVP_PKEY_set1_EC_KEY(result->key_, ec_key.get()))
return NULL;
+ CHECK_EQ(EVP_PKEY_EC, EVP_PKEY_type(result->key_->type));
return result.release();
}
@@ -112,38 +117,37 @@ ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
return NULL;
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- // Write the encrypted private key into a memory BIO.
- char* private_key_data = reinterpret_cast<char*>(
- const_cast<uint8*>(&encrypted_private_key_info[0]));
- int private_key_data_len =
- static_cast<int>(encrypted_private_key_info.size());
- ScopedOpenSSL<BIO, BIO_free_all> bio(
- BIO_new_mem_buf(private_key_data, private_key_data_len));
- if (!bio.get())
- return NULL;
- // Convert it, then decrypt it into a PKCS#8 object.
- ScopedOpenSSL<X509_SIG, X509_SIG_free> p8_encrypted(
- d2i_PKCS8_bio(bio.get(), NULL));
- if (!p8_encrypted.get())
+ const uint8_t* data = &encrypted_private_key_info[0];
+ const uint8_t* ptr = data;
+ ScopedX509_SIG p8_encrypted(
+ d2i_X509_SIG(NULL, &ptr, encrypted_private_key_info.size()));
+ if (!p8_encrypted || ptr != data + encrypted_private_key_info.size())
return NULL;
- ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> p8_decrypted(
- PKCS8_decrypt(p8_encrypted.get(),
- password.c_str(),
- static_cast<int>(password.size())));
- if (!p8_decrypted.get() && password.empty()) {
- // Hack for reading keys generated by ec_private_key_nss. Passing NULL
- // causes OpenSSL to use an empty password instead of "\0\0".
- p8_decrypted.reset(PKCS8_decrypt(p8_encrypted.get(), NULL, 0));
+ ScopedPKCS8_PRIV_KEY_INFO p8_decrypted;
+ if (password.empty()) {
+ // Hack for reading keys generated by an older version of the OpenSSL
+ // code. OpenSSL used to use "\0\0" rather than the empty string because it
+ // would treat the password as an ASCII string to be converted to UCS-2
+ // while NSS used a byte string.
+ p8_decrypted.reset(PKCS8_decrypt_pbe(
+ p8_encrypted.get(), reinterpret_cast<const uint8_t*>("\0\0"), 2));
+ }
+ if (!p8_decrypted) {
+ p8_decrypted.reset(PKCS8_decrypt_pbe(
+ p8_encrypted.get(),
+ reinterpret_cast<const uint8_t*>(password.data()),
+ password.size()));
}
- if (!p8_decrypted.get())
+
+ if (!p8_decrypted)
return NULL;
// Create a new EVP_PKEY for it.
scoped_ptr<ECPrivateKey> result(new ECPrivateKey);
result->key_ = EVP_PKCS82PKEY(p8_decrypted.get());
- if (!result->key_)
+ if (!result->key_ || EVP_PKEY_type(result->key_->type) != EVP_PKEY_EC)
return NULL;
return result.release();
@@ -155,8 +159,7 @@ bool ECPrivateKey::ExportEncryptedPrivateKey(
std::vector<uint8>* output) {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
// Convert into a PKCS#8 object.
- ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> pkcs8(
- EVP_PKEY2PKCS8(key_));
+ ScopedPKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(key_));
if (!pkcs8.get())
return false;
@@ -164,15 +167,14 @@ bool ECPrivateKey::ExportEncryptedPrivateKey(
// NOTE: NSS uses SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
// so use NID_pbe_WithSHA1And3_Key_TripleDES_CBC which should be the OpenSSL
// equivalent.
- ScopedOpenSSL<X509_SIG, X509_SIG_free> encrypted(
- PKCS8_encrypt(NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
- NULL,
- password.c_str(),
- static_cast<int>(password.size()),
- NULL,
- 0,
- iterations,
- pkcs8.get()));
+ ScopedX509_SIG encrypted(PKCS8_encrypt_pbe(
+ NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
+ reinterpret_cast<const uint8_t*>(password.data()),
+ password.size(),
+ NULL,
+ 0,
+ iterations,
+ pkcs8.get()));
if (!encrypted.get())
return false;
@@ -188,9 +190,29 @@ bool ECPrivateKey::ExportPublicKey(std::vector<uint8>* output) {
key_, reinterpret_cast<ExportBioFunction>(i2d_PUBKEY_bio), output);
}
+bool ECPrivateKey::ExportRawPublicKey(std::string* output) {
+ // i2d_PublicKey will produce an ANSI X9.62 public key which, for a P-256
+ // key, is 0x04 (meaning uncompressed) followed by the x and y field
+ // elements as 32-byte, big-endian numbers.
+ static const int kExpectedKeyLength = 65;
+
+ int len = i2d_PublicKey(key_, NULL);
+ if (len != kExpectedKeyLength)
+ return false;
+
+ uint8 buf[kExpectedKeyLength];
+ uint8* derp = buf;
+ len = i2d_PublicKey(key_, &derp);
+ if (len != kExpectedKeyLength)
+ return false;
+
+ output->assign(reinterpret_cast<char*>(buf + 1), kExpectedKeyLength - 1);
+ return true;
+}
+
bool ECPrivateKey::ExportValue(std::vector<uint8>* output) {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- ScopedOpenSSL<EC_KEY, EC_KEY_free> ec_key(EVP_PKEY_get1_EC_KEY(key_));
+ ScopedEC_KEY ec_key(EVP_PKEY_get1_EC_KEY(key_));
return ExportKey(ec_key.get(),
reinterpret_cast<ExportDataFunction>(i2d_ECPrivateKey),
output);
@@ -198,7 +220,7 @@ bool ECPrivateKey::ExportValue(std::vector<uint8>* output) {
bool ECPrivateKey::ExportECParams(std::vector<uint8>* output) {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- ScopedOpenSSL<EC_KEY, EC_KEY_free> ec_key(EVP_PKEY_get1_EC_KEY(key_));
+ ScopedEC_KEY ec_key(EVP_PKEY_get1_EC_KEY(key_));
return ExportKey(ec_key.get(),
reinterpret_cast<ExportDataFunction>(i2d_ECParameters),
output);
diff --git a/chromium/crypto/ec_private_key_unittest.cc b/chromium/crypto/ec_private_key_unittest.cc
index 8f653f15e58..6993a20b08f 100644
--- a/chromium/crypto/ec_private_key_unittest.cc
+++ b/chromium/crypto/ec_private_key_unittest.cc
@@ -6,6 +6,7 @@
#include <vector>
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -16,10 +17,8 @@ TEST(ECPrivateKeyUnitTest, InitRandomTest) {
const std::string password1;
const std::string password2 = "test";
- scoped_ptr<crypto::ECPrivateKey> keypair1(
- crypto::ECPrivateKey::Create());
- scoped_ptr<crypto::ECPrivateKey> keypair2(
- crypto::ECPrivateKey::Create());
+ scoped_ptr<crypto::ECPrivateKey> keypair1(crypto::ECPrivateKey::Create());
+ scoped_ptr<crypto::ECPrivateKey> keypair2(crypto::ECPrivateKey::Create());
ASSERT_TRUE(keypair1.get());
ASSERT_TRUE(keypair2.get());
@@ -36,12 +35,14 @@ TEST(ECPrivateKeyUnitTest, InitRandomTest) {
std::vector<uint8> privkey2;
std::vector<uint8> pubkey1;
std::vector<uint8> pubkey2;
- ASSERT_TRUE(keypair1->ExportEncryptedPrivateKey(
- password1, 1, &privkey1));
- ASSERT_TRUE(keypair2->ExportEncryptedPrivateKey(
- password2, 1, &privkey2));
+ std::string raw_pubkey1;
+ std::string raw_pubkey2;
+ ASSERT_TRUE(keypair1->ExportEncryptedPrivateKey(password1, 1, &privkey1));
+ ASSERT_TRUE(keypair2->ExportEncryptedPrivateKey(password2, 1, &privkey2));
EXPECT_TRUE(keypair1->ExportPublicKey(&pubkey1));
EXPECT_TRUE(keypair2->ExportPublicKey(&pubkey2));
+ EXPECT_TRUE(keypair1->ExportRawPublicKey(&raw_pubkey1));
+ EXPECT_TRUE(keypair2->ExportRawPublicKey(&raw_pubkey2));
scoped_ptr<crypto::ECPrivateKey> keypair3(
crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
@@ -68,13 +69,52 @@ TEST(ECPrivateKeyUnitTest, InitRandomTest) {
std::vector<uint8> pubkey3;
std::vector<uint8> pubkey4;
+ std::string raw_pubkey3;
+ std::string raw_pubkey4;
EXPECT_TRUE(keypair3->ExportPublicKey(&pubkey3));
EXPECT_TRUE(keypair4->ExportPublicKey(&pubkey4));
+ EXPECT_TRUE(keypair3->ExportRawPublicKey(&raw_pubkey3));
+ EXPECT_TRUE(keypair4->ExportRawPublicKey(&raw_pubkey4));
EXPECT_EQ(pubkey1, pubkey3);
EXPECT_EQ(pubkey2, pubkey4);
+ EXPECT_EQ(raw_pubkey1, raw_pubkey3);
+ 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());
+ ASSERT_TRUE(keypair1.get());
+ ASSERT_TRUE(keypair2.get());
+
+ std::vector<uint8> key1value;
+ std::vector<uint8> key2value;
+ EXPECT_TRUE(keypair1->ExportValue(&key1value));
+ EXPECT_TRUE(keypair2->ExportValue(&key2value));
+ EXPECT_EQ(key1value, key2value);
+
+ std::vector<uint8> key1params;
+ std::vector<uint8> key2params;
+ EXPECT_TRUE(keypair1->ExportECParams(&key1params));
+ EXPECT_TRUE(keypair2->ExportECParams(&key2params));
+ EXPECT_EQ(key1params, key2params);
+
+ std::vector<uint8> pubkey1;
+ std::vector<uint8> pubkey2;
+ EXPECT_TRUE(keypair1->ExportPublicKey(&pubkey1));
+ EXPECT_TRUE(keypair2->ExportPublicKey(&pubkey2));
+ EXPECT_EQ(pubkey1, pubkey2);
+
+ std::string raw_pubkey1;
+ std::string raw_pubkey2;
+ EXPECT_TRUE(keypair1->ExportRawPublicKey(&raw_pubkey1));
+ EXPECT_TRUE(keypair2->ExportRawPublicKey(&raw_pubkey2));
+ EXPECT_EQ(raw_pubkey1, raw_pubkey2);
+}
+#endif // !defined(USE_OPENSSL)
+
TEST(ECPrivateKeyUnitTest, BadPasswordTest) {
const std::string password1;
const std::string password2 = "test";
@@ -113,7 +153,6 @@ TEST(ECPrivateKeyUnitTest, LoadNSSKeyTest) {
0x58, 0x82, 0x14, 0xfb, 0x47, 0x85, 0x3c, 0xc3, 0xdf, 0xdd, 0xcc, 0x79,
0x9f, 0x41, 0x83, 0x72, 0xf2, 0x0a, 0xe9, 0xe1, 0x2c, 0x12, 0xb0, 0xb0,
0x0a, 0xb2, 0x1d, 0xca, 0x15, 0xb2, 0xca};
- unsigned int nss_key_len = 187;
static const unsigned char nss_pub_key[] = {
0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
@@ -123,22 +162,62 @@ TEST(ECPrivateKeyUnitTest, LoadNSSKeyTest) {
0xd7, 0x5c, 0x5d, 0xc5, 0x53, 0x6e, 0xe5, 0xa9, 0x33, 0xd5, 0xcc, 0xab,
0x53, 0x78, 0xdd, 0xd6, 0x12, 0x3a, 0x5e, 0xeb, 0xbf, 0xdf, 0x16, 0xd3,
0x2c, 0x3b, 0xe8, 0xdb, 0x19, 0xfc, 0x5e};
- unsigned int nss_pub_key_len = 91;
scoped_ptr<crypto::ECPrivateKey> keypair_nss(
crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
"",
- std::vector<uint8>(nss_key, nss_key + nss_key_len),
- std::vector<uint8>(nss_pub_key, nss_pub_key + nss_pub_key_len)));
+ std::vector<uint8>(nss_key, nss_key + arraysize(nss_key)),
+ std::vector<uint8>(nss_pub_key,
+ nss_pub_key + arraysize(nss_pub_key))));
EXPECT_TRUE(keypair_nss.get());
}
-// The plan is to migrate to OpenSSL everywhere, so making NSS implementation be
-// able to load the OpenSSL generated keys isn't that important.
-#if defined(USE_OPENSSL)
+// Although the plan is to transition from OpenSSL to NSS, ensure NSS can import
+// OpenSSL's format so that it is possible to rollback.
TEST(ECPrivateKeyUnitTest, LoadOpenSSLKeyTest) {
static const unsigned char openssl_key[] = {
+ 0x30, 0x81, 0xb0, 0x30, 0x1b, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0d, 0x04, 0x08, 0xb2, 0xfe, 0x68,
+ 0xc2, 0xea, 0x0f, 0x10, 0x9c, 0x02, 0x01, 0x01, 0x04, 0x81, 0x90, 0xe2,
+ 0xf6, 0x1c, 0xca, 0xad, 0x64, 0x30, 0xbf, 0x88, 0x04, 0x35, 0xe5, 0x0f,
+ 0x11, 0x49, 0x06, 0x01, 0x14, 0x33, 0x80, 0xa2, 0x78, 0x44, 0x5b, 0xaa,
+ 0x0d, 0xd7, 0x00, 0x36, 0x9d, 0x91, 0x97, 0x37, 0x20, 0x7b, 0x27, 0xc1,
+ 0xa0, 0xa2, 0x73, 0x06, 0x15, 0xdf, 0xc8, 0x13, 0x9b, 0xc9, 0x8c, 0x9c,
+ 0xce, 0x00, 0xd0, 0xc8, 0x42, 0xc1, 0xda, 0x2b, 0x07, 0x2b, 0x12, 0xa3,
+ 0xce, 0x10, 0x39, 0x7a, 0xf1, 0x55, 0x69, 0x8d, 0xa5, 0xc4, 0x2a, 0x00,
+ 0x0d, 0x94, 0xc6, 0xde, 0x6a, 0x3d, 0xb7, 0xe5, 0x6d, 0x59, 0x3e, 0x09,
+ 0xb5, 0xe3, 0x3e, 0xfc, 0x50, 0x56, 0xe9, 0x50, 0x42, 0x7c, 0xe7, 0xf0,
+ 0x19, 0xbd, 0x31, 0xa7, 0x85, 0x47, 0xb3, 0xe9, 0xb3, 0x50, 0x3c, 0xc9,
+ 0x32, 0x37, 0x1a, 0x93, 0x78, 0x48, 0x78, 0x82, 0xde, 0xad, 0x5c, 0xf2,
+ 0xcf, 0xf2, 0xbb, 0x2c, 0x44, 0x05, 0x7f, 0x4a, 0xf9, 0xb1, 0x2b, 0xdd,
+ 0x49, 0xf6, 0x7e, 0xd0, 0x42, 0xaa, 0x14, 0x3c, 0x24, 0x77, 0xb4};
+ static const unsigned char openssl_pub_key[] = {
+ 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
+ 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
+ 0x42, 0x00, 0x04, 0xb9, 0xda, 0x0d, 0x71, 0x60, 0xb3, 0x63, 0x28, 0x22,
+ 0x67, 0xe7, 0xe0, 0xa3, 0xf8, 0x00, 0x8e, 0x4c, 0x89, 0xed, 0x31, 0x34,
+ 0xf6, 0xdb, 0xc4, 0xfe, 0x0b, 0x5d, 0xe1, 0x11, 0x39, 0x49, 0xa6, 0x50,
+ 0xa8, 0xe3, 0x4a, 0xc0, 0x40, 0x88, 0xb8, 0x38, 0x3f, 0x56, 0xfb, 0x33,
+ 0x8d, 0xd4, 0x64, 0x91, 0xd6, 0x15, 0x77, 0x42, 0x27, 0xc5, 0xaa, 0x44,
+ 0xff, 0xab, 0x4d, 0xb5, 0x7e, 0x25, 0x3d};
+
+ scoped_ptr<crypto::ECPrivateKey> keypair_openssl(
+ crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
+ "",
+ std::vector<uint8>(openssl_key, openssl_key + arraysize(openssl_key)),
+ std::vector<uint8>(openssl_pub_key,
+ openssl_pub_key + arraysize(openssl_pub_key))));
+
+ EXPECT_TRUE(keypair_openssl.get());
+}
+
+// The Android code writes out Channel IDs differently from the NSS
+// implementation; the empty password is converted to "\0\0". The OpenSSL port
+// should support either.
+#if defined(USE_OPENSSL)
+TEST(ECPrivateKeyUnitTest, LoadOldOpenSSLKeyTest) {
+ static const unsigned char openssl_key[] = {
0x30, 0x82, 0x01, 0xa1, 0x30, 0x1b, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0d, 0x04, 0x08, 0x86, 0xaa,
0xd7, 0xdf, 0x3b, 0x91, 0x97, 0x60, 0x02, 0x01, 0x01, 0x04, 0x82, 0x01,
@@ -175,7 +254,6 @@ TEST(ECPrivateKeyUnitTest, LoadOpenSSLKeyTest) {
0xc2, 0xc1, 0x55, 0x22, 0x42, 0x2f, 0x13, 0x7d, 0x93, 0x27, 0xc8, 0x11,
0x35, 0xc5, 0xe3, 0xc5, 0xaa, 0x15, 0x3c, 0xac, 0x30, 0xbc, 0x45, 0x16,
0xed};
- unsigned int openssl_key_len = 421;
static const unsigned char openssl_pub_key[] = {
0x30, 0x82, 0x01, 0x4b, 0x30, 0x82, 0x01, 0x03, 0x06, 0x07, 0x2a, 0x86,
0x48, 0xce, 0x3d, 0x02, 0x01, 0x30, 0x81, 0xf7, 0x02, 0x01, 0x01, 0x30,
@@ -205,14 +283,13 @@ TEST(ECPrivateKeyUnitTest, LoadOpenSSLKeyTest) {
0x88, 0x38, 0xc0, 0xdb, 0xba, 0xf6, 0x99, 0xd8, 0xa5, 0x3b, 0x83, 0xe9,
0xe3, 0xd5, 0x61, 0x99, 0x73, 0x42, 0xc6, 0x6c, 0xe8, 0x0a, 0x95, 0x40,
0x41, 0x3b, 0x0d, 0x10, 0xa7, 0x4a, 0x93, 0xdb, 0x5a, 0xe7, 0xec};
- unsigned int openssl_pub_key_len = 335;
scoped_ptr<crypto::ECPrivateKey> keypair_openssl(
crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
"",
- std::vector<uint8>(openssl_key, openssl_key + openssl_key_len),
+ std::vector<uint8>(openssl_key, openssl_key + arraysize(openssl_key)),
std::vector<uint8>(openssl_pub_key,
- openssl_pub_key + openssl_pub_key_len)));
+ openssl_pub_key + arraysize(openssl_pub_key))));
EXPECT_TRUE(keypair_openssl.get());
}
diff --git a/chromium/crypto/ec_signature_creator_impl.h b/chromium/crypto/ec_signature_creator_impl.h
index 8ef67cd7f3d..f2ef9d65795 100644
--- a/chromium/crypto/ec_signature_creator_impl.h
+++ b/chromium/crypto/ec_signature_creator_impl.h
@@ -17,10 +17,10 @@ class ECSignatureCreatorImpl : public ECSignatureCreator {
virtual bool Sign(const uint8* data,
int data_len,
- std::vector<uint8>* signature) OVERRIDE;
+ std::vector<uint8>* signature) override;
virtual bool DecodeSignature(const std::vector<uint8>& der_sig,
- std::vector<uint8>* out_raw_sig) OVERRIDE;
+ 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 7f0a873f993..91e8a6a8d33 100644
--- a/chromium/crypto/ec_signature_creator_openssl.cc
+++ b/chromium/crypto/ec_signature_creator_openssl.cc
@@ -13,6 +13,7 @@
#include "base/logging.h"
#include "crypto/ec_private_key.h"
#include "crypto/openssl_util.h"
+#include "crypto/scoped_openssl_types.h"
namespace crypto {
@@ -27,7 +28,7 @@ bool ECSignatureCreatorImpl::Sign(const uint8* data,
int data_len,
std::vector<uint8>* signature) {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy> ctx(EVP_MD_CTX_create());
+ ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create());
size_t sig_len = 0;
if (!ctx.get() ||
!EVP_DigestSignInit(ctx.get(), NULL, EVP_sha256(), NULL, key_->key()) ||
@@ -52,7 +53,7 @@ bool ECSignatureCreatorImpl::DecodeSignature(const std::vector<uint8>& der_sig,
OpenSSLErrStackTracer err_tracer(FROM_HERE);
// Create ECDSA_SIG object from DER-encoded data.
const unsigned char* der_data = &der_sig.front();
- ScopedOpenSSL<ECDSA_SIG, ECDSA_SIG_free> ecdsa_sig(
+ ScopedECDSA_SIG ecdsa_sig(
d2i_ECDSA_SIG(NULL, &der_data, static_cast<long>(der_sig.size())));
if (!ecdsa_sig.get())
return false;
diff --git a/chromium/crypto/encryptor_openssl.cc b/chromium/crypto/encryptor_openssl.cc
index 0bf96b79df2..0504adbcb9f 100644
--- a/chromium/crypto/encryptor_openssl.cc
+++ b/chromium/crypto/encryptor_openssl.cc
@@ -19,7 +19,6 @@ namespace {
const EVP_CIPHER* GetCipherForKey(SymmetricKey* key) {
switch (key->key().length()) {
case 16: return EVP_aes_128_cbc();
- case 24: return EVP_aes_192_cbc();
case 32: return EVP_aes_256_cbc();
default: return NULL;
}
@@ -100,8 +99,8 @@ bool Encryptor::Crypt(bool do_encrypt,
DCHECK(cipher); // Already handled in Init();
const std::string& key = key_->key();
- DCHECK_EQ(EVP_CIPHER_iv_length(cipher), static_cast<int>(iv_.length()));
- DCHECK_EQ(EVP_CIPHER_key_length(cipher), static_cast<int>(key.length()));
+ DCHECK_EQ(EVP_CIPHER_iv_length(cipher), iv_.length());
+ DCHECK_EQ(EVP_CIPHER_key_length(cipher), key.length());
ScopedCipherCTX ctx;
if (!EVP_CipherInit_ex(ctx.get(), cipher, NULL,
diff --git a/chromium/crypto/encryptor_unittest.cc b/chromium/crypto/encryptor_unittest.cc
index 2a21a8e13db..1a99783679f 100644
--- a/chromium/crypto/encryptor_unittest.cc
+++ b/chromium/crypto/encryptor_unittest.cc
@@ -456,48 +456,21 @@ TEST(EncryptorTest, EncryptAES128CBCRegression) {
EXPECT_EQ(plaintext, decrypted);
}
-// Expected output derived from the NSS implementation.
-TEST(EncryptorTest, EncryptAES192CBCRegression) {
- std::string key = "192bitsIsTwentyFourByte!";
- std::string iv = "Sweet Sixteen IV";
- std::string plaintext = "Small text";
- std::string expected_ciphertext_hex = "78DE5D7C2714FC5C61346C5416F6C89A";
-
- scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
- crypto::SymmetricKey::AES, key));
- ASSERT_TRUE(sym_key.get());
-
- crypto::Encryptor encryptor;
- // The IV must be exactly as long a the cipher block size.
- EXPECT_EQ(16U, iv.size());
- EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
-
- std::string ciphertext;
- EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
- EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
- ciphertext.size()));
-
- std::string decrypted;
- EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
- EXPECT_EQ(plaintext, decrypted);
-}
-
-// Not all platforms allow import/generation of symmetric keys with an
-// unsupported size.
-#if !defined(USE_NSS) && !defined(OS_WIN) && !defined(OS_MACOSX)
+// Symmetric keys with an unsupported size should be rejected. Whether they are
+// rejected by SymmetricKey::Import or Encryptor::Init depends on the platform.
TEST(EncryptorTest, UnsupportedKeySize) {
std::string key = "7 = bad";
std::string iv = "Sweet Sixteen IV";
scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
crypto::SymmetricKey::AES, key));
- ASSERT_TRUE(sym_key.get());
+ if (!sym_key.get())
+ return;
crypto::Encryptor encryptor;
- // The IV must be exactly as long a the cipher block size.
+ // The IV must be exactly as long as the cipher block size.
EXPECT_EQ(16U, iv.size());
EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
}
-#endif // unsupported platforms.
TEST(EncryptorTest, UnsupportedIV) {
std::string key = "128=SixteenBytes";
diff --git a/chromium/crypto/hkdf.cc b/chromium/crypto/hkdf.cc
index 1cd8468977e..82aae24679e 100644
--- a/chromium/crypto/hkdf.cc
+++ b/chromium/crypto/hkdf.cc
@@ -5,6 +5,7 @@
#include "crypto/hkdf.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "crypto/hmac.h"
namespace crypto {
@@ -15,7 +16,8 @@ HKDF::HKDF(const base::StringPiece& secret,
const base::StringPiece& salt,
const base::StringPiece& info,
size_t key_bytes_to_generate,
- size_t iv_bytes_to_generate) {
+ size_t iv_bytes_to_generate,
+ size_t subkey_secret_bytes_to_generate) {
// https://tools.ietf.org/html/rfc5869#section-2.2
base::StringPiece actual_salt = salt;
char zeros[kSHA256HashLength];
@@ -40,8 +42,9 @@ HKDF::HKDF(const base::StringPiece& secret,
// https://tools.ietf.org/html/rfc5869#section-2.3
// Perform the Expand phase to turn the pseudorandom key
// and info into the output keying material.
- const size_t material_length =
- 2*key_bytes_to_generate + 2*iv_bytes_to_generate;
+ const size_t material_length = 2 * key_bytes_to_generate +
+ 2 * iv_bytes_to_generate +
+ subkey_secret_bytes_to_generate;
const size_t n = (material_length + kSHA256HashLength-1) /
kSHA256HashLength;
DCHECK_LT(n, 256u);
@@ -90,6 +93,11 @@ HKDF::HKDF(const base::StringPiece& secret,
j += iv_bytes_to_generate;
server_write_iv_ = base::StringPiece(reinterpret_cast<char*>(&output_[j]),
iv_bytes_to_generate);
+ j += iv_bytes_to_generate;
+ }
+ if (subkey_secret_bytes_to_generate) {
+ subkey_secret_ = base::StringPiece(reinterpret_cast<char*>(&output_[j]),
+ subkey_secret_bytes_to_generate);
}
}
diff --git a/chromium/crypto/hkdf.h b/chromium/crypto/hkdf.h
index 1d7a87673a1..e91bccf5b4f 100644
--- a/chromium/crypto/hkdf.h
+++ b/chromium/crypto/hkdf.h
@@ -8,9 +8,7 @@
#include <vector>
#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
-#include "build/build_config.h"
#include "crypto/crypto_export.h"
namespace crypto {
@@ -20,7 +18,7 @@ namespace crypto {
// See https://tools.ietf.org/html/rfc5869 for details.
class CRYPTO_EXPORT HKDF {
public:
- // |secret|: The input shared secret (or, from RFC 5869, the IKM).
+ // |secret|: the input shared secret (or, from RFC 5869, the IKM).
// |salt|: an (optional) public salt / non-secret random value. While
// optional, callers are strongly recommended to provide a salt. There is no
// added security value in making this larger than the SHA-256 block size of
@@ -28,13 +26,18 @@ class CRYPTO_EXPORT HKDF {
// |info|: an (optional) label to distinguish different uses of HKDF. It is
// optional context and application specific information (can be a zero-length
// string).
- // |key_bytes_to_generate|: the number of bytes of key material to generate.
- // |iv_bytes_to_generate|: the number of bytes of IV to generate.
+ // |key_bytes_to_generate|: the number of bytes of key material to generate
+ // for both client and server.
+ // |iv_bytes_to_generate|: the number of bytes of IV to generate for both
+ // client and server.
+ // |subkey_secret_bytes_to_generate|: the number of bytes of subkey secret to
+ // generate, shared between client and server.
HKDF(const base::StringPiece& secret,
const base::StringPiece& salt,
const base::StringPiece& info,
size_t key_bytes_to_generate,
- size_t iv_bytes_to_generate);
+ size_t iv_bytes_to_generate,
+ size_t subkey_secret_bytes_to_generate);
~HKDF();
base::StringPiece client_write_key() const {
@@ -49,6 +52,9 @@ class CRYPTO_EXPORT HKDF {
base::StringPiece server_write_iv() const {
return server_write_iv_;
}
+ base::StringPiece subkey_secret() const {
+ return subkey_secret_;
+ }
private:
std::vector<uint8> output_;
@@ -57,6 +63,7 @@ class CRYPTO_EXPORT HKDF {
base::StringPiece server_write_key_;
base::StringPiece client_write_iv_;
base::StringPiece server_write_iv_;
+ base::StringPiece subkey_secret_;
};
} // namespace crypto
diff --git a/chromium/crypto/hkdf_unittest.cc b/chromium/crypto/hkdf_unittest.cc
index dc369d1b94f..bcb19c5c10d 100644
--- a/chromium/crypto/hkdf_unittest.cc
+++ b/chromium/crypto/hkdf_unittest.cc
@@ -82,7 +82,7 @@ TEST(HKDFTest, HKDF) {
// We set the key_length to the length of the expected output and then take
// the result from the first key, which is the client write key.
- HKDF hkdf(key, salt, info, expected.size(), 0);
+ HKDF hkdf(key, salt, info, expected.size(), 0, 0);
ASSERT_EQ(expected.size(), hkdf.client_write_key().size());
EXPECT_EQ(0, memcmp(expected.data(), hkdf.client_write_key().data(),
diff --git a/chromium/crypto/hmac_openssl.cc b/chromium/crypto/hmac_openssl.cc
index 46bfbaefbef..92eea19d780 100644
--- a/chromium/crypto/hmac_openssl.cc
+++ b/chromium/crypto/hmac_openssl.cc
@@ -54,7 +54,7 @@ bool HMAC::Sign(const base::StringPiece& data,
DCHECK(!plat_->key.empty()); // Init must be called before Sign.
ScopedOpenSSLSafeSizeBuffer<EVP_MAX_MD_SIZE> result(digest, digest_length);
- return ::HMAC(hash_alg_ == SHA1 ? EVP_sha1() : EVP_sha256(),
+ return !!::HMAC(hash_alg_ == SHA1 ? EVP_sha1() : EVP_sha256(),
&plat_->key[0], plat_->key.size(),
reinterpret_cast<const unsigned char*>(data.data()),
data.size(),
diff --git a/chromium/crypto/hmac_unittest.cc b/chromium/crypto/hmac_unittest.cc
index 174c32382fa..91eccd68e23 100644
--- a/chromium/crypto/hmac_unittest.cc
+++ b/chromium/crypto/hmac_unittest.cc
@@ -142,7 +142,7 @@ TEST(HMACTest, RFC2202TestCases) {
"\xBB\xFF\x1A\x91" }
};
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ for (size_t i = 0; i < arraysize(cases); ++i) {
crypto::HMAC hmac(crypto::HMAC::SHA1);
ASSERT_TRUE(hmac.Init(reinterpret_cast<const unsigned char*>(cases[i].key),
cases[i].key_len));
@@ -239,7 +239,7 @@ TEST(HMACTest, HMACObjectReuse) {
ASSERT_TRUE(
hmac.Init(reinterpret_cast<const unsigned char*>(kSimpleKey),
kSimpleKeyLength));
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSimpleHmacCases); ++i) {
+ for (size_t i = 0; i < arraysize(kSimpleHmacCases); ++i) {
std::string data_string(kSimpleHmacCases[i].data,
kSimpleHmacCases[i].data_len);
unsigned char digest[kSHA1DigestSize];
@@ -254,7 +254,7 @@ TEST(HMACTest, Verify) {
hmac.Init(reinterpret_cast<const unsigned char*>(kSimpleKey),
kSimpleKeyLength));
const char empty_digest[kSHA1DigestSize] = { 0 };
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSimpleHmacCases); ++i) {
+ for (size_t i = 0; i < arraysize(kSimpleHmacCases); ++i) {
// Expected results
EXPECT_TRUE(hmac.Verify(
base::StringPiece(kSimpleHmacCases[i].data,
diff --git a/chromium/crypto/hmac_win.cc b/chromium/crypto/hmac_win.cc
index ba7d8275035..99b3a60d57e 100644
--- a/chromium/crypto/hmac_win.cc
+++ b/chromium/crypto/hmac_win.cc
@@ -5,7 +5,6 @@
#include "crypto/hmac.h"
#include <windows.h>
-#include <wincrypt.h>
#include <algorithm>
#include <vector>
@@ -14,6 +13,7 @@
#include "crypto/scoped_capi_types.h"
#include "crypto/third_party/nss/chromium-blapi.h"
#include "crypto/third_party/nss/chromium-sha256.h"
+#include "crypto/wincrypt_shim.h"
namespace crypto {
diff --git a/chromium/crypto/mock_apple_keychain.h b/chromium/crypto/mock_apple_keychain.h
index efbb438aa6a..d9573162ee6 100644
--- a/chromium/crypto/mock_apple_keychain.h
+++ b/chromium/crypto/mock_apple_keychain.h
@@ -40,9 +40,9 @@ class CRYPTO_EXPORT MockAppleKeychain : public AppleKeychain {
const char* accountName,
UInt32* passwordLength,
void** passwordData,
- SecKeychainItemRef* itemRef) const OVERRIDE;
+ SecKeychainItemRef* itemRef) const override;
virtual OSStatus ItemFreeContent(SecKeychainAttributeList* attrList,
- void* data) const OVERRIDE;
+ void* data) const override;
virtual OSStatus AddGenericPassword(
SecKeychainRef keychain,
UInt32 serviceNameLength,
@@ -51,7 +51,7 @@ class CRYPTO_EXPORT MockAppleKeychain : public AppleKeychain {
const char* accountName,
UInt32 passwordLength,
const void* passwordData,
- SecKeychainItemRef* itemRef) const OVERRIDE;
+ SecKeychainItemRef* itemRef) const override;
#if !defined(OS_IOS)
virtual OSStatus ItemCopyAttributesAndData(
@@ -60,23 +60,23 @@ class CRYPTO_EXPORT MockAppleKeychain : public AppleKeychain {
SecItemClass* itemClass,
SecKeychainAttributeList** attrList,
UInt32* length,
- void** outData) const OVERRIDE;
+ 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;
+ const void* data) const override;
virtual OSStatus ItemFreeAttributesAndData(SecKeychainAttributeList* attrList,
- void* data) const OVERRIDE;
- virtual OSStatus ItemDelete(SecKeychainItemRef itemRef) const OVERRIDE;
+ void* data) const override;
+ virtual OSStatus ItemDelete(SecKeychainItemRef itemRef) const override;
virtual OSStatus SearchCreateFromAttributes(
CFTypeRef keychainOrArray,
SecItemClass itemClass,
const SecKeychainAttributeList* attrList,
- SecKeychainSearchRef* searchRef) const OVERRIDE;
+ SecKeychainSearchRef* searchRef) const override;
virtual OSStatus SearchCopyNext(SecKeychainSearchRef searchRef,
- SecKeychainItemRef* itemRef) const OVERRIDE;
+ SecKeychainItemRef* itemRef) const override;
// Pass "some.domain.com" as the serverName to get errSecDuplicateItem.
virtual OSStatus AddInternetPassword(
SecKeychainRef keychain,
@@ -91,8 +91,8 @@ class CRYPTO_EXPORT MockAppleKeychain : public AppleKeychain {
SecAuthenticationType authenticationType,
UInt32 passwordLength,
const void* passwordData,
- SecKeychainItemRef* itemRef) const OVERRIDE;
- virtual void Free(CFTypeRef ref) const OVERRIDE;
+ SecKeychainItemRef* itemRef) const override;
+ virtual 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.
@@ -140,7 +140,6 @@ class CRYPTO_EXPORT MockAppleKeychain : public AppleKeychain {
int password_data_count() const { return password_data_count_; }
private:
-
// Type used for the keys in the std::map(s) and MockAppleKeychain items.
typedef uintptr_t MockKeychainItemType;
diff --git a/chromium/crypto/nss_util.cc b/chromium/crypto/nss_util.cc
index 5958ad972da..8f9865a3c6c 100644
--- a/chromium/crypto/nss_util.cc
+++ b/chromium/crypto/nss_util.cc
@@ -27,8 +27,8 @@
#include "base/debug/alias.h"
#include "base/debug/stack_trace.h"
#include "base/environment.h"
-#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
@@ -57,7 +57,7 @@ namespace crypto {
namespace {
#if defined(OS_CHROMEOS)
-const char kNSSDatabaseName[] = "Real NSS database";
+const char kUserNSSDatabaseName[] = "UserNSSDB";
// Constants for loading the Chrome OS TPM-backed PKCS #11 library.
const char kChapsModuleName[] = "Chaps";
@@ -81,6 +81,7 @@ std::string GetNSSErrorMessage() {
}
#if defined(USE_NSS)
+#if !defined(OS_CHROMEOS)
base::FilePath GetDefaultConfigDirectory() {
base::FilePath dir;
PathService::Get(base::DIR_HOME, &dir);
@@ -96,6 +97,7 @@ base::FilePath GetDefaultConfigDirectory() {
DVLOG(2) << "DefaultConfigDirectory: " << dir.value();
return dir;
}
+#endif // !defined(IS_CHROMEOS)
// On non-Chrome OS platforms, return the default config directory. On Chrome OS
// test images, return a read-only directory with fake root CA certs (which are
@@ -196,12 +198,6 @@ class NSPRInitSingleton {
base::LazyInstance<NSPRInitSingleton>::Leaky
g_nspr_singleton = LAZY_INSTANCE_INITIALIZER;
-// This is a LazyInstance so that it will be deleted automatically when the
-// unittest exits. NSSInitSingleton is a LeakySingleton, so it would not be
-// deleted if it were a regular member.
-base::LazyInstance<base::ScopedTempDir> g_test_nss_db_dir =
- LAZY_INSTANCE_INITIALIZER;
-
// Force a crash with error info on NSS_NoDB_Init failure.
void CrashOnNSSInitFailure() {
int nss_error = PR_GetError();
@@ -216,11 +212,11 @@ void CrashOnNSSInitFailure() {
#if defined(OS_CHROMEOS)
class ChromeOSUserData {
public:
- ChromeOSUserData(ScopedPK11Slot public_slot, bool is_primary_user)
+ explicit ChromeOSUserData(ScopedPK11Slot public_slot)
: public_slot_(public_slot.Pass()),
- is_primary_user_(is_primary_user) {}
+ private_slot_initialization_started_(false) {}
~ChromeOSUserData() {
- if (public_slot_ && !is_primary_user_) {
+ if (public_slot_) {
SECStatus status = SECMOD_CloseUserDB(public_slot_.get());
if (status != SECSuccess)
PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError();
@@ -254,10 +250,19 @@ class ChromeOSUserData {
}
}
+ bool private_slot_initialization_started() const {
+ return private_slot_initialization_started_;
+ }
+
+ void set_private_slot_initialization_started() {
+ private_slot_initialization_started_ = true;
+ }
+
private:
ScopedPK11Slot public_slot_;
ScopedPK11Slot private_slot_;
- bool is_primary_user_;
+
+ bool private_slot_initialization_started_;
typedef std::vector<base::Callback<void(ScopedPK11Slot)> >
SlotReadyCallbackList;
@@ -271,30 +276,13 @@ class NSSInitSingleton {
// Used with PostTaskAndReply to pass handles to worker thread and back.
struct TPMModuleAndSlot {
explicit TPMModuleAndSlot(SECMODModule* init_chaps_module)
- : chaps_module(init_chaps_module), tpm_slot(NULL) {}
+ : chaps_module(init_chaps_module) {}
SECMODModule* chaps_module;
- PK11SlotInfo* tpm_slot;
+ crypto::ScopedPK11Slot tpm_slot;
};
- void OpenPersistentNSSDB() {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- if (!chromeos_user_logged_in_) {
- // GetDefaultConfigDirectory causes us to do blocking IO on UI thread.
- // Temporarily allow it until we fix http://crbug.com/70119
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- chromeos_user_logged_in_ = true;
-
- // This creates another DB slot in NSS that is read/write, unlike
- // the fake root CA cert DB and the "default" crypto key
- // provider, which are still read-only (because we initialized
- // NSS before we had a cryptohome mounted).
- software_slot_ = OpenUserDB(GetDefaultConfigDirectory(),
- kNSSDatabaseName);
- }
- }
-
- PK11SlotInfo* OpenPersistentNSSDBForPath(const base::FilePath& path) {
+ ScopedPK11Slot OpenPersistentNSSDBForPath(const std::string& db_name,
+ const base::FilePath& path) {
DCHECK(thread_checker_.CalledOnValidThread());
// NSS is allowed to do IO on the current thread since dispatching
// to a dedicated thread would still have the affect of blocking
@@ -304,9 +292,9 @@ class NSSInitSingleton {
base::FilePath nssdb_path = path.AppendASCII(".pki").AppendASCII("nssdb");
if (!base::CreateDirectory(nssdb_path)) {
LOG(ERROR) << "Failed to create " << nssdb_path.value() << " directory.";
- return NULL;
+ return ScopedPK11Slot();
}
- return OpenUserDB(nssdb_path, kNSSDatabaseName);
+ return OpenSoftwareNSSDB(nssdb_path, db_name);
}
void EnableTPMTokenForNSS() {
@@ -323,8 +311,9 @@ class NSSInitSingleton {
return tpm_token_enabled_for_nss_;
}
- void InitializeTPMToken(int token_slot_id,
- const base::Callback<void(bool)>& callback) {
+ void InitializeTPMTokenAndSystemSlot(
+ int system_slot_id,
+ const base::Callback<void(bool)>& callback) {
DCHECK(thread_checker_.CalledOnValidThread());
// Should not be called while there is already an initialization in
// progress.
@@ -352,9 +341,9 @@ class NSSInitSingleton {
if (base::WorkerPool::PostTaskAndReply(
FROM_HERE,
base::Bind(&NSSInitSingleton::InitializeTPMTokenOnWorkerThread,
- token_slot_id,
+ system_slot_id,
tpm_args_ptr),
- base::Bind(&NSSInitSingleton::OnInitializedTPMToken,
+ base::Bind(&NSSInitSingleton::OnInitializedTPMTokenAndSystemSlot,
base::Unretained(this), // NSSInitSingleton is leaky
callback,
base::Passed(&tpm_args)),
@@ -389,34 +378,38 @@ class NSSInitSingleton {
}
}
- void OnInitializedTPMToken(const base::Callback<void(bool)>& callback,
- scoped_ptr<TPMModuleAndSlot> tpm_args) {
+ void OnInitializedTPMTokenAndSystemSlot(
+ const base::Callback<void(bool)>& callback,
+ scoped_ptr<TPMModuleAndSlot> tpm_args) {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(2) << "Loaded chaps: " << !!tpm_args->chaps_module
<< ", got tpm slot: " << !!tpm_args->tpm_slot;
chaps_module_ = tpm_args->chaps_module;
- tpm_slot_ = tpm_args->tpm_slot;
- if (!chaps_module_ && test_slot_) {
+ tpm_slot_ = tpm_args->tpm_slot.Pass();
+ if (!chaps_module_ && test_system_slot_) {
// chromeos_unittests try to test the TPM initialization process. If we
// have a test DB open, pretend that it is the TPM slot.
- tpm_slot_ = PK11_ReferenceSlot(test_slot_);
+ tpm_slot_.reset(PK11_ReferenceSlot(test_system_slot_.get()));
}
initializing_tpm_token_ = false;
- if (tpm_slot_) {
- TPMReadyCallbackList callback_list;
- callback_list.swap(tpm_ready_callback_list_);
- for (TPMReadyCallbackList::iterator i = callback_list.begin();
- i != callback_list.end();
- ++i) {
- (*i).Run();
- }
- }
+ if (tpm_slot_)
+ RunAndClearTPMReadyCallbackList();
callback.Run(!!tpm_slot_);
}
+ void RunAndClearTPMReadyCallbackList() {
+ TPMReadyCallbackList callback_list;
+ callback_list.swap(tpm_ready_callback_list_);
+ for (TPMReadyCallbackList::iterator i = callback_list.begin();
+ i != callback_list.end();
+ ++i) {
+ i->Run();
+ }
+ }
+
bool IsTPMTokenReady(const base::Closure& callback) {
if (!callback.is_null()) {
// Cannot DCHECK in the general case yet, but since the callback is
@@ -429,7 +422,7 @@ class NSSInitSingleton {
<< base::debug::StackTrace().ToString();
}
- if (tpm_slot_ != NULL)
+ if (tpm_slot_)
return true;
if (!callback.is_null())
@@ -441,8 +434,9 @@ class NSSInitSingleton {
// Note that CK_SLOT_ID is an unsigned long, but cryptohome gives us the slot
// id as an int. This should be safe since this is only used with chaps, which
// we also control.
- static PK11SlotInfo* GetTPMSlotForIdOnWorkerThread(SECMODModule* chaps_module,
- CK_SLOT_ID slot_id) {
+ static crypto::ScopedPK11Slot GetTPMSlotForIdOnWorkerThread(
+ SECMODModule* chaps_module,
+ CK_SLOT_ID slot_id) {
DCHECK(chaps_module);
DVLOG(3) << "Poking chaps module.";
@@ -453,37 +447,49 @@ class NSSInitSingleton {
PK11SlotInfo* slot = SECMOD_LookupSlot(chaps_module->moduleID, slot_id);
if (!slot)
LOG(ERROR) << "TPM slot " << slot_id << " not found.";
- return slot;
+ return crypto::ScopedPK11Slot(slot);
}
- bool InitializeNSSForChromeOSUser(
- const std::string& email,
- const std::string& username_hash,
- bool is_primary_user,
- const base::FilePath& path) {
+ bool InitializeNSSForChromeOSUser(const std::string& username_hash,
+ const base::FilePath& path) {
DCHECK(thread_checker_.CalledOnValidThread());
if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) {
// This user already exists in our mapping.
DVLOG(2) << username_hash << " already initialized.";
return false;
}
- ScopedPK11Slot public_slot;
- if (is_primary_user) {
- DVLOG(2) << "Primary user, using GetPublicNSSKeySlot()";
- public_slot.reset(GetPublicNSSKeySlot());
- } else {
- DVLOG(2) << "Opening NSS DB " << path.value();
- public_slot.reset(OpenPersistentNSSDBForPath(path));
- }
+
+ DVLOG(2) << "Opening NSS DB " << path.value();
+ std::string db_name = base::StringPrintf(
+ "%s %s", kUserNSSDatabaseName, username_hash.c_str());
+ ScopedPK11Slot public_slot(OpenPersistentNSSDBForPath(db_name, path));
chromeos_user_map_[username_hash] =
- new ChromeOSUserData(public_slot.Pass(), is_primary_user);
+ new ChromeOSUserData(public_slot.Pass());
return true;
}
+ bool ShouldInitializeTPMForChromeOSUser(const std::string& username_hash) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());
+
+ return !chromeos_user_map_[username_hash]
+ ->private_slot_initialization_started();
+ }
+
+ void WillInitializeTPMForChromeOSUser(const std::string& username_hash) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());
+
+ chromeos_user_map_[username_hash]
+ ->set_private_slot_initialization_started();
+ }
+
void InitializeTPMForChromeOSUser(const std::string& username_hash,
CK_SLOT_ID slot_id) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());
+ DCHECK(chromeos_user_map_[username_hash]->
+ private_slot_initialization_started());
if (!chaps_module_)
return;
@@ -511,7 +517,7 @@ class NSSInitSingleton {
DVLOG(2) << "Got tpm slot for " << username_hash << " "
<< !!tpm_args->tpm_slot;
chromeos_user_map_[username_hash]->SetPrivateSlot(
- ScopedPK11Slot(tpm_args->tpm_slot));
+ tpm_args->tpm_slot.Pass());
}
void InitializePrivateSoftwareSlotForChromeOSUser(
@@ -519,6 +525,9 @@ class NSSInitSingleton {
DCHECK(thread_checker_.CalledOnValidThread());
VLOG(1) << "using software private slot for " << username_hash;
DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());
+ DCHECK(chromeos_user_map_[username_hash]->
+ private_slot_initialization_started());
+
chromeos_user_map_[username_hash]->SetPrivateSlot(
chromeos_user_map_[username_hash]->GetPublicSlot());
}
@@ -532,11 +541,6 @@ class NSSInitSingleton {
return ScopedPK11Slot();
}
- if (test_slot_) {
- DVLOG(2) << "returning test_slot_ for " << username_hash;
- return ScopedPK11Slot(PK11_ReferenceSlot(test_slot_));
- }
-
if (chromeos_user_map_.find(username_hash) == chromeos_user_map_.end()) {
LOG(ERROR) << username_hash << " not initialized.";
return ScopedPK11Slot();
@@ -560,97 +564,69 @@ class NSSInitSingleton {
DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());
- if (test_slot_) {
- DVLOG(2) << "returning test_slot_ for " << username_hash;
- return ScopedPK11Slot(PK11_ReferenceSlot(test_slot_));
- }
-
return chromeos_user_map_[username_hash]->GetPrivateSlot(callback);
}
- void CloseTestChromeOSUser(const std::string& username_hash) {
+ void CloseChromeOSUserForTesting(const std::string& username_hash) {
DCHECK(thread_checker_.CalledOnValidThread());
ChromeOSUserMap::iterator i = chromeos_user_map_.find(username_hash);
DCHECK(i != chromeos_user_map_.end());
delete i->second;
chromeos_user_map_.erase(i);
}
-#endif // defined(OS_CHROMEOS)
-
-
- bool OpenTestNSSDB() {
- DCHECK(thread_checker_.CalledOnValidThread());
- // NSS is allowed to do IO on the current thread since dispatching
- // to a dedicated thread would still have the affect of blocking
- // the current thread, due to NSS's internal locking requirements
- base::ThreadRestrictions::ScopedAllowIO allow_io;
-
- if (test_slot_)
- return true;
- if (!g_test_nss_db_dir.Get().CreateUniqueTempDir())
- return false;
- test_slot_ = OpenUserDB(g_test_nss_db_dir.Get().path(), kTestTPMTokenName);
- return !!test_slot_;
- }
- void CloseTestNSSDB() {
- DCHECK(thread_checker_.CalledOnValidThread());
- // NSS is allowed to do IO on the current thread since dispatching
- // to a dedicated thread would still have the affect of blocking
- // the current thread, due to NSS's internal locking requirements
- base::ThreadRestrictions::ScopedAllowIO allow_io;
-
- if (!test_slot_)
- return;
- SECStatus status = SECMOD_CloseUserDB(test_slot_);
- if (status != SECSuccess)
- PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError();
- PK11_FreeSlot(test_slot_);
- test_slot_ = NULL;
- ignore_result(g_test_nss_db_dir.Get().Delete());
+ void SetSystemKeySlotForTesting(ScopedPK11Slot slot) {
+ // Ensure that a previous value of test_system_slot_ is not overwritten.
+ // Unsetting, i.e. setting a NULL, however is allowed.
+ DCHECK(!slot || !test_system_slot_);
+ test_system_slot_ = slot.Pass();
+ if (test_system_slot_) {
+ tpm_slot_.reset(PK11_ReferenceSlot(test_system_slot_.get()));
+ RunAndClearTPMReadyCallbackList();
+ } else {
+ tpm_slot_.reset();
+ }
}
+#endif // defined(OS_CHROMEOS)
- PK11SlotInfo* GetPublicNSSKeySlot() {
+#if !defined(OS_CHROMEOS)
+ PK11SlotInfo* GetPersistentNSSKeySlot() {
// TODO(mattm): Change to DCHECK when callers have been fixed.
if (!thread_checker_.CalledOnValidThread()) {
DVLOG(1) << "Called on wrong thread.\n"
<< base::debug::StackTrace().ToString();
}
- if (test_slot_)
- return PK11_ReferenceSlot(test_slot_);
- if (software_slot_)
- return PK11_ReferenceSlot(software_slot_);
return PK11_GetInternalKeySlot();
}
+#endif
- PK11SlotInfo* GetPrivateNSSKeySlot() {
- // TODO(mattm): Change to DCHECK when callers have been fixed.
- if (!thread_checker_.CalledOnValidThread()) {
- DVLOG(1) << "Called on wrong thread.\n"
- << base::debug::StackTrace().ToString();
- }
+#if defined(OS_CHROMEOS)
+ void GetSystemNSSKeySlotCallback(
+ const base::Callback<void(ScopedPK11Slot)>& callback) {
+ callback.Run(ScopedPK11Slot(PK11_ReferenceSlot(tpm_slot_.get())));
+ }
- if (test_slot_)
- return PK11_ReferenceSlot(test_slot_);
+ ScopedPK11Slot GetSystemNSSKeySlot(
+ const base::Callback<void(ScopedPK11Slot)>& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // TODO(mattm): chromeos::TPMTokenloader always calls
+ // InitializeTPMTokenAndSystemSlot with slot 0. If the system slot is
+ // disabled, tpm_slot_ will be the first user's slot instead. Can that be
+ // detected and return NULL instead?
-#if defined(OS_CHROMEOS)
- if (tpm_token_enabled_for_nss_) {
- if (IsTPMTokenReady(base::Closure())) {
- return PK11_ReferenceSlot(tpm_slot_);
- } else {
- // If we were supposed to get the hardware token, but were
- // unable to, return NULL rather than fall back to sofware.
- return NULL;
- }
+ base::Closure wrapped_callback;
+ if (!callback.is_null()) {
+ wrapped_callback =
+ base::Bind(&NSSInitSingleton::GetSystemNSSKeySlotCallback,
+ base::Unretained(this) /* singleton is leaky */,
+ callback);
}
-#endif
- // If we weren't supposed to enable the TPM for NSS, then return
- // the software slot.
- if (software_slot_)
- return PK11_ReferenceSlot(software_slot_);
- return PK11_GetInternalKeySlot();
+ if (IsTPMTokenReady(wrapped_callback))
+ return ScopedPK11Slot(PK11_ReferenceSlot(tpm_slot_.get()));
+ return ScopedPK11Slot();
}
+#endif
#if defined(USE_NSS)
base::Lock* write_lock() {
@@ -671,11 +647,7 @@ class NSSInitSingleton {
: tpm_token_enabled_for_nss_(false),
initializing_tpm_token_(false),
chaps_module_(NULL),
- software_slot_(NULL),
- test_slot_(NULL),
- tpm_slot_(NULL),
- root_(NULL),
- chromeos_user_logged_in_(false) {
+ root_(NULL) {
base::TimeTicks start_time = base::TimeTicks::Now();
// It's safe to construct on any thread, since LazyInstance will prevent any
@@ -776,12 +748,12 @@ class NSSInitSingleton {
0, NSS_USE_ALG_IN_CERT_SIGNATURE);
// The UMA bit is conditionally set for this histogram in
- // chrome/common/startup_metric_utils.cc .
- HISTOGRAM_CUSTOM_TIMES("Startup.SlowStartupNSSInit",
- base::TimeTicks::Now() - start_time,
- base::TimeDelta::FromMilliseconds(10),
- base::TimeDelta::FromHours(1),
- 50);
+ // components/startup_metric_utils.cc .
+ LOCAL_HISTOGRAM_CUSTOM_TIMES("Startup.SlowStartupNSSInit",
+ base::TimeTicks::Now() - start_time,
+ base::TimeDelta::FromMilliseconds(10),
+ base::TimeDelta::FromHours(1),
+ 50);
}
// NOTE(willchan): We don't actually execute this code since we leak NSS to
@@ -791,16 +763,7 @@ class NSSInitSingleton {
#if defined(OS_CHROMEOS)
STLDeleteValues(&chromeos_user_map_);
#endif
- if (tpm_slot_) {
- PK11_FreeSlot(tpm_slot_);
- tpm_slot_ = NULL;
- }
- if (software_slot_) {
- SECMOD_CloseUserDB(software_slot_);
- PK11_FreeSlot(software_slot_);
- software_slot_ = NULL;
- }
- CloseTestNSSDB();
+ tpm_slot_.reset();
if (root_) {
SECMOD_UnloadUserModule(root_);
SECMOD_DestroyModule(root_);
@@ -862,23 +825,6 @@ class NSSInitSingleton {
}
#endif
- static PK11SlotInfo* OpenUserDB(const base::FilePath& path,
- const char* description) {
- const std::string modspec =
- base::StringPrintf("configDir='sql:%s' tokenDescription='%s'",
- path.value().c_str(), description);
- PK11SlotInfo* db_slot = SECMOD_OpenUserDB(modspec.c_str());
- if (db_slot) {
- if (PK11_NeedUserInit(db_slot))
- PK11_InitPin(db_slot, NULL, NULL);
- }
- else {
- LOG(ERROR) << "Error opening persistent database (" << modspec
- << "): " << GetNSSErrorMessage();
- }
- return db_slot;
- }
-
static void DisableAESNIIfNeeded() {
if (NSS_VersionCheck("3.15") && !NSS_VersionCheck("3.15.4")) {
// Some versions of NSS have a bug that causes AVX instructions to be
@@ -902,14 +848,12 @@ class NSSInitSingleton {
typedef std::vector<base::Closure> TPMReadyCallbackList;
TPMReadyCallbackList tpm_ready_callback_list_;
SECMODModule* chaps_module_;
- PK11SlotInfo* software_slot_;
- PK11SlotInfo* test_slot_;
- PK11SlotInfo* tpm_slot_;
+ crypto::ScopedPK11Slot tpm_slot_;
SECMODModule* root_;
- bool chromeos_user_logged_in_;
#if defined(OS_CHROMEOS)
typedef std::map<std::string, ChromeOSUserData*> ChromeOSUserMap;
ChromeOSUserMap chromeos_user_map_;
+ ScopedPK11Slot test_system_slot_;
#endif
#if defined(USE_NSS)
// TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011
@@ -927,9 +871,24 @@ base::LazyInstance<NSSInitSingleton>::Leaky
g_nss_singleton = LAZY_INSTANCE_INITIALIZER;
} // namespace
-const char kTestTPMTokenName[] = "Test DB";
-
#if defined(USE_NSS)
+ScopedPK11Slot OpenSoftwareNSSDB(const base::FilePath& path,
+ const std::string& description) {
+ const std::string modspec =
+ base::StringPrintf("configDir='sql:%s' tokenDescription='%s'",
+ path.value().c_str(),
+ description.c_str());
+ PK11SlotInfo* db_slot = SECMOD_OpenUserDB(modspec.c_str());
+ if (db_slot) {
+ if (PK11_NeedUserInit(db_slot))
+ PK11_InitPin(db_slot, NULL, NULL);
+ } else {
+ LOG(ERROR) << "Error opening persistent database (" << modspec
+ << "): " << GetNSSErrorMessage();
+ }
+ return ScopedPK11Slot(db_slot);
+}
+
void EarlySetupForNSSInit() {
base::FilePath database_dir = GetInitialConfigDirectory();
if (!database_dir.empty())
@@ -1028,19 +987,6 @@ bool CheckNSSVersion(const char* version) {
}
#if defined(USE_NSS)
-ScopedTestNSSDB::ScopedTestNSSDB()
- : is_open_(g_nss_singleton.Get().OpenTestNSSDB()) {
-}
-
-ScopedTestNSSDB::~ScopedTestNSSDB() {
- // Don't close when NSS is < 3.15.1, because it would require an additional
- // sleep for 1 second after closing the database, due to
- // http://bugzil.la/875601.
- if (NSS_VersionCheck("3.15.1")) {
- g_nss_singleton.Get().CloseTestNSSDB();
- }
-}
-
base::Lock* GetNSSWriteLock() {
return g_nss_singleton.Get().write_lock();
}
@@ -1066,12 +1012,16 @@ AutoSECMODListReadLock::AutoSECMODListReadLock()
AutoSECMODListReadLock::~AutoSECMODListReadLock() {
SECMOD_ReleaseReadLock(lock_);
}
-
#endif // defined(USE_NSS)
#if defined(OS_CHROMEOS)
-void OpenPersistentNSSDB() {
- g_nss_singleton.Get().OpenPersistentNSSDB();
+ScopedPK11Slot GetSystemNSSKeySlot(
+ const base::Callback<void(ScopedPK11Slot)>& callback) {
+ return g_nss_singleton.Get().GetSystemNSSKeySlot(callback);
+}
+
+void SetSystemKeySlotForTesting(ScopedPK11Slot slot) {
+ g_nss_singleton.Get().SetSystemKeySlotForTesting(slot.Pass());
}
void EnableTPMTokenForNSS() {
@@ -1086,59 +1036,54 @@ bool IsTPMTokenReady(const base::Closure& callback) {
return g_nss_singleton.Get().IsTPMTokenReady(callback);
}
-void InitializeTPMToken(int token_slot_id,
- const base::Callback<void(bool)>& callback) {
- g_nss_singleton.Get().InitializeTPMToken(token_slot_id, callback);
+void InitializeTPMTokenAndSystemSlot(
+ int token_slot_id,
+ const base::Callback<void(bool)>& callback) {
+ g_nss_singleton.Get().InitializeTPMTokenAndSystemSlot(token_slot_id,
+ callback);
}
-ScopedTestNSSChromeOSUser::ScopedTestNSSChromeOSUser(
- const std::string& username_hash)
- : username_hash_(username_hash), constructed_successfully_(false) {
- if (!temp_dir_.CreateUniqueTempDir())
- return;
- constructed_successfully_ =
- InitializeNSSForChromeOSUser(username_hash,
- username_hash,
- false /* is_primary_user */,
- temp_dir_.path());
+bool InitializeNSSForChromeOSUser(const std::string& username_hash,
+ const base::FilePath& path) {
+ return g_nss_singleton.Get().InitializeNSSForChromeOSUser(username_hash,
+ path);
}
-ScopedTestNSSChromeOSUser::~ScopedTestNSSChromeOSUser() {
- if (constructed_successfully_)
- g_nss_singleton.Get().CloseTestChromeOSUser(username_hash_);
+bool ShouldInitializeTPMForChromeOSUser(const std::string& username_hash) {
+ return g_nss_singleton.Get().ShouldInitializeTPMForChromeOSUser(
+ username_hash);
}
-void ScopedTestNSSChromeOSUser::FinishInit() {
- InitializePrivateSoftwareSlotForChromeOSUser(username_hash_);
+void WillInitializeTPMForChromeOSUser(const std::string& username_hash) {
+ g_nss_singleton.Get().WillInitializeTPMForChromeOSUser(username_hash);
}
-bool InitializeNSSForChromeOSUser(
- const std::string& email,
- const std::string& username_hash,
- bool is_primary_user,
- const base::FilePath& path) {
- return g_nss_singleton.Get().InitializeNSSForChromeOSUser(
- email, username_hash, is_primary_user, path);
-}
void InitializeTPMForChromeOSUser(
const std::string& username_hash,
CK_SLOT_ID slot_id) {
g_nss_singleton.Get().InitializeTPMForChromeOSUser(username_hash, slot_id);
}
+
void InitializePrivateSoftwareSlotForChromeOSUser(
const std::string& username_hash) {
g_nss_singleton.Get().InitializePrivateSoftwareSlotForChromeOSUser(
username_hash);
}
+
ScopedPK11Slot GetPublicSlotForChromeOSUser(const std::string& username_hash) {
return g_nss_singleton.Get().GetPublicSlotForChromeOSUser(username_hash);
}
+
ScopedPK11Slot GetPrivateSlotForChromeOSUser(
const std::string& username_hash,
const base::Callback<void(ScopedPK11Slot)>& callback) {
return g_nss_singleton.Get().GetPrivateSlotForChromeOSUser(username_hash,
callback);
}
+
+void CloseChromeOSUserForTesting(const std::string& username_hash) {
+ g_nss_singleton.Get().CloseChromeOSUserForTesting(username_hash);
+}
#endif // defined(OS_CHROMEOS)
base::Time PRTimeToBaseTime(PRTime prtime) {
@@ -1150,12 +1095,10 @@ PRTime BaseTimeToPRTime(base::Time time) {
return time.ToInternalValue() - base::Time::UnixEpoch().ToInternalValue();
}
-PK11SlotInfo* GetPublicNSSKeySlot() {
- return g_nss_singleton.Get().GetPublicNSSKeySlot();
-}
-
-PK11SlotInfo* GetPrivateNSSKeySlot() {
- return g_nss_singleton.Get().GetPrivateNSSKeySlot();
+#if !defined(OS_CHROMEOS)
+PK11SlotInfo* GetPersistentNSSKeySlot() {
+ return g_nss_singleton.Get().GetPersistentNSSKeySlot();
}
+#endif
} // namespace crypto
diff --git a/chromium/crypto/nss_util.h b/chromium/crypto/nss_util.h
index e94c4f6daca..56fdfa6b659 100644
--- a/chromium/crypto/nss_util.h
+++ b/chromium/crypto/nss_util.h
@@ -9,7 +9,6 @@
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
-#include "base/files/scoped_temp_dir.h"
#include "crypto/crypto_export.h"
namespace base {
@@ -23,9 +22,6 @@ class Time;
// initialization functions.
namespace crypto {
-// The TPMToken name used for the NSS slot opened by ScopedTestNSSDB.
-CRYPTO_EXPORT extern const char kTestTPMTokenName[];
-
#if defined(USE_NSS)
// EarlySetupForNSSInit performs lightweight setup which must occur before the
// process goes multithreaded. This does not initialise NSS. For test, see
@@ -95,14 +91,9 @@ CRYPTO_EXPORT void LoadNSSLibraries();
bool CheckNSSVersion(const char* version);
#if defined(OS_CHROMEOS)
-// Open the r/w nssdb that's stored inside the user's encrypted home
-// directory. This is the default slot returned by
-// GetPublicNSSKeySlot().
-CRYPTO_EXPORT void OpenPersistentNSSDB();
-
-// Indicates that NSS should load the Chaps library so that we
-// can access the TPM through NSS. Once this is called,
-// GetPrivateNSSKeySlot() will return the TPM slot if one was found.
+// Indicates that NSS should use the Chaps library so that we
+// can access the TPM through NSS. InitializeTPMTokenAndSystemSlot and
+// InitializeTPMForChromeOSUser must still be called to load the slots.
CRYPTO_EXPORT void EnableTPMTokenForNSS();
// Returns true if EnableTPMTokenForNSS has been called.
@@ -118,34 +109,14 @@ CRYPTO_EXPORT bool IsTPMTokenEnabledForNSS();
CRYPTO_EXPORT bool IsTPMTokenReady(const base::Closure& callback)
WARN_UNUSED_RESULT;
-// Initialize the TPM token. The |callback| will run on the same thread with
-// true if the token and slot were successfully loaded or were already
-// initialized. |callback| will be passed false if loading failed.
-// Once called, InitializeTPMToken must not be called again until the |callback|
-// has been run.
-CRYPTO_EXPORT void InitializeTPMToken(
- int token_slot_id,
+// Initialize the TPM token and system slot. The |callback| will run on the same
+// thread with true if the token and slot were successfully loaded or were
+// already initialized. |callback| will be passed false if loading failed. Once
+// called, InitializeTPMTokenAndSystemSlot must not be called again until the
+// |callback| has been run.
+CRYPTO_EXPORT void InitializeTPMTokenAndSystemSlot(
+ int system_slot_id,
const base::Callback<void(bool)>& callback);
-
-// Exposed for unittests only.
-class CRYPTO_EXPORT_PRIVATE ScopedTestNSSChromeOSUser {
- public:
- explicit ScopedTestNSSChromeOSUser(const std::string& username_hash);
- ~ScopedTestNSSChromeOSUser();
-
- std::string username_hash() const { return username_hash_; }
- bool constructed_successfully() const { return constructed_successfully_; }
-
- // Completes initialization of user. Causes any waiting private slot callbacks
- // to run.
- void FinishInit();
-
- private:
- const std::string username_hash_;
- base::ScopedTempDir temp_dir_;
- bool constructed_successfully_;
- DISALLOW_COPY_AND_ASSIGN(ScopedTestNSSChromeOSUser);
-};
#endif
// Convert a NSS PRTime value into a base::Time object.
@@ -157,23 +128,6 @@ CRYPTO_EXPORT base::Time PRTimeToBaseTime(int64 prtime);
CRYPTO_EXPORT int64 BaseTimeToPRTime(base::Time time);
#if defined(USE_NSS)
-// Exposed for unittests only.
-// TODO(mattm): When NSS 3.14 is the minimum version required,
-// switch back to using a separate user DB for each test.
-// Because of https://bugzilla.mozilla.org/show_bug.cgi?id=588269 , the
-// opened user DB is not automatically closed.
-class CRYPTO_EXPORT_PRIVATE ScopedTestNSSDB {
- public:
- ScopedTestNSSDB();
- ~ScopedTestNSSDB();
-
- bool is_open() { return is_open_; }
-
- private:
- bool is_open_;
- DISALLOW_COPY_AND_ASSIGN(ScopedTestNSSDB);
-};
-
// 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
@@ -194,7 +148,6 @@ class CRYPTO_EXPORT AutoNSSWriteLock {
base::Lock *lock_;
DISALLOW_COPY_AND_ASSIGN(AutoNSSWriteLock);
};
-
#endif // defined(USE_NSS)
} // namespace crypto
diff --git a/chromium/crypto/nss_util_internal.h b/chromium/crypto/nss_util_internal.h
index 262a59a1ba9..f321343d956 100644
--- a/chromium/crypto/nss_util_internal.h
+++ b/chromium/crypto/nss_util_internal.h
@@ -21,17 +21,18 @@ class FilePath;
namespace crypto {
-// Returns a reference to the default NSS key slot for storing
-// public-key data only (e.g. server certs). Caller must release
-// returned reference with PK11_FreeSlot.
-CRYPTO_EXPORT PK11SlotInfo* GetPublicNSSKeySlot() WARN_UNUSED_RESULT;
-
-// Returns a reference to the default slot for storing private-key and
-// mixed private-key/public-key data. Returns a hardware (TPM) NSS
-// key slot if on ChromeOS and EnableTPMForNSS() has been called
-// successfully. Caller must release returned reference with
-// PK11_FreeSlot.
-CRYPTO_EXPORT PK11SlotInfo* GetPrivateNSSKeySlot() WARN_UNUSED_RESULT;
+// Opens an NSS software database in folder |path|, with the (potentially)
+// user-visible description |description|. Returns the slot for the opened
+// database, or NULL if the database could not be opened.
+CRYPTO_EXPORT_PRIVATE ScopedPK11Slot
+ OpenSoftwareNSSDB(const base::FilePath& path,
+ const std::string& description);
+
+#if !defined(OS_CHROMEOS)
+// Returns a reference to the default NSS key slot for storing persistent data.
+// Caller must release returned reference with PK11_FreeSlot.
+CRYPTO_EXPORT PK11SlotInfo* GetPersistentNSSKeySlot() WARN_UNUSED_RESULT;
+#endif
// A helper class that acquires the SECMOD list read lock while the
// AutoSECMODListReadLock is in scope.
@@ -46,13 +47,38 @@ class CRYPTO_EXPORT AutoSECMODListReadLock {
};
#if defined(OS_CHROMEOS)
+// Returns a reference to the system-wide TPM slot if it is loaded. If it is not
+// loaded and |callback| is non-null, the |callback| will be run once the slot
+// is loaded.
+CRYPTO_EXPORT ScopedPK11Slot GetSystemNSSKeySlot(
+ const base::Callback<void(ScopedPK11Slot)>& callback) WARN_UNUSED_RESULT;
+
+// Sets the test system slot to |slot|, which means that |slot| will be exposed
+// through |GetSystemNSSKeySlot| and |IsTPMTokenReady| will return true.
+// |InitializeTPMTokenAndSystemSlot|, which triggers the TPM initialization,
+// does not have to be called if the test system slot is set.
+// This must must not be called consecutively with a |slot| != NULL. If |slot|
+// is NULL, the test system slot is unset.
+CRYPTO_EXPORT_PRIVATE void SetSystemKeySlotForTesting(ScopedPK11Slot slot);
+
// Prepare per-user NSS slot mapping. It is safe to call this function multiple
// times. Returns true if the user was added, or false if it already existed.
CRYPTO_EXPORT bool InitializeNSSForChromeOSUser(
- const std::string& email,
const std::string& username_hash,
- bool is_primary_user,
- const base::FilePath& path) WARN_UNUSED_RESULT;
+ const base::FilePath& path);
+
+// Returns whether TPM for ChromeOS user still needs initialization. If
+// true is returned, the caller can proceed to initialize TPM slot for the
+// user, but should call |WillInitializeTPMForChromeOSUser| first.
+// |InitializeNSSForChromeOSUser| must have been called first.
+CRYPTO_EXPORT bool ShouldInitializeTPMForChromeOSUser(
+ const std::string& username_hash) WARN_UNUSED_RESULT;
+
+// Makes |ShouldInitializeTPMForChromeOSUser| start returning false.
+// Should be called before starting TPM initialization for the user.
+// Assumes |InitializeNSSForChromeOSUser| had already been called.
+CRYPTO_EXPORT void WillInitializeTPMForChromeOSUser(
+ const std::string& username_hash);
// Use TPM slot |slot_id| for user. InitializeNSSForChromeOSUser must have been
// called first.
@@ -75,6 +101,11 @@ CRYPTO_EXPORT ScopedPK11Slot GetPublicSlotForChromeOSUser(
CRYPTO_EXPORT ScopedPK11Slot GetPrivateSlotForChromeOSUser(
const std::string& username_hash,
const base::Callback<void(ScopedPK11Slot)>& callback) WARN_UNUSED_RESULT;
+
+// Closes the NSS DB for |username_hash| that was previously opened by the
+// *Initialize*ForChromeOSUser functions.
+CRYPTO_EXPORT_PRIVATE void CloseChromeOSUserForTesting(
+ const std::string& username_hash);
#endif // defined(OS_CHROMEOS)
} // namespace crypto
diff --git a/chromium/crypto/nss_util_unittest.cc b/chromium/crypto/nss_util_unittest.cc
index b68788513c6..28591916d3f 100644
--- a/chromium/crypto/nss_util_unittest.cc
+++ b/chromium/crypto/nss_util_unittest.cc
@@ -19,14 +19,17 @@ TEST(NSSUtilTest, PRTimeConversion) {
prxtime.tm_params.tp_gmt_offset = 0;
prxtime.tm_params.tp_dst_offset = 0;
base::Time::Exploded exploded;
- prxtime.tm_year = exploded.year = 2011;
+ exploded.year = prxtime.tm_year = 2011;
exploded.month = 12;
prxtime.tm_month = 11;
- prxtime.tm_wday = exploded.day_of_week = 0; // Should be unusued.
- prxtime.tm_mday = exploded.day_of_month = 10;
- prxtime.tm_hour = exploded.hour = 2;
- prxtime.tm_min = exploded.minute = 52;
- prxtime.tm_sec = exploded.second = 19;
+ // PRExplodedTime::tm_wday is a smaller type than Exploded::day_of_week, so
+ // assigning the two in this order instead of the reverse avoids potential
+ // warnings about type downcasting.
+ exploded.day_of_week = prxtime.tm_wday = 0; // Should be unused.
+ exploded.day_of_month = prxtime.tm_mday = 10;
+ exploded.hour = prxtime.tm_hour = 2;
+ exploded.minute = prxtime.tm_min = 52;
+ exploded.second = prxtime.tm_sec = 19;
exploded.millisecond = 342;
prxtime.tm_usec = 342000;
diff --git a/chromium/crypto/openssl_bio_string_unittest.cc b/chromium/crypto/openssl_bio_string_unittest.cc
index 39d3a9aeaed..9dfa0e70f73 100644
--- a/chromium/crypto/openssl_bio_string_unittest.cc
+++ b/chromium/crypto/openssl_bio_string_unittest.cc
@@ -6,39 +6,34 @@
#include <openssl/bio.h>
-#include "crypto/openssl_util.h"
+#include "crypto/scoped_openssl_types.h"
#include "testing/gtest/include/gtest/gtest.h"
+namespace crypto {
+
TEST(OpenSSLBIOString, TestWrite) {
std::string s;
const std::string expected1("a one\nb 2\n");
const std::string expected2("c d e f");
const std::string expected3("g h i");
{
- crypto::ScopedOpenSSL<BIO, BIO_free_all> bio(crypto::BIO_new_string(&s));
+ ScopedBIO bio(BIO_new_string(&s));
ASSERT_TRUE(bio.get());
EXPECT_EQ(static_cast<int>(expected1.size()),
BIO_printf(bio.get(), "a %s\nb %i\n", "one", 2));
EXPECT_EQ(expected1, s);
- EXPECT_EQ(static_cast<int>(expected1.size()), BIO_tell(bio.get()));
EXPECT_EQ(1, BIO_flush(bio.get()));
- EXPECT_EQ(-1, BIO_seek(bio.get(), 0));
EXPECT_EQ(expected1, s);
EXPECT_EQ(static_cast<int>(expected2.size()),
BIO_write(bio.get(), expected2.data(), expected2.size()));
EXPECT_EQ(expected1 + expected2, s);
- EXPECT_EQ(static_cast<int>(expected1.size() + expected2.size()),
- BIO_tell(bio.get()));
EXPECT_EQ(static_cast<int>(expected3.size()),
BIO_puts(bio.get(), expected3.c_str()));
EXPECT_EQ(expected1 + expected2 + expected3, s);
- EXPECT_EQ(static_cast<int>(expected1.size() + expected2.size() +
- expected3.size()),
- BIO_tell(bio.get()));
}
EXPECT_EQ(expected1 + expected2 + expected3, s);
}
@@ -48,7 +43,7 @@ TEST(OpenSSLBIOString, TestReset) {
const std::string expected1("a b c\n");
const std::string expected2("d e f g\n");
{
- crypto::ScopedOpenSSL<BIO, BIO_free_all> bio(crypto::BIO_new_string(&s));
+ ScopedBIO bio(BIO_new_string(&s));
ASSERT_TRUE(bio.get());
EXPECT_EQ(static_cast<int>(expected1.size()),
@@ -64,3 +59,5 @@ TEST(OpenSSLBIOString, TestReset) {
}
EXPECT_EQ(expected2, s);
}
+
+} // namespace crypto
diff --git a/chromium/crypto/openssl_util.cc b/chromium/crypto/openssl_util.cc
index 34af810c1d0..f41b55a8fff 100644
--- a/chromium/crypto/openssl_util.cc
+++ b/chromium/crypto/openssl_util.cc
@@ -6,6 +6,7 @@
#include <openssl/err.h>
#include <openssl/ssl.h>
+#include <openssl/cpu.h>
#include "base/logging.h"
#include "base/memory/scoped_vector.h"
@@ -16,14 +17,16 @@
#if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
#include <cpu-features.h>
+#include "base/cpu.h"
#endif
namespace crypto {
namespace {
-unsigned long CurrentThreadId() {
- return static_cast<unsigned long>(base::PlatformThread::CurrentId());
+void CurrentThreadId(CRYPTO_THREADID* id) {
+ CRYPTO_THREADID_set_numeric(
+ id, static_cast<unsigned long>(base::PlatformThread::CurrentId()));
}
// Singleton for initializing and cleaning up the OpenSSL library.
@@ -47,19 +50,21 @@ class OpenSSLInitSingleton {
OpenSSLInitSingleton() {
SSL_load_error_strings();
SSL_library_init();
- OpenSSL_add_all_algorithms();
int num_locks = CRYPTO_num_locks();
locks_.reserve(num_locks);
for (int i = 0; i < num_locks; ++i)
locks_.push_back(new base::Lock());
CRYPTO_set_locking_callback(LockingCallback);
- CRYPTO_set_id_callback(CurrentThreadId);
+ 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
}
diff --git a/chromium/crypto/openssl_util.h b/chromium/crypto/openssl_util.h
index bf83e470eb3..2743883dc17 100644
--- a/chromium/crypto/openssl_util.h
+++ b/chromium/crypto/openssl_util.h
@@ -11,36 +11,6 @@
namespace crypto {
-// A helper class that takes care of destroying OpenSSL objects when they go out
-// of scope.
-template <typename T, void (*destructor)(T*)>
-class ScopedOpenSSL {
- public:
- ScopedOpenSSL() : ptr_(NULL) { }
- explicit ScopedOpenSSL(T* ptr) : ptr_(ptr) { }
- ~ScopedOpenSSL() {
- reset(NULL);
- }
-
- T* get() const { return ptr_; }
- T* release() {
- T* ptr = ptr_;
- ptr_ = NULL;
- return ptr;
- }
- void reset(T* ptr) {
- if (ptr != ptr_) {
- if (ptr_) (*destructor)(ptr_);
- ptr_ = ptr;
- }
- }
-
- private:
- T* ptr_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedOpenSSL);
-};
-
// Provides a buffer of at least MIN_SIZE bytes, for use when calling OpenSSL's
// SHA256, HMAC, etc functions, adapting the buffer sizing rules to meet those
// of the our base wrapper APIs.
diff --git a/chromium/crypto/p224.cc b/chromium/crypto/p224.cc
index ac0a081037f..5f76fbc259b 100644
--- a/chromium/crypto/p224.cc
+++ b/chromium/crypto/p224.cc
@@ -149,7 +149,7 @@ void ReduceLarge(FieldElement* out, LargeFieldElement* inptr) {
// Eliminate the term at 2*224 that we introduced while keeping the same
// value mod p.
in[0] -= in[8]; // reflection off the "+1" term of p.
- (*out)[3] += static_cast<uint32>(in[8] & 0xffff) << 12; // "-2**96" term
+ (*out)[3] += static_cast<uint32>(in[8] & 0xffff) << 12; // "-2**96" term
(*out)[4] += static_cast<uint32>(in[8] >> 16); // rest of "-2**96" term
// in[0] < 2**64
// out[3] < 2**29
@@ -638,7 +638,7 @@ void Put224Bits(uint32* out, const uint32* in) {
out[0] = HostToNet32((in[6] >> 24) | (in[7] << 4));
}
-} // anonymous namespace
+} // anonymous namespace
namespace crypto {
diff --git a/chromium/crypto/p224_spake_unittest.cc b/chromium/crypto/p224_spake_unittest.cc
index ca35f7245b9..589cdbfcf0d 100644
--- a/chromium/crypto/p224_spake_unittest.cc
+++ b/chromium/crypto/p224_spake_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <string>
#include <crypto/p224_spake.h>
#include "base/logging.h"
@@ -13,7 +14,6 @@ namespace {
bool RunExchange(P224EncryptedKeyExchange* client,
P224EncryptedKeyExchange* server) {
-
for (;;) {
std::string client_message, server_message;
client_message = client->GetMessage();
diff --git a/chromium/crypto/rsa_private_key.h b/chromium/crypto/rsa_private_key.h
index cb190677b16..221e341a6fe 100644
--- a/chromium/crypto/rsa_private_key.h
+++ b/chromium/crypto/rsa_private_key.h
@@ -216,6 +216,12 @@ class CRYPTO_EXPORT RSAPrivateKey {
static RSAPrivateKey* FindFromPublicKeyInfoInSlot(
const std::vector<uint8>& input,
PK11SlotInfo* slot);
+#elif 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);
+
#endif
#if defined(USE_OPENSSL)
diff --git a/chromium/crypto/rsa_private_key_nss_unittest.cc b/chromium/crypto/rsa_private_key_nss_unittest.cc
index 66d352a0bd2..b91b431c3ee 100644
--- a/chromium/crypto/rsa_private_key_nss_unittest.cc
+++ b/chromium/crypto/rsa_private_key_nss_unittest.cc
@@ -8,7 +8,7 @@
#include <pk11pub.h>
#include "base/memory/scoped_ptr.h"
-#include "crypto/nss_util.h"
+#include "crypto/scoped_test_nss_db.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace crypto {
@@ -18,39 +18,12 @@ class RSAPrivateKeyNSSTest : public testing::Test {
RSAPrivateKeyNSSTest() {}
virtual ~RSAPrivateKeyNSSTest() {}
- virtual void SetUp() {
-#if defined(OS_CHROMEOS)
- OpenPersistentNSSDB();
-#endif
- }
-
private:
ScopedTestNSSDB test_nssdb_;
DISALLOW_COPY_AND_ASSIGN(RSAPrivateKeyNSSTest);
};
-TEST_F(RSAPrivateKeyNSSTest, CreateFromKeyTest) {
- scoped_ptr<crypto::RSAPrivateKey> key_pair(RSAPrivateKey::Create(256));
-
- scoped_ptr<crypto::RSAPrivateKey> key_copy(
- RSAPrivateKey::CreateFromKey(key_pair->key()));
- ASSERT_TRUE(key_copy.get());
-
- std::vector<uint8> privkey;
- std::vector<uint8> pubkey;
- ASSERT_TRUE(key_pair->ExportPrivateKey(&privkey));
- ASSERT_TRUE(key_pair->ExportPublicKey(&pubkey));
-
- std::vector<uint8> privkey_copy;
- std::vector<uint8> pubkey_copy;
- ASSERT_TRUE(key_copy->ExportPrivateKey(&privkey_copy));
- ASSERT_TRUE(key_copy->ExportPublicKey(&pubkey_copy));
-
- ASSERT_EQ(privkey, privkey_copy);
- ASSERT_EQ(pubkey, pubkey_copy);
-}
-
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));
diff --git a/chromium/crypto/rsa_private_key_openssl.cc b/chromium/crypto/rsa_private_key_openssl.cc
index f191e393288..053c4a2f930 100644
--- a/chromium/crypto/rsa_private_key_openssl.cc
+++ b/chromium/crypto/rsa_private_key_openssl.cc
@@ -4,6 +4,8 @@
#include "crypto/rsa_private_key.h"
+#include <openssl/bio.h>
+#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/pkcs12.h>
#include <openssl/rsa.h>
@@ -11,6 +13,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "crypto/openssl_util.h"
+#include "crypto/scoped_openssl_types.h"
namespace crypto {
@@ -29,7 +32,7 @@ bool ExportKey(EVP_PKEY* key,
return false;
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new(BIO_s_mem()));
+ ScopedBIO bio(BIO_new(BIO_s_mem()));
int res = export_fn(bio.get(), key);
if (!res)
@@ -50,8 +53,8 @@ bool ExportKey(EVP_PKEY* key,
RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- ScopedOpenSSL<RSA, RSA_free> rsa_key(RSA_new());
- ScopedOpenSSL<BIGNUM, BN_free> bn(BN_new());
+ ScopedRSA rsa_key(RSA_new());
+ ScopedBIGNUM bn(BN_new());
if (!rsa_key.get() || !bn.get() || !BN_set_word(bn.get(), 65537L))
return NULL;
@@ -75,14 +78,14 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
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]));
- ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data, input.size()));
+ 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> p8inf(
+ ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>::Type p8inf(
d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL));
if (!p8inf.get())
return NULL;
@@ -95,6 +98,16 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
return result.release();
}
+// static
+RSAPrivateKey* RSAPrivateKey::CreateFromKey(EVP_PKEY* key) {
+ DCHECK(key);
+ if (EVP_PKEY_type(key->type) != EVP_PKEY_RSA)
+ return NULL;
+ RSAPrivateKey* copy = new RSAPrivateKey();
+ copy->key_ = EVP_PKEY_dup(key);
+ return copy;
+}
+
RSAPrivateKey::RSAPrivateKey()
: key_(NULL) {
}
@@ -106,11 +119,11 @@ RSAPrivateKey::~RSAPrivateKey() {
RSAPrivateKey* RSAPrivateKey::Copy() const {
scoped_ptr<RSAPrivateKey> copy(new RSAPrivateKey());
- RSA* rsa = EVP_PKEY_get1_RSA(key_);
+ ScopedRSA rsa(EVP_PKEY_get1_RSA(key_));
if (!rsa)
return NULL;
copy->key_ = EVP_PKEY_new();
- if (!EVP_PKEY_set1_RSA(copy->key_, rsa))
+ if (!EVP_PKEY_set1_RSA(copy->key_, rsa.get()))
return NULL;
return copy.release();
}
diff --git a/chromium/crypto/rsa_private_key_unittest.cc b/chromium/crypto/rsa_private_key_unittest.cc
index b981bda07d4..d53d50228d2 100644
--- a/chromium/crypto/rsa_private_key_unittest.cc
+++ b/chromium/crypto/rsa_private_key_unittest.cc
@@ -208,168 +208,168 @@ TEST(RSAPrivateKeyUnitTest, PublicKeyTest) {
// This test case verifies these two failures modes don't occur.
TEST(RSAPrivateKeyUnitTest, ShortIntegers) {
const uint8 short_integer_with_high_bit[] = {
- 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x00, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
- 0x02, 0x61, 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01,
- 0x00, 0x02, 0x81, 0x81, 0x00, 0x92, 0x59, 0x32,
- 0x7d, 0x8e, 0xaf, 0x2e, 0xd5, 0xb2, 0x5c, 0x67,
- 0xc8, 0x7d, 0x48, 0xb7, 0x84, 0x12, 0xd0, 0x76,
- 0xda, 0xe1, 0xa3, 0x1e, 0x40, 0x01, 0x14, 0x5c,
- 0xef, 0x26, 0x6e, 0x28, 0xa2, 0xf7, 0xa5, 0xb4,
- 0x02, 0x37, 0xd0, 0x53, 0x10, 0xcb, 0x7c, 0x6a,
- 0xf4, 0x53, 0x9f, 0xb8, 0xe0, 0x83, 0x93, 0xd1,
- 0x19, 0xd8, 0x28, 0xd1, 0xd1, 0xd8, 0x87, 0x8f,
- 0x92, 0xfd, 0x73, 0xc0, 0x4d, 0x3e, 0x07, 0x22,
- 0x1f, 0xc1, 0x20, 0xb0, 0x70, 0xb2, 0x3b, 0xea,
- 0xb1, 0xe5, 0x0a, 0xfd, 0x56, 0x49, 0x5e, 0x39,
- 0x90, 0x91, 0xce, 0x04, 0x83, 0x29, 0xaa, 0xfd,
- 0x12, 0xa4, 0x42, 0x26, 0x6c, 0x6e, 0x79, 0x70,
- 0x77, 0x03, 0xb2, 0x07, 0x01, 0x3d, 0x85, 0x81,
- 0x95, 0x9e, 0xda, 0x5a, 0xa3, 0xf4, 0x2d, 0x38,
- 0x04, 0x58, 0xf5, 0x6b, 0xc9, 0xf1, 0xb5, 0x65,
- 0xfe, 0x66, 0x0d, 0xa2, 0xd5, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0x02, 0x81, 0x80, 0x5e, 0x01, 0x5f,
- 0xb6, 0x59, 0x1d, 0xdc, 0x36, 0xb6, 0x60, 0x36,
- 0xe6, 0x08, 0xdb, 0xd9, 0xcd, 0xc3, 0x8c, 0x16,
- 0x9c, 0x98, 0x8d, 0x7f, 0xd3, 0xdb, 0x1d, 0xaa,
- 0x68, 0x8f, 0xc5, 0xf8, 0xe2, 0x5d, 0xb3, 0x19,
- 0xc2, 0xc6, 0xf9, 0x51, 0x32, 0x1b, 0x93, 0x6a,
- 0xdc, 0x50, 0x8e, 0xeb, 0x61, 0x84, 0x03, 0x42,
- 0x30, 0x98, 0xb1, 0xf7, 0xbd, 0x14, 0x9a, 0x57,
- 0x36, 0x33, 0x09, 0xd4, 0x3e, 0x90, 0xda, 0xef,
- 0x09, 0x6e, 0xef, 0x49, 0xb6, 0x60, 0x68, 0x5e,
- 0x54, 0x17, 0x25, 0x5b, 0x37, 0xe3, 0x35, 0x63,
- 0x5b, 0x60, 0x3c, 0xbd, 0x50, 0xdf, 0x46, 0x43,
- 0x08, 0xa4, 0x71, 0x21, 0xf1, 0x30, 0x71, 0xdc,
- 0xda, 0xd7, 0x6f, 0xd2, 0x18, 0xbd, 0x39, 0xf1,
- 0xe1, 0xbe, 0xa8, 0x8d, 0x62, 0xdf, 0xa2, 0x3e,
- 0xb6, 0x15, 0x26, 0xb6, 0x57, 0xbd, 0x63, 0xdb,
- 0xc1, 0x91, 0xec, 0xb8, 0x01, 0x02, 0x41, 0x00,
- 0xc6, 0x1a, 0x06, 0x48, 0xf2, 0x12, 0x1c, 0x9f,
- 0x74, 0x20, 0x5c, 0x85, 0xa2, 0xda, 0xe5, 0x62,
- 0x96, 0x8d, 0x22, 0x7b, 0x78, 0x73, 0xea, 0xbb,
- 0x9f, 0x59, 0x42, 0x13, 0x15, 0xc8, 0x11, 0x50,
- 0x6c, 0x55, 0xf6, 0xdf, 0x8b, 0xfe, 0xc7, 0xdd,
- 0xa8, 0xca, 0x54, 0x41, 0xe8, 0xce, 0xbe, 0x7d,
- 0xbd, 0xe2, 0x13, 0x4b, 0x5b, 0x61, 0xeb, 0x69,
- 0x6c, 0xb1, 0x9b, 0x28, 0x68, 0x5b, 0xd6, 0x01,
- 0x02, 0x41, 0x00, 0xbd, 0x1e, 0xfe, 0x51, 0x99,
- 0xb6, 0xe3, 0x84, 0xfe, 0xf1, 0x9e, 0xfd, 0x9c,
- 0xe7, 0x86, 0x43, 0x68, 0x7f, 0x2f, 0x6a, 0x2a,
- 0x4c, 0xae, 0xa6, 0x41, 0x1c, 0xf0, 0x10, 0x37,
- 0x54, 0x23, 0xba, 0x05, 0x0d, 0x18, 0x27, 0x8d,
- 0xb8, 0xe4, 0x8f, 0xf2, 0x25, 0x73, 0x8a, 0xd7,
- 0x05, 0x98, 0x6b, 0x3d, 0x55, 0xb7, 0x6f, 0x7c,
- 0xec, 0x77, 0x61, 0x54, 0x7b, 0xb6, 0x6b, 0x31,
- 0xec, 0x94, 0xd5, 0x02, 0x41, 0x00, 0x90, 0xa2,
- 0xa5, 0x9e, 0x12, 0xa7, 0x68, 0xa0, 0x7e, 0xdf,
- 0xb5, 0xcd, 0x98, 0x26, 0xab, 0xbd, 0xbc, 0x5f,
- 0xd5, 0x22, 0x42, 0xc2, 0x97, 0x4a, 0x5f, 0x40,
- 0x82, 0xfe, 0x7e, 0x33, 0xb1, 0x78, 0x7f, 0x70,
- 0x90, 0x2b, 0x8d, 0x01, 0xfb, 0x18, 0xfa, 0x48,
- 0xa7, 0x15, 0xec, 0x0d, 0x2e, 0x85, 0x8d, 0xe2,
- 0x86, 0xe5, 0xc9, 0x15, 0x88, 0x14, 0x53, 0xd8,
- 0xa4, 0x88, 0xef, 0x10, 0xc6, 0x01, 0x02, 0x41,
- 0x00, 0xba, 0xe4, 0xaf, 0x14, 0xfa, 0xdf, 0xf6,
- 0xd5, 0xce, 0x8f, 0xfe, 0xbb, 0xc8, 0x5c, 0x30,
- 0x9d, 0xda, 0xdd, 0x9d, 0x80, 0xc0, 0x0e, 0x89,
- 0xa5, 0xb8, 0xc1, 0x1d, 0x28, 0x19, 0x55, 0x67,
- 0xfd, 0x03, 0xd2, 0xdd, 0xe4, 0xf0, 0xb4, 0x20,
- 0x03, 0x74, 0x9b, 0xb8, 0x24, 0x23, 0xbb, 0xde,
- 0xd5, 0x53, 0x86, 0xaa, 0xc1, 0x5d, 0x65, 0xdd,
- 0xcf, 0xec, 0x8a, 0x59, 0x4a, 0x73, 0xca, 0xc5,
- 0x85, 0x02, 0x40, 0x00, 0xc4, 0x5e, 0x8d, 0xa4,
- 0xea, 0xbb, 0x6a, 0x9b, 0xe6, 0x3a, 0x4d, 0xc1,
- 0xdb, 0xe5, 0x52, 0x38, 0xf9, 0x59, 0x91, 0x2d,
- 0x90, 0x82, 0xe3, 0x31, 0x1b, 0x48, 0xb7, 0x42,
- 0xfa, 0x1d, 0x83, 0xd5, 0x3d, 0x02, 0xc2, 0x12,
- 0x71, 0x10, 0x3a, 0xbd, 0x92, 0x8f, 0x9b, 0xa2,
- 0x6b, 0x2d, 0x21, 0xa4, 0x65, 0xe9, 0xfa, 0x8c,
- 0x30, 0x2a, 0x89, 0xce, 0xd0, 0xa7, 0x67, 0xd8,
+ 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x00, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+ 0x02, 0x61, 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01,
+ 0x00, 0x02, 0x81, 0x81, 0x00, 0x92, 0x59, 0x32,
+ 0x7d, 0x8e, 0xaf, 0x2e, 0xd5, 0xb2, 0x5c, 0x67,
+ 0xc8, 0x7d, 0x48, 0xb7, 0x84, 0x12, 0xd0, 0x76,
+ 0xda, 0xe1, 0xa3, 0x1e, 0x40, 0x01, 0x14, 0x5c,
+ 0xef, 0x26, 0x6e, 0x28, 0xa2, 0xf7, 0xa5, 0xb4,
+ 0x02, 0x37, 0xd0, 0x53, 0x10, 0xcb, 0x7c, 0x6a,
+ 0xf4, 0x53, 0x9f, 0xb8, 0xe0, 0x83, 0x93, 0xd1,
+ 0x19, 0xd8, 0x28, 0xd1, 0xd1, 0xd8, 0x87, 0x8f,
+ 0x92, 0xfd, 0x73, 0xc0, 0x4d, 0x3e, 0x07, 0x22,
+ 0x1f, 0xc1, 0x20, 0xb0, 0x70, 0xb2, 0x3b, 0xea,
+ 0xb1, 0xe5, 0x0a, 0xfd, 0x56, 0x49, 0x5e, 0x39,
+ 0x90, 0x91, 0xce, 0x04, 0x83, 0x29, 0xaa, 0xfd,
+ 0x12, 0xa4, 0x42, 0x26, 0x6c, 0x6e, 0x79, 0x70,
+ 0x77, 0x03, 0xb2, 0x07, 0x01, 0x3d, 0x85, 0x81,
+ 0x95, 0x9e, 0xda, 0x5a, 0xa3, 0xf4, 0x2d, 0x38,
+ 0x04, 0x58, 0xf5, 0x6b, 0xc9, 0xf1, 0xb5, 0x65,
+ 0xfe, 0x66, 0x0d, 0xa2, 0xd5, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0x02, 0x81, 0x80, 0x5e, 0x01, 0x5f,
+ 0xb6, 0x59, 0x1d, 0xdc, 0x36, 0xb6, 0x60, 0x36,
+ 0xe6, 0x08, 0xdb, 0xd9, 0xcd, 0xc3, 0x8c, 0x16,
+ 0x9c, 0x98, 0x8d, 0x7f, 0xd3, 0xdb, 0x1d, 0xaa,
+ 0x68, 0x8f, 0xc5, 0xf8, 0xe2, 0x5d, 0xb3, 0x19,
+ 0xc2, 0xc6, 0xf9, 0x51, 0x32, 0x1b, 0x93, 0x6a,
+ 0xdc, 0x50, 0x8e, 0xeb, 0x61, 0x84, 0x03, 0x42,
+ 0x30, 0x98, 0xb1, 0xf7, 0xbd, 0x14, 0x9a, 0x57,
+ 0x36, 0x33, 0x09, 0xd4, 0x3e, 0x90, 0xda, 0xef,
+ 0x09, 0x6e, 0xef, 0x49, 0xb6, 0x60, 0x68, 0x5e,
+ 0x54, 0x17, 0x25, 0x5b, 0x37, 0xe3, 0x35, 0x63,
+ 0x5b, 0x60, 0x3c, 0xbd, 0x50, 0xdf, 0x46, 0x43,
+ 0x08, 0xa4, 0x71, 0x21, 0xf1, 0x30, 0x71, 0xdc,
+ 0xda, 0xd7, 0x6f, 0xd2, 0x18, 0xbd, 0x39, 0xf1,
+ 0xe1, 0xbe, 0xa8, 0x8d, 0x62, 0xdf, 0xa2, 0x3e,
+ 0xb6, 0x15, 0x26, 0xb6, 0x57, 0xbd, 0x63, 0xdb,
+ 0xc1, 0x91, 0xec, 0xb8, 0x01, 0x02, 0x41, 0x00,
+ 0xc6, 0x1a, 0x06, 0x48, 0xf2, 0x12, 0x1c, 0x9f,
+ 0x74, 0x20, 0x5c, 0x85, 0xa2, 0xda, 0xe5, 0x62,
+ 0x96, 0x8d, 0x22, 0x7b, 0x78, 0x73, 0xea, 0xbb,
+ 0x9f, 0x59, 0x42, 0x13, 0x15, 0xc8, 0x11, 0x50,
+ 0x6c, 0x55, 0xf6, 0xdf, 0x8b, 0xfe, 0xc7, 0xdd,
+ 0xa8, 0xca, 0x54, 0x41, 0xe8, 0xce, 0xbe, 0x7d,
+ 0xbd, 0xe2, 0x13, 0x4b, 0x5b, 0x61, 0xeb, 0x69,
+ 0x6c, 0xb1, 0x9b, 0x28, 0x68, 0x5b, 0xd6, 0x01,
+ 0x02, 0x41, 0x00, 0xbd, 0x1e, 0xfe, 0x51, 0x99,
+ 0xb6, 0xe3, 0x84, 0xfe, 0xf1, 0x9e, 0xfd, 0x9c,
+ 0xe7, 0x86, 0x43, 0x68, 0x7f, 0x2f, 0x6a, 0x2a,
+ 0x4c, 0xae, 0xa6, 0x41, 0x1c, 0xf0, 0x10, 0x37,
+ 0x54, 0x23, 0xba, 0x05, 0x0d, 0x18, 0x27, 0x8d,
+ 0xb8, 0xe4, 0x8f, 0xf2, 0x25, 0x73, 0x8a, 0xd7,
+ 0x05, 0x98, 0x6b, 0x3d, 0x55, 0xb7, 0x6f, 0x7c,
+ 0xec, 0x77, 0x61, 0x54, 0x7b, 0xb6, 0x6b, 0x31,
+ 0xec, 0x94, 0xd5, 0x02, 0x41, 0x00, 0x90, 0xa2,
+ 0xa5, 0x9e, 0x12, 0xa7, 0x68, 0xa0, 0x7e, 0xdf,
+ 0xb5, 0xcd, 0x98, 0x26, 0xab, 0xbd, 0xbc, 0x5f,
+ 0xd5, 0x22, 0x42, 0xc2, 0x97, 0x4a, 0x5f, 0x40,
+ 0x82, 0xfe, 0x7e, 0x33, 0xb1, 0x78, 0x7f, 0x70,
+ 0x90, 0x2b, 0x8d, 0x01, 0xfb, 0x18, 0xfa, 0x48,
+ 0xa7, 0x15, 0xec, 0x0d, 0x2e, 0x85, 0x8d, 0xe2,
+ 0x86, 0xe5, 0xc9, 0x15, 0x88, 0x14, 0x53, 0xd8,
+ 0xa4, 0x88, 0xef, 0x10, 0xc6, 0x01, 0x02, 0x41,
+ 0x00, 0xba, 0xe4, 0xaf, 0x14, 0xfa, 0xdf, 0xf6,
+ 0xd5, 0xce, 0x8f, 0xfe, 0xbb, 0xc8, 0x5c, 0x30,
+ 0x9d, 0xda, 0xdd, 0x9d, 0x80, 0xc0, 0x0e, 0x89,
+ 0xa5, 0xb8, 0xc1, 0x1d, 0x28, 0x19, 0x55, 0x67,
+ 0xfd, 0x03, 0xd2, 0xdd, 0xe4, 0xf0, 0xb4, 0x20,
+ 0x03, 0x74, 0x9b, 0xb8, 0x24, 0x23, 0xbb, 0xde,
+ 0xd5, 0x53, 0x86, 0xaa, 0xc1, 0x5d, 0x65, 0xdd,
+ 0xcf, 0xec, 0x8a, 0x59, 0x4a, 0x73, 0xca, 0xc5,
+ 0x85, 0x02, 0x40, 0x00, 0xc4, 0x5e, 0x8d, 0xa4,
+ 0xea, 0xbb, 0x6a, 0x9b, 0xe6, 0x3a, 0x4d, 0xc1,
+ 0xdb, 0xe5, 0x52, 0x38, 0xf9, 0x59, 0x91, 0x2d,
+ 0x90, 0x82, 0xe3, 0x31, 0x1b, 0x48, 0xb7, 0x42,
+ 0xfa, 0x1d, 0x83, 0xd5, 0x3d, 0x02, 0xc2, 0x12,
+ 0x71, 0x10, 0x3a, 0xbd, 0x92, 0x8f, 0x9b, 0xa2,
+ 0x6b, 0x2d, 0x21, 0xa4, 0x65, 0xe9, 0xfa, 0x8c,
+ 0x30, 0x2a, 0x89, 0xce, 0xd0, 0xa7, 0x67, 0xd8,
0x45, 0x84, 0xb0
};
const uint8 short_integer_without_high_bit[] = {
- 0x30, 0x82, 0x02, 0x76, 0x02, 0x01, 0x00, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
- 0x02, 0x60, 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01,
- 0x00, 0x02, 0x81, 0x81, 0x00, 0xc3, 0x9e, 0x8d,
- 0xc4, 0x6d, 0x38, 0xe8, 0x0e, 0x9f, 0x84, 0x03,
- 0x40, 0x8e, 0x81, 0x2e, 0x56, 0x67, 0x78, 0x11,
- 0x85, 0x27, 0x81, 0x52, 0xf2, 0x1b, 0x3e, 0x5b,
- 0xf8, 0xab, 0xfc, 0xaf, 0xca, 0x5c, 0x26, 0xd5,
- 0xfa, 0xd4, 0x55, 0x50, 0x38, 0xb9, 0x9d, 0x89,
- 0x92, 0x7e, 0x34, 0xcf, 0x37, 0x82, 0x48, 0x2d,
- 0xaa, 0xc4, 0x6a, 0x0e, 0x93, 0xea, 0xad, 0x8a,
- 0x33, 0xf0, 0x42, 0x23, 0xe0, 0x4c, 0x98, 0xbf,
- 0x01, 0x00, 0x1b, 0xfe, 0x06, 0x15, 0xc6, 0xe3,
- 0x80, 0x79, 0x6d, 0xfe, 0x48, 0xcd, 0x40, 0xbb,
- 0xf9, 0x58, 0xe6, 0xbf, 0xd5, 0x4c, 0x29, 0x48,
- 0x53, 0x78, 0x06, 0x03, 0x0d, 0x59, 0xf5, 0x20,
- 0xe0, 0xe6, 0x8c, 0xb2, 0xf5, 0xd8, 0x61, 0x52,
- 0x7e, 0x40, 0x83, 0xd7, 0x69, 0xae, 0xd7, 0x75,
- 0x02, 0x2d, 0x49, 0xd5, 0x15, 0x5b, 0xf1, 0xd9,
- 0x4d, 0x60, 0x7d, 0x62, 0xa5, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0x02, 0x7f, 0x6d, 0x45, 0x23, 0xeb,
- 0x95, 0x17, 0x34, 0x88, 0xf6, 0x91, 0xc7, 0x3f,
- 0x48, 0x5a, 0xe0, 0x87, 0x63, 0x44, 0xae, 0x84,
- 0xb2, 0x8c, 0x8a, 0xc8, 0xb2, 0x6f, 0x22, 0xf0,
- 0xc5, 0x21, 0x61, 0x10, 0xa8, 0x69, 0x09, 0x1e,
- 0x13, 0x7d, 0x94, 0x52, 0x1b, 0x5c, 0xe4, 0x7b,
- 0xf0, 0x03, 0x8f, 0xbc, 0x72, 0x09, 0xdf, 0x78,
- 0x84, 0x3e, 0xb9, 0xe5, 0xe6, 0x31, 0x0a, 0x01,
- 0xf9, 0x32, 0xf8, 0xd6, 0x57, 0xa3, 0x87, 0xe6,
- 0xf5, 0x98, 0xbc, 0x8e, 0x41, 0xb9, 0x50, 0x17,
- 0x7b, 0xd3, 0x97, 0x5a, 0x44, 0x3a, 0xee, 0xff,
- 0x6b, 0xb3, 0x3a, 0x52, 0xe7, 0xa4, 0x96, 0x9a,
- 0xf6, 0x83, 0xc8, 0x97, 0x1c, 0x63, 0xa1, 0xd6,
- 0xb3, 0xa8, 0xb2, 0xc7, 0x73, 0x25, 0x0f, 0x58,
- 0x36, 0xb9, 0x7a, 0x47, 0xa7, 0x4d, 0x30, 0xfe,
- 0x4d, 0x74, 0x56, 0xe8, 0xfb, 0xd6, 0x50, 0xe5,
- 0xe0, 0x28, 0x15, 0x02, 0x41, 0x00, 0xeb, 0x15,
- 0x62, 0xb6, 0x37, 0x41, 0x7c, 0xc5, 0x00, 0x22,
- 0x2c, 0x5a, 0x5e, 0xe4, 0xb2, 0x11, 0x87, 0x89,
- 0xad, 0xf4, 0x57, 0x68, 0x90, 0xb7, 0x9f, 0xe2,
- 0x79, 0x20, 0x6b, 0x98, 0x00, 0x0d, 0x3a, 0x3b,
- 0xc1, 0xcd, 0x36, 0xf9, 0x27, 0xda, 0x40, 0x36,
- 0x1d, 0xb8, 0x5c, 0x96, 0xeb, 0x04, 0x08, 0xe1,
- 0x3f, 0xfa, 0x94, 0x8b, 0x0f, 0xa0, 0xff, 0xc1,
- 0x51, 0xea, 0x90, 0xad, 0x15, 0xc7, 0x02, 0x41,
- 0x00, 0xd5, 0x06, 0x45, 0xd7, 0x55, 0x63, 0x1a,
- 0xf0, 0x89, 0x81, 0xae, 0x87, 0x23, 0xa2, 0x39,
- 0xfe, 0x3d, 0x82, 0xc7, 0xcb, 0x15, 0xb9, 0xe3,
- 0xe2, 0x5b, 0xc6, 0xd2, 0x55, 0xdd, 0xab, 0x55,
- 0x29, 0x7c, 0xda, 0x0e, 0x1c, 0x09, 0xfc, 0x73,
- 0x0d, 0x01, 0xed, 0x6d, 0x2f, 0x05, 0xd0, 0xd5,
- 0x1d, 0xce, 0x18, 0x7f, 0xb0, 0xc8, 0x47, 0x77,
- 0xd2, 0xa9, 0x9e, 0xfc, 0x39, 0x4b, 0x3d, 0x94,
- 0x33, 0x02, 0x41, 0x00, 0x8f, 0x94, 0x09, 0x2d,
- 0x17, 0x44, 0x75, 0x0a, 0xf1, 0x10, 0xee, 0x1b,
- 0xe7, 0xd7, 0x2f, 0xf6, 0xca, 0xdc, 0x49, 0x15,
- 0x72, 0x09, 0x58, 0x51, 0xfe, 0x61, 0xd8, 0xee,
- 0xf7, 0x27, 0xe7, 0xe8, 0x2c, 0x47, 0xf1, 0x0f,
- 0x00, 0x63, 0x5e, 0x76, 0xcb, 0x3f, 0x02, 0x19,
- 0xe6, 0xda, 0xfa, 0x01, 0x05, 0xd7, 0x65, 0x37,
- 0x0b, 0x60, 0x7f, 0x94, 0x2a, 0x80, 0x8d, 0x22,
- 0x81, 0x68, 0x65, 0x63, 0x02, 0x41, 0x00, 0xc2,
- 0xd4, 0x18, 0xde, 0x47, 0x9e, 0xfb, 0x8d, 0x91,
- 0x05, 0xc5, 0x3c, 0x9d, 0xcf, 0x8a, 0x60, 0xc7,
- 0x9b, 0x2b, 0xe5, 0xc6, 0xba, 0x1b, 0xfc, 0xf3,
- 0xd9, 0x54, 0x97, 0xe9, 0xc4, 0x00, 0x80, 0x90,
- 0x4a, 0xd2, 0x6a, 0xbc, 0x8b, 0x62, 0x22, 0x3c,
- 0x68, 0x0c, 0xda, 0xdb, 0xe3, 0xd2, 0x76, 0x8e,
- 0xff, 0x03, 0x12, 0x09, 0x2a, 0xac, 0x21, 0x44,
- 0xb7, 0x3e, 0x91, 0x9c, 0x09, 0xf6, 0xd7, 0x02,
- 0x41, 0x00, 0xc0, 0xa1, 0xbb, 0x70, 0xdc, 0xf8,
- 0xeb, 0x17, 0x61, 0xd4, 0x8c, 0x7c, 0x3b, 0x82,
- 0x91, 0x58, 0xff, 0xf9, 0x19, 0xac, 0x3a, 0x73,
- 0xa7, 0x20, 0xe5, 0x22, 0x02, 0xc4, 0xf6, 0xb9,
- 0xb9, 0x43, 0x53, 0x35, 0x88, 0xe1, 0x05, 0xb6,
- 0x43, 0x9b, 0x39, 0xc8, 0x04, 0x4d, 0x2b, 0x01,
- 0xf7, 0xe6, 0x1b, 0x8d, 0x7e, 0x89, 0xe3, 0x43,
- 0xd4, 0xf3, 0xab, 0x28, 0xd4, 0x5a, 0x1f, 0x20,
+ 0x30, 0x82, 0x02, 0x76, 0x02, 0x01, 0x00, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+ 0x02, 0x60, 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01,
+ 0x00, 0x02, 0x81, 0x81, 0x00, 0xc3, 0x9e, 0x8d,
+ 0xc4, 0x6d, 0x38, 0xe8, 0x0e, 0x9f, 0x84, 0x03,
+ 0x40, 0x8e, 0x81, 0x2e, 0x56, 0x67, 0x78, 0x11,
+ 0x85, 0x27, 0x81, 0x52, 0xf2, 0x1b, 0x3e, 0x5b,
+ 0xf8, 0xab, 0xfc, 0xaf, 0xca, 0x5c, 0x26, 0xd5,
+ 0xfa, 0xd4, 0x55, 0x50, 0x38, 0xb9, 0x9d, 0x89,
+ 0x92, 0x7e, 0x34, 0xcf, 0x37, 0x82, 0x48, 0x2d,
+ 0xaa, 0xc4, 0x6a, 0x0e, 0x93, 0xea, 0xad, 0x8a,
+ 0x33, 0xf0, 0x42, 0x23, 0xe0, 0x4c, 0x98, 0xbf,
+ 0x01, 0x00, 0x1b, 0xfe, 0x06, 0x15, 0xc6, 0xe3,
+ 0x80, 0x79, 0x6d, 0xfe, 0x48, 0xcd, 0x40, 0xbb,
+ 0xf9, 0x58, 0xe6, 0xbf, 0xd5, 0x4c, 0x29, 0x48,
+ 0x53, 0x78, 0x06, 0x03, 0x0d, 0x59, 0xf5, 0x20,
+ 0xe0, 0xe6, 0x8c, 0xb2, 0xf5, 0xd8, 0x61, 0x52,
+ 0x7e, 0x40, 0x83, 0xd7, 0x69, 0xae, 0xd7, 0x75,
+ 0x02, 0x2d, 0x49, 0xd5, 0x15, 0x5b, 0xf1, 0xd9,
+ 0x4d, 0x60, 0x7d, 0x62, 0xa5, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0x02, 0x7f, 0x6d, 0x45, 0x23, 0xeb,
+ 0x95, 0x17, 0x34, 0x88, 0xf6, 0x91, 0xc7, 0x3f,
+ 0x48, 0x5a, 0xe0, 0x87, 0x63, 0x44, 0xae, 0x84,
+ 0xb2, 0x8c, 0x8a, 0xc8, 0xb2, 0x6f, 0x22, 0xf0,
+ 0xc5, 0x21, 0x61, 0x10, 0xa8, 0x69, 0x09, 0x1e,
+ 0x13, 0x7d, 0x94, 0x52, 0x1b, 0x5c, 0xe4, 0x7b,
+ 0xf0, 0x03, 0x8f, 0xbc, 0x72, 0x09, 0xdf, 0x78,
+ 0x84, 0x3e, 0xb9, 0xe5, 0xe6, 0x31, 0x0a, 0x01,
+ 0xf9, 0x32, 0xf8, 0xd6, 0x57, 0xa3, 0x87, 0xe6,
+ 0xf5, 0x98, 0xbc, 0x8e, 0x41, 0xb9, 0x50, 0x17,
+ 0x7b, 0xd3, 0x97, 0x5a, 0x44, 0x3a, 0xee, 0xff,
+ 0x6b, 0xb3, 0x3a, 0x52, 0xe7, 0xa4, 0x96, 0x9a,
+ 0xf6, 0x83, 0xc8, 0x97, 0x1c, 0x63, 0xa1, 0xd6,
+ 0xb3, 0xa8, 0xb2, 0xc7, 0x73, 0x25, 0x0f, 0x58,
+ 0x36, 0xb9, 0x7a, 0x47, 0xa7, 0x4d, 0x30, 0xfe,
+ 0x4d, 0x74, 0x56, 0xe8, 0xfb, 0xd6, 0x50, 0xe5,
+ 0xe0, 0x28, 0x15, 0x02, 0x41, 0x00, 0xeb, 0x15,
+ 0x62, 0xb6, 0x37, 0x41, 0x7c, 0xc5, 0x00, 0x22,
+ 0x2c, 0x5a, 0x5e, 0xe4, 0xb2, 0x11, 0x87, 0x89,
+ 0xad, 0xf4, 0x57, 0x68, 0x90, 0xb7, 0x9f, 0xe2,
+ 0x79, 0x20, 0x6b, 0x98, 0x00, 0x0d, 0x3a, 0x3b,
+ 0xc1, 0xcd, 0x36, 0xf9, 0x27, 0xda, 0x40, 0x36,
+ 0x1d, 0xb8, 0x5c, 0x96, 0xeb, 0x04, 0x08, 0xe1,
+ 0x3f, 0xfa, 0x94, 0x8b, 0x0f, 0xa0, 0xff, 0xc1,
+ 0x51, 0xea, 0x90, 0xad, 0x15, 0xc7, 0x02, 0x41,
+ 0x00, 0xd5, 0x06, 0x45, 0xd7, 0x55, 0x63, 0x1a,
+ 0xf0, 0x89, 0x81, 0xae, 0x87, 0x23, 0xa2, 0x39,
+ 0xfe, 0x3d, 0x82, 0xc7, 0xcb, 0x15, 0xb9, 0xe3,
+ 0xe2, 0x5b, 0xc6, 0xd2, 0x55, 0xdd, 0xab, 0x55,
+ 0x29, 0x7c, 0xda, 0x0e, 0x1c, 0x09, 0xfc, 0x73,
+ 0x0d, 0x01, 0xed, 0x6d, 0x2f, 0x05, 0xd0, 0xd5,
+ 0x1d, 0xce, 0x18, 0x7f, 0xb0, 0xc8, 0x47, 0x77,
+ 0xd2, 0xa9, 0x9e, 0xfc, 0x39, 0x4b, 0x3d, 0x94,
+ 0x33, 0x02, 0x41, 0x00, 0x8f, 0x94, 0x09, 0x2d,
+ 0x17, 0x44, 0x75, 0x0a, 0xf1, 0x10, 0xee, 0x1b,
+ 0xe7, 0xd7, 0x2f, 0xf6, 0xca, 0xdc, 0x49, 0x15,
+ 0x72, 0x09, 0x58, 0x51, 0xfe, 0x61, 0xd8, 0xee,
+ 0xf7, 0x27, 0xe7, 0xe8, 0x2c, 0x47, 0xf1, 0x0f,
+ 0x00, 0x63, 0x5e, 0x76, 0xcb, 0x3f, 0x02, 0x19,
+ 0xe6, 0xda, 0xfa, 0x01, 0x05, 0xd7, 0x65, 0x37,
+ 0x0b, 0x60, 0x7f, 0x94, 0x2a, 0x80, 0x8d, 0x22,
+ 0x81, 0x68, 0x65, 0x63, 0x02, 0x41, 0x00, 0xc2,
+ 0xd4, 0x18, 0xde, 0x47, 0x9e, 0xfb, 0x8d, 0x91,
+ 0x05, 0xc5, 0x3c, 0x9d, 0xcf, 0x8a, 0x60, 0xc7,
+ 0x9b, 0x2b, 0xe5, 0xc6, 0xba, 0x1b, 0xfc, 0xf3,
+ 0xd9, 0x54, 0x97, 0xe9, 0xc4, 0x00, 0x80, 0x90,
+ 0x4a, 0xd2, 0x6a, 0xbc, 0x8b, 0x62, 0x22, 0x3c,
+ 0x68, 0x0c, 0xda, 0xdb, 0xe3, 0xd2, 0x76, 0x8e,
+ 0xff, 0x03, 0x12, 0x09, 0x2a, 0xac, 0x21, 0x44,
+ 0xb7, 0x3e, 0x91, 0x9c, 0x09, 0xf6, 0xd7, 0x02,
+ 0x41, 0x00, 0xc0, 0xa1, 0xbb, 0x70, 0xdc, 0xf8,
+ 0xeb, 0x17, 0x61, 0xd4, 0x8c, 0x7c, 0x3b, 0x82,
+ 0x91, 0x58, 0xff, 0xf9, 0x19, 0xac, 0x3a, 0x73,
+ 0xa7, 0x20, 0xe5, 0x22, 0x02, 0xc4, 0xf6, 0xb9,
+ 0xb9, 0x43, 0x53, 0x35, 0x88, 0xe1, 0x05, 0xb6,
+ 0x43, 0x9b, 0x39, 0xc8, 0x04, 0x4d, 0x2b, 0x01,
+ 0xf7, 0xe6, 0x1b, 0x8d, 0x7e, 0x89, 0xe3, 0x43,
+ 0xd4, 0xf3, 0xab, 0x28, 0xd4, 0x5a, 0x1f, 0x20,
0xea, 0xbe
};
@@ -403,3 +403,30 @@ TEST(RSAPrivateKeyUnitTest, ShortIntegers) {
ASSERT_TRUE(0 == memcmp(&output2.front(), &input2.front(),
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));
+
+ scoped_ptr<crypto::RSAPrivateKey> key_copy(
+ crypto::RSAPrivateKey::CreateFromKey(key_pair->key()));
+ ASSERT_TRUE(key_copy.get());
+
+ std::vector<uint8> privkey;
+ std::vector<uint8> pubkey;
+ ASSERT_TRUE(key_pair->ExportPrivateKey(&privkey));
+ ASSERT_TRUE(key_pair->ExportPublicKey(&pubkey));
+
+ std::vector<uint8> privkey_copy;
+ std::vector<uint8> pubkey_copy;
+ ASSERT_TRUE(key_copy->ExportPrivateKey(&privkey_copy));
+ ASSERT_TRUE(key_copy->ExportPublicKey(&pubkey_copy));
+
+ ASSERT_EQ(privkey, privkey_copy);
+ ASSERT_EQ(pubkey, pubkey_copy);
+}
+#endif
+
diff --git a/chromium/crypto/scoped_capi_types.h b/chromium/crypto/scoped_capi_types.h
index 9ab28d9aacc..ac92e394b9c 100644
--- a/chromium/crypto/scoped_capi_types.h
+++ b/chromium/crypto/scoped_capi_types.h
@@ -6,11 +6,11 @@
#define CRYPTO_SCOPED_CAPI_TYPES_H_
#include <windows.h>
-#include <wincrypt.h>
#include <algorithm>
#include "base/logging.h"
+#include "crypto/wincrypt_shim.h"
namespace crypto {
diff --git a/chromium/crypto/scoped_nss_types.h b/chromium/crypto/scoped_nss_types.h
index d5aebc5dd20..fdfb83c154f 100644
--- a/chromium/crypto/scoped_nss_types.h
+++ b/chromium/crypto/scoped_nss_types.h
@@ -16,17 +16,17 @@ namespace crypto {
template <typename Type, void (*Destroyer)(Type*)>
struct NSSDestroyer {
+ typedef void AllowSelfReset;
void operator()(Type* ptr) const {
- if (ptr)
- Destroyer(ptr);
+ Destroyer(ptr);
}
};
template <typename Type, void (*Destroyer)(Type*, PRBool), PRBool freeit>
struct NSSDestroyer1 {
+ typedef void AllowSelfReset;
void operator()(Type* ptr) const {
- if (ptr)
- Destroyer(ptr, freeit);
+ Destroyer(ptr, freeit);
}
};
diff --git a/chromium/crypto/scoped_openssl_types.h b/chromium/crypto/scoped_openssl_types.h
new file mode 100644
index 00000000000..cc056e49efe
--- /dev/null
+++ b/chromium/crypto/scoped_openssl_types.h
@@ -0,0 +1,59 @@
+// Copyright 2014 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_SCOPED_OPENSSL_TYPES_H_
+#define CRYPTO_SCOPED_OPENSSL_TYPES_H_
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+
+#include "base/memory/scoped_ptr.h"
+
+namespace crypto {
+
+// Simplistic helper that wraps a call to a deleter function. In a C++11 world,
+// this would be std::function<>. An alternative would be to re-use
+// base::internal::RunnableAdapter<>, but that's far too heavy weight.
+template <typename Type, void (*Destroyer)(Type*)>
+struct OpenSSLDestroyer {
+ typedef void AllowSelfReset;
+ void operator()(Type* ptr) const { Destroyer(ptr); }
+};
+
+template <typename PointerType, void (*Destroyer)(PointerType*)>
+struct ScopedOpenSSL {
+ typedef scoped_ptr<PointerType, OpenSSLDestroyer<PointerType, Destroyer> >
+ Type;
+};
+
+struct OpenSSLFree {
+ void operator()(uint8_t* ptr) const { OPENSSL_free(ptr); }
+};
+
+// Several typedefs are provided for crypto-specific primitives, for
+// 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;
+
+// The bytes must have been allocated with OPENSSL_malloc.
+typedef scoped_ptr<uint8_t, OpenSSLFree> ScopedOpenSSLBytes;
+
+} // namespace crypto
+
+#endif // CRYPTO_SCOPED_OPENSSL_TYPES_H_
diff --git a/chromium/crypto/scoped_test_nss_chromeos_user.cc b/chromium/crypto/scoped_test_nss_chromeos_user.cc
new file mode 100644
index 00000000000..aec25d8dff0
--- /dev/null
+++ b/chromium/crypto/scoped_test_nss_chromeos_user.cc
@@ -0,0 +1,37 @@
+// Copyright 2014 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/scoped_test_nss_chromeos_user.h"
+
+#include "base/logging.h"
+#include "crypto/nss_util.h"
+#include "crypto/nss_util_internal.h"
+
+namespace crypto {
+
+ScopedTestNSSChromeOSUser::ScopedTestNSSChromeOSUser(
+ const std::string& username_hash)
+ : username_hash_(username_hash), constructed_successfully_(false) {
+ if (!temp_dir_.CreateUniqueTempDir())
+ return;
+ // This opens a software DB in the given folder. In production code that is in
+ // the home folder, but for testing the temp folder is used.
+ constructed_successfully_ =
+ InitializeNSSForChromeOSUser(username_hash, temp_dir_.path());
+}
+
+ScopedTestNSSChromeOSUser::~ScopedTestNSSChromeOSUser() {
+ if (constructed_successfully_)
+ CloseChromeOSUserForTesting(username_hash_);
+}
+
+void ScopedTestNSSChromeOSUser::FinishInit() {
+ DCHECK(constructed_successfully_);
+ if (!ShouldInitializeTPMForChromeOSUser(username_hash_))
+ return;
+ WillInitializeTPMForChromeOSUser(username_hash_);
+ InitializePrivateSoftwareSlotForChromeOSUser(username_hash_);
+}
+
+} // namespace crypto
diff --git a/chromium/crypto/scoped_test_nss_chromeos_user.h b/chromium/crypto/scoped_test_nss_chromeos_user.h
new file mode 100644
index 00000000000..1638517704d
--- /dev/null
+++ b/chromium/crypto/scoped_test_nss_chromeos_user.h
@@ -0,0 +1,43 @@
+// Copyright 2014 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_SCOPED_TEST_NSS_CHROMEOS_USER_H_
+#define CRYPTO_SCOPED_TEST_NSS_CHROMEOS_USER_H_
+
+#include <string>
+
+#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
+#include "crypto/crypto_export.h"
+
+namespace crypto {
+
+// Opens a persistent NSS software database in a temporary directory for the
+// user with |username_hash|. This database will be used for both the user's
+// public and private slot.
+class CRYPTO_EXPORT_PRIVATE ScopedTestNSSChromeOSUser {
+ public:
+ // Opens the software database and sets the public slot for the user. The
+ // private slot will not be initialized until FinishInit() is called.
+ explicit ScopedTestNSSChromeOSUser(const std::string& username_hash);
+ ~ScopedTestNSSChromeOSUser();
+
+ std::string username_hash() const { return username_hash_; }
+ bool constructed_successfully() const { return constructed_successfully_; }
+
+ // Completes initialization of user. Causes any waiting private slot callbacks
+ // to run, see GetPrivateSlotForChromeOSUser().
+ void FinishInit();
+
+ private:
+ const std::string username_hash_;
+ base::ScopedTempDir temp_dir_;
+ bool constructed_successfully_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedTestNSSChromeOSUser);
+};
+
+} // namespace crypto
+
+#endif // CRYPTO_SCOPED_TEST_NSS_CHROMEOS_USER_H_
diff --git a/chromium/crypto/scoped_test_nss_db.cc b/chromium/crypto/scoped_test_nss_db.cc
new file mode 100644
index 00000000000..452c26d73e5
--- /dev/null
+++ b/chromium/crypto/scoped_test_nss_db.cc
@@ -0,0 +1,53 @@
+// Copyright 2014 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/scoped_test_nss_db.h"
+
+#include "base/logging.h"
+#include "base/threading/thread_restrictions.h"
+#include "crypto/nss_util.h"
+#include "crypto/nss_util_internal.h"
+
+namespace crypto {
+
+ScopedTestNSSDB::ScopedTestNSSDB() {
+ EnsureNSSInit();
+ // NSS is allowed to do IO on the current thread since dispatching
+ // to a dedicated thread would still have the affect of blocking
+ // the current thread, due to NSS's internal locking requirements
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+
+ if (!temp_dir_.CreateUniqueTempDir())
+ return;
+
+ const char kTestDescription[] = "Test DB";
+ slot_ = OpenSoftwareNSSDB(temp_dir_.path(), kTestDescription);
+}
+
+ScopedTestNSSDB::~ScopedTestNSSDB() {
+ // Don't close when NSS is < 3.15.1, because it would require an additional
+ // sleep for 1 second after closing the database, due to
+ // http://bugzil.la/875601.
+ if (!NSS_VersionCheck("3.15.1")) {
+ LOG(ERROR) << "NSS version is < 3.15.1, test DB will not be closed.";
+ temp_dir_.Take();
+ return;
+ }
+
+ // NSS is allowed to do IO on the current thread since dispatching
+ // to a dedicated thread would still have the affect of blocking
+ // the current thread, due to NSS's internal locking requirements
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+
+ if (slot_) {
+ SECStatus status = SECMOD_CloseUserDB(slot_.get());
+ if (status != SECSuccess)
+ PLOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError();
+ }
+
+ if (!temp_dir_.Delete())
+ LOG(ERROR) << "Could not delete temporary directory.";
+}
+
+} // namespace crypto
diff --git a/chromium/crypto/scoped_test_nss_db.h b/chromium/crypto/scoped_test_nss_db.h
new file mode 100644
index 00000000000..88c2d55dbe4
--- /dev/null
+++ b/chromium/crypto/scoped_test_nss_db.h
@@ -0,0 +1,35 @@
+// Copyright 2014 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_SCOPED_TEST_NSS_DB_H_
+#define CRYPTO_SCOPED_TEST_NSS_DB_H_
+
+#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
+#include "crypto/crypto_export.h"
+#include "crypto/scoped_nss_types.h"
+
+namespace crypto {
+
+// Opens a persistent NSS database in a temporary directory.
+// Prior NSS version 3.15.1, because of http://bugzil.la/875601 , the opened DB
+// will not be closed automatically.
+class CRYPTO_EXPORT_PRIVATE ScopedTestNSSDB {
+ public:
+ ScopedTestNSSDB();
+ ~ScopedTestNSSDB();
+
+ bool is_open() const { return slot_; }
+ PK11SlotInfo* slot() const { return slot_.get(); }
+
+ private:
+ base::ScopedTempDir temp_dir_;
+ ScopedPK11Slot slot_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedTestNSSDB);
+};
+
+} // namespace crypto
+
+#endif // CRYPTO_SCOPED_TEST_NSS_DB_H_
diff --git a/chromium/crypto/scoped_test_system_nss_key_slot.cc b/chromium/crypto/scoped_test_system_nss_key_slot.cc
new file mode 100644
index 00000000000..53fbbffc1a9
--- /dev/null
+++ b/chromium/crypto/scoped_test_system_nss_key_slot.cc
@@ -0,0 +1,32 @@
+// Copyright 2014 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/scoped_test_system_nss_key_slot.h"
+
+#include "crypto/nss_util_internal.h"
+#include "crypto/scoped_test_nss_db.h"
+
+namespace crypto {
+
+ScopedTestSystemNSSKeySlot::ScopedTestSystemNSSKeySlot()
+ : test_db_(new ScopedTestNSSDB) {
+ if (!test_db_->is_open())
+ return;
+ SetSystemKeySlotForTesting(
+ ScopedPK11Slot(PK11_ReferenceSlot(test_db_->slot())));
+}
+
+ScopedTestSystemNSSKeySlot::~ScopedTestSystemNSSKeySlot() {
+ SetSystemKeySlotForTesting(ScopedPK11Slot());
+}
+
+bool ScopedTestSystemNSSKeySlot::ConstructedSuccessfully() const {
+ return test_db_->is_open();
+}
+
+PK11SlotInfo* ScopedTestSystemNSSKeySlot::slot() const {
+ return test_db_->slot();
+}
+
+} // namespace crypto
diff --git a/chromium/crypto/scoped_test_system_nss_key_slot.h b/chromium/crypto/scoped_test_system_nss_key_slot.h
new file mode 100644
index 00000000000..ac3b72c4ce0
--- /dev/null
+++ b/chromium/crypto/scoped_test_system_nss_key_slot.h
@@ -0,0 +1,43 @@
+// Copyright 2014 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_SCOPED_TEST_SYSTEM_NSS_KEY_SLOT_H_
+#define CRYPTO_SCOPED_TEST_SYSTEM_NSS_KEY_SLOT_H_
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "crypto/crypto_export.h"
+
+// Forward declaration, from <pk11pub.h>
+typedef struct PK11SlotInfoStr PK11SlotInfo;
+
+namespace crypto {
+
+class ScopedTestNSSDB;
+
+// Opens a persistent NSS software database in a temporary directory and sets
+// the test system slot to the opened database. This helper should be created in
+// tests to fake the system token that is usually provided by the Chaps module.
+// |slot| is exposed through |GetSystemNSSKeySlot| and |IsTPMTokenReady| will
+// return true.
+// |InitializeTPMTokenAndSystemSlot|, which triggers the TPM initialization,
+// does not have to be called if this helper is used.
+// At most one instance of this helper must be used at a time.
+class CRYPTO_EXPORT_PRIVATE ScopedTestSystemNSSKeySlot {
+ public:
+ explicit ScopedTestSystemNSSKeySlot();
+ ~ScopedTestSystemNSSKeySlot();
+
+ bool ConstructedSuccessfully() const;
+ PK11SlotInfo* slot() const;
+
+ private:
+ scoped_ptr<ScopedTestNSSDB> test_db_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedTestSystemNSSKeySlot);
+};
+
+} // namespace crypto
+
+#endif // CRYPTO_SCOPED_TEST_SYSTEM_NSS_KEY_SLOT_H_
diff --git a/chromium/crypto/secure_hash_default.cc b/chromium/crypto/secure_hash_default.cc
index 7b912e1af60..1f5e59ba2ab 100644
--- a/chromium/crypto/secure_hash_default.cc
+++ b/chromium/crypto/secure_hash_default.cc
@@ -28,17 +28,17 @@ class SecureHashSHA256NSS : public SecureHash {
}
// SecureHash implementation:
- virtual void Update(const void* input, size_t len) OVERRIDE {
+ virtual 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 {
+ virtual 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;
+ virtual bool Serialize(Pickle* pickle) override;
+ virtual 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 84d28a52725..61946a8da81 100644
--- a/chromium/crypto/secure_hash_openssl.cc
+++ b/chromium/crypto/secure_hash_openssl.cc
@@ -30,18 +30,18 @@ class SecureHashSHA256OpenSSL : public SecureHash {
OPENSSL_cleanse(&ctx_, sizeof(ctx_));
}
- virtual void Update(const void* input, size_t len) OVERRIDE {
+ virtual 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 {
+ virtual 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;
+ virtual bool Serialize(Pickle* pickle) override;
+ virtual bool Deserialize(PickleIterator* data_iterator) override;
private:
SHA256_CTX ctx_;
diff --git a/chromium/crypto/secure_hash_unittest.cc b/chromium/crypto/secure_hash_unittest.cc
index 42b9ade3593..c21c365b1c2 100644
--- a/chromium/crypto/secure_hash_unittest.cc
+++ b/chromium/crypto/secure_hash_unittest.cc
@@ -4,6 +4,8 @@
#include "crypto/secure_hash.h"
+#include <string>
+
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/pickle.h"
diff --git a/chromium/crypto/signature_creator.h b/chromium/crypto/signature_creator.h
index 6074bcbe9cb..840d1ff0b80 100644
--- a/chromium/crypto/signature_creator.h
+++ b/chromium/crypto/signature_creator.h
@@ -5,10 +5,9 @@
#ifndef CRYPTO_SIGNATURE_CREATOR_H_
#define CRYPTO_SIGNATURE_CREATOR_H_
-#include "build/build_config.h"
-
#include <vector>
+#include "build/build_config.h"
#include "base/basictypes.h"
#include "crypto/crypto_export.h"
@@ -25,18 +24,27 @@ namespace crypto {
class RSAPrivateKey;
// Signs data using a bare private key (as opposed to a full certificate).
-// Currently can only sign data using SHA-1 with RSA encryption.
+// Currently can only sign data using SHA-1 or SHA-256 with RSA PKCS#1v1.5.
class CRYPTO_EXPORT SignatureCreator {
public:
+ // The set of supported hash functions. Extend as required.
+ enum HashAlgorithm {
+ SHA1,
+ SHA256,
+ };
+
~SignatureCreator();
// Create an instance. The caller must ensure that the provided PrivateKey
- // instance outlives the created SignatureCreator.
- static SignatureCreator* Create(RSAPrivateKey* key);
+ // instance outlives the created SignatureCreator. Uses the HashAlgorithm
+ // specified.
+ static SignatureCreator* Create(RSAPrivateKey* key, HashAlgorithm hash_alg);
+
- // Signs the precomputed SHA-1 digest |data| using private |key| as
+ // Signs the precomputed |hash_alg| digest |data| using private |key| as
// specified in PKCS #1 v1.5.
static bool Sign(RSAPrivateKey* key,
+ HashAlgorithm hash_alg,
const uint8* data,
int data_len,
std::vector<uint8>* signature);
diff --git a/chromium/crypto/signature_creator_nss.cc b/chromium/crypto/signature_creator_nss.cc
index bc8dc449a43..47728b07563 100644
--- a/chromium/crypto/signature_creator_nss.cc
+++ b/chromium/crypto/signature_creator_nss.cc
@@ -15,6 +15,30 @@
namespace crypto {
+namespace {
+
+SECOidTag ToNSSSigOid(SignatureCreator::HashAlgorithm hash_alg) {
+ switch (hash_alg) {
+ case SignatureCreator::SHA1:
+ return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
+ case SignatureCreator::SHA256:
+ return SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
+ }
+ return SEC_OID_UNKNOWN;
+}
+
+SECOidTag ToNSSHashOid(SignatureCreator::HashAlgorithm hash_alg) {
+ switch (hash_alg) {
+ case SignatureCreator::SHA1:
+ return SEC_OID_SHA1;
+ case SignatureCreator::SHA256:
+ return SEC_OID_SHA256;
+ }
+ return SEC_OID_UNKNOWN;
+}
+
+} // namespace
+
SignatureCreator::~SignatureCreator() {
if (sign_context_) {
SGN_DestroyContext(sign_context_, PR_TRUE);
@@ -23,12 +47,12 @@ SignatureCreator::~SignatureCreator() {
}
// static
-SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
+SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key,
+ HashAlgorithm hash_alg) {
scoped_ptr<SignatureCreator> result(new SignatureCreator);
result->key_ = key;
- result->sign_context_ = SGN_NewContext(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION,
- key->key());
+ result->sign_context_ = SGN_NewContext(ToNSSSigOid(hash_alg), key->key());
if (!result->sign_context_) {
NOTREACHED();
return NULL;
@@ -45,6 +69,7 @@ SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
// static
bool SignatureCreator::Sign(RSAPrivateKey* key,
+ HashAlgorithm hash_alg,
const uint8* data,
int data_len,
std::vector<uint8>* signature) {
@@ -54,7 +79,7 @@ bool SignatureCreator::Sign(RSAPrivateKey* key,
data_item.len = data_len;
SECItem signature_item;
- SECStatus rv = SGN_Digest(key->key(), SEC_OID_SHA1, &signature_item,
+ SECStatus rv = SGN_Digest(key->key(), ToNSSHashOid(hash_alg), &signature_item,
&data_item);
if (rv != SECSuccess) {
NOTREACHED();
diff --git a/chromium/crypto/signature_creator_openssl.cc b/chromium/crypto/signature_creator_openssl.cc
index e46d3d002c1..7a1349b5a5a 100644
--- a/chromium/crypto/signature_creator_openssl.cc
+++ b/chromium/crypto/signature_creator_openssl.cc
@@ -12,33 +12,64 @@
#include "base/stl_util.h"
#include "crypto/openssl_util.h"
#include "crypto/rsa_private_key.h"
+#include "crypto/scoped_openssl_types.h"
namespace crypto {
+namespace {
+
+const EVP_MD* ToOpenSSLDigest(SignatureCreator::HashAlgorithm hash_alg) {
+ switch (hash_alg) {
+ case SignatureCreator::SHA1:
+ return EVP_sha1();
+ case SignatureCreator::SHA256:
+ return EVP_sha256();
+ }
+ return NULL;
+}
+
+int ToOpenSSLDigestType(SignatureCreator::HashAlgorithm hash_alg) {
+ switch (hash_alg) {
+ case SignatureCreator::SHA1:
+ return NID_sha1;
+ case SignatureCreator::SHA256:
+ return NID_sha256;
+ }
+ return NID_undef;
+}
+
+} // namespace
+
// static
-SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
+SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key,
+ HashAlgorithm hash_alg) {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
scoped_ptr<SignatureCreator> result(new SignatureCreator);
result->key_ = key;
- if (!EVP_SignInit_ex(result->sign_context_, EVP_sha1(), NULL))
+ const EVP_MD* const digest = ToOpenSSLDigest(hash_alg);
+ DCHECK(digest);
+ if (!digest) {
+ return NULL;
+ }
+ if (!EVP_SignInit_ex(result->sign_context_, digest, NULL))
return NULL;
return result.release();
}
// static
bool SignatureCreator::Sign(RSAPrivateKey* key,
+ HashAlgorithm hash_alg,
const uint8* data,
int data_len,
std::vector<uint8>* signature) {
- RSA* rsa_key = EVP_PKEY_get1_RSA(key->key());
+ ScopedRSA rsa_key(EVP_PKEY_get1_RSA(key->key()));
if (!rsa_key)
return false;
- signature->resize(RSA_size(rsa_key));
+ signature->resize(RSA_size(rsa_key.get()));
unsigned int len = 0;
- bool success = RSA_sign(NID_sha1, data, data_len, vector_as_array(signature),
- &len, rsa_key);
- if (!success) {
+ if (!RSA_sign(ToOpenSSLDigestType(hash_alg), data, data_len,
+ vector_as_array(signature), &len, rsa_key.get())) {
signature->clear();
return false;
}
diff --git a/chromium/crypto/signature_creator_unittest.cc b/chromium/crypto/signature_creator_unittest.cc
index f0a888816e6..694becdcb44 100644
--- a/chromium/crypto/signature_creator_unittest.cc
+++ b/chromium/crypto/signature_creator_unittest.cc
@@ -7,6 +7,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/sha1.h"
#include "crypto/rsa_private_key.h"
+#include "crypto/sha2.h"
#include "crypto/signature_creator.h"
#include "crypto/signature_verifier.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -19,6 +20,12 @@ const uint8 kSHA1WithRSAAlgorithmID[] = {
0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00
};
+// This is the algorithm ID for SHA-1 with RSA encryption.
+const uint8 kSHA256WithRSAAlgorithmID[] = {
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0B, 0x05, 0x00
+};
+
}
TEST(SignatureCreatorTest, BasicTest) {
@@ -34,7 +41,8 @@ TEST(SignatureCreatorTest, BasicTest) {
ASSERT_TRUE(key.get());
scoped_ptr<crypto::SignatureCreator> signer(
- crypto::SignatureCreator::Create(key.get()));
+ crypto::SignatureCreator::Create(key.get(),
+ crypto::SignatureCreator::SHA1));
ASSERT_TRUE(signer.get());
std::string data("Hello, World!");
@@ -76,6 +84,7 @@ TEST(SignatureCreatorTest, SignDigestTest) {
std::vector<uint8> signature;
ASSERT_TRUE(crypto::SignatureCreator::Sign(
key.get(),
+ crypto::SignatureCreator::SHA1,
reinterpret_cast<const uint8*>(sha1.c_str()),
sha1.size(),
&signature));
@@ -94,3 +103,41 @@ TEST(SignatureCreatorTest, SignDigestTest) {
data.size());
ASSERT_TRUE(verifier.VerifyFinal());
}
+
+TEST(SignatureCreatorTest, SignSHA256DigestTest) {
+ // Do a verify round trip.
+ scoped_ptr<crypto::RSAPrivateKey> key_original(
+ crypto::RSAPrivateKey::Create(1024));
+ ASSERT_TRUE(key_original.get());
+
+ std::vector<uint8> key_info;
+ key_original->ExportPrivateKey(&key_info);
+ scoped_ptr<crypto::RSAPrivateKey> key(
+ crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info));
+ ASSERT_TRUE(key.get());
+
+ std::string data("Hello, World!");
+ std::string sha256 = crypto::SHA256HashString(data);
+ // Sign sha256 of the input data.
+ std::vector<uint8> signature;
+ ASSERT_TRUE(crypto::SignatureCreator::Sign(
+ key.get(),
+ crypto::SignatureCreator::HashAlgorithm::SHA256,
+ reinterpret_cast<const uint8*>(sha256.c_str()),
+ sha256.size(),
+ &signature));
+
+ std::vector<uint8> public_key_info;
+ ASSERT_TRUE(key_original->ExportPublicKey(&public_key_info));
+
+ // Verify the input data.
+ crypto::SignatureVerifier verifier;
+ ASSERT_TRUE(verifier.VerifyInit(
+ kSHA256WithRSAAlgorithmID, sizeof(kSHA256WithRSAAlgorithmID),
+ &signature.front(), signature.size(),
+ &public_key_info.front(), public_key_info.size()));
+
+ verifier.VerifyUpdate(reinterpret_cast<const uint8*>(data.c_str()),
+ data.size());
+ ASSERT_TRUE(verifier.VerifyFinal());
+}
diff --git a/chromium/crypto/signature_verifier.h b/chromium/crypto/signature_verifier.h
index 93591d2a82d..fbf87d4cc64 100644
--- a/chromium/crypto/signature_verifier.h
+++ b/chromium/crypto/signature_verifier.h
@@ -5,10 +5,9 @@
#ifndef CRYPTO_SIGNATURE_VERIFIER_H_
#define CRYPTO_SIGNATURE_VERIFIER_H_
-#include "build/build_config.h"
-
#include <vector>
+#include "build/build_config.h"
#include "base/basictypes.h"
#include "crypto/crypto_export.h"
diff --git a/chromium/crypto/signature_verifier_openssl.cc b/chromium/crypto/signature_verifier_openssl.cc
index a85f00b491e..a855120ef83 100644
--- a/chromium/crypto/signature_verifier_openssl.cc
+++ b/chromium/crypto/signature_verifier_openssl.cc
@@ -13,6 +13,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "crypto/openssl_util.h"
+#include "crypto/scoped_openssl_types.h"
namespace crypto {
@@ -25,13 +26,13 @@ const EVP_MD* ToOpenSSLDigest(SignatureVerifier::HashAlgorithm hash_alg) {
case SignatureVerifier::SHA256:
return EVP_sha256();
}
- return EVP_md_null();
+ return NULL;
}
} // namespace
struct SignatureVerifier::VerifyContext {
- ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy> ctx;
+ ScopedEVP_MD_CTX ctx;
};
SignatureVerifier::SignatureVerifier()
@@ -49,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> algorithm(
+ ScopedOpenSSL<X509_ALGOR, X509_ALGOR_free>::Type algorithm(
d2i_X509_ALGOR(NULL, &signature_algorithm, signature_algorithm_len));
if (!algorithm.get())
return false;
@@ -79,8 +80,11 @@ bool SignatureVerifier::VerifyInitRSAPSS(HashAlgorithm hash_alg,
const uint8* public_key_info,
int public_key_info_len) {
OpenSSLErrStackTracer err_tracer(FROM_HERE);
- const EVP_MD* digest = ToOpenSSLDigest(hash_alg);
+ const EVP_MD* const digest = ToOpenSSLDigest(hash_alg);
DCHECK(digest);
+ if (!digest) {
+ return false;
+ }
EVP_PKEY_CTX* pkey_ctx;
if (!CommonInit(digest, signature, signature_len, public_key_info,
@@ -91,8 +95,12 @@ bool SignatureVerifier::VerifyInitRSAPSS(HashAlgorithm hash_alg,
int rv = EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING);
if (rv != 1)
return false;
- rv = EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx,
- ToOpenSSLDigest(mask_hash_alg));
+ const EVP_MD* const mgf_digest = ToOpenSSLDigest(mask_hash_alg);
+ DCHECK(mgf_digest);
+ if (!mgf_digest) {
+ return false;
+ }
+ rv = EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf_digest);
if (rv != 1)
return false;
rv = EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len);
@@ -135,13 +143,11 @@ bool SignatureVerifier::CommonInit(const EVP_MD* digest,
// 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));
- ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data,
- public_key_info_len));
+ ScopedBIO bio(BIO_new_mem_buf(data, public_key_info_len));
if (!bio.get())
return false;
- ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> public_key(
- d2i_PUBKEY_bio(bio.get(), NULL));
+ ScopedEVP_PKEY public_key(d2i_PUBKEY_bio(bio.get(), NULL));
if (!public_key.get())
return false;
diff --git a/chromium/crypto/signature_verifier_unittest.cc b/chromium/crypto/signature_verifier_unittest.cc
index 332979971c6..f6c42e0fdc7 100644
--- a/chromium/crypto/signature_verifier_unittest.cc
+++ b/chromium/crypto/signature_verifier_unittest.cc
@@ -3,6 +3,8 @@
// found in the LICENSE file.
#include "crypto/signature_verifier.h"
+
+#include "base/numerics/safe_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(SignatureVerifierTest, BasicTest) {
@@ -1005,36 +1007,36 @@ 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 length = public_exponent_e.size();
- public_key_info->insert(public_key_info->begin(), length);
+ uint8 exponent_size = base::checked_cast<uint8>(public_exponent_e.size());
+ public_key_info->insert(public_key_info->begin(), exponent_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 length16 = modulus_n.size();
+ uint16 modulus_size = base::checked_cast<uint16>(modulus_n.size());
if (modulus_n[0] & 0x80) {
public_key_info->insert(public_key_info->begin(), 0x00);
- length16++;
+ modulus_size++;
}
- public_key_info->insert(public_key_info->begin(), length16 & 0xff);
- public_key_info->insert(public_key_info->begin(), (length16 >> 8) & 0xff);
+ 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);
public_key_info->insert(public_key_info->begin(), kIntegerTag);
// Encode the RSAPublicKey SEQUENCE.
- length16 = public_key_info->size();
- public_key_info->insert(public_key_info->begin(), length16 & 0xff);
- public_key_info->insert(public_key_info->begin(), (length16 >> 8) & 0xff);
+ 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);
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);
- length16 = public_key_info->size();
- public_key_info->insert(public_key_info->begin(), length16 & 0xff);
- public_key_info->insert(public_key_info->begin(), (length16 >> 8) & 0xff);
+ 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);
public_key_info->insert(public_key_info->begin(), kBitStringTag);
@@ -1049,9 +1051,9 @@ static bool EncodeRSAPublicKey(const std::vector<uint8>& modulus_n,
algorithm, algorithm + sizeof(algorithm));
// Encode the outermost SEQUENCE.
- length16 = public_key_info->size();
- public_key_info->insert(public_key_info->begin(), length16 & 0xff);
- public_key_info->insert(public_key_info->begin(), (length16 >> 8) & 0xff);
+ 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);
public_key_info->insert(public_key_info->begin(), kSequenceTag);
diff --git a/chromium/crypto/symmetric_key.h b/chromium/crypto/symmetric_key.h
index 413f61e0bca..ab105c1754c 100644
--- a/chromium/crypto/symmetric_key.h
+++ b/chromium/crypto/symmetric_key.h
@@ -57,10 +57,10 @@ class CRYPTO_EXPORT SymmetricKey {
// size for use with |algorithm|. The caller owns the returned SymmetricKey.
static SymmetricKey* Import(Algorithm algorithm, const std::string& raw_key);
-#if defined(USE_OPENSSL)
- const std::string& key() { return key_; }
-#elif defined(NACL_WIN64)
+#if defined(NACL_WIN64)
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)
PK11SymKey* key() const { return key_.get(); }
#endif
@@ -71,10 +71,7 @@ class CRYPTO_EXPORT SymmetricKey {
bool GetRawKey(std::string* raw_key);
private:
-#if defined(USE_OPENSSL)
- SymmetricKey() {}
- std::string key_;
-#elif defined(NACL_WIN64)
+#if defined(NACL_WIN64)
SymmetricKey(HCRYPTPROV provider, HCRYPTKEY key,
const void* key_data, size_t key_size_in_bytes);
@@ -88,6 +85,9 @@ class CRYPTO_EXPORT SymmetricKey {
// TODO(rsleevi): See if KP_EFFECTIVE_KEYLEN is the reason why CryptExportKey
// fails with NTE_BAD_KEY/NTE_BAD_LEN
std::string raw_key_;
+#elif defined(USE_OPENSSL)
+ SymmetricKey() {}
+ std::string key_;
#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
explicit SymmetricKey(PK11SymKey* key);
ScopedPK11SymKey key_;
diff --git a/chromium/crypto/symmetric_key_nss.cc b/chromium/crypto/symmetric_key_nss.cc
index b438b376b25..95ca9bd073e 100644
--- a/chromium/crypto/symmetric_key_nss.cc
+++ b/chromium/crypto/symmetric_key_nss.cc
@@ -20,7 +20,11 @@ SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm,
DCHECK_EQ(AES, algorithm);
EnsureNSSInit();
- if (key_size_in_bits == 0)
+
+ // Whitelist supported key sizes to avoid accidentaly relying on
+ // algorithms available in NSS but not BoringSSL and vice
+ // versa. Note that BoringSSL does not support AES-192.
+ if (key_size_in_bits != 128 && key_size_in_bits != 256)
return NULL;
ScopedPK11Slot slot(PK11_GetInternalSlot());
@@ -45,6 +49,14 @@ SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
if (salt.empty() || iterations == 0 || key_size_in_bits == 0)
return NULL;
+ if (algorithm == AES) {
+ // Whitelist supported key sizes to avoid accidentaly relying on
+ // algorithms available in NSS but not BoringSSL and vice
+ // versa. Note that BoringSSL does not support AES-192.
+ if (key_size_in_bits != 128 && key_size_in_bits != 256)
+ return NULL;
+ }
+
SECItem password_item;
password_item.type = siBuffer;
password_item.data = reinterpret_cast<unsigned char*>(
@@ -84,6 +96,15 @@ SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
SymmetricKey* SymmetricKey::Import(Algorithm algorithm,
const std::string& raw_key) {
EnsureNSSInit();
+
+ if (algorithm == AES) {
+ // Whitelist supported key sizes to avoid accidentaly relying on
+ // algorithms available in NSS but not BoringSSL and vice
+ // versa. Note that BoringSSL does not support AES-192.
+ if (raw_key.size() != 128/8 && raw_key.size() != 256/8)
+ return NULL;
+ }
+
CK_MECHANISM_TYPE cipher =
algorithm == AES ? CKM_AES_CBC : CKM_SHA_1_HMAC;
diff --git a/chromium/crypto/symmetric_key_openssl.cc b/chromium/crypto/symmetric_key_openssl.cc
index e1c6fb7eded..e268a1d0f98 100644
--- a/chromium/crypto/symmetric_key_openssl.cc
+++ b/chromium/crypto/symmetric_key_openssl.cc
@@ -24,6 +24,13 @@ SymmetricKey::~SymmetricKey() {
SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm,
size_t key_size_in_bits) {
DCHECK_EQ(AES, algorithm);
+
+ // Whitelist supported key sizes to avoid accidentaly relying on
+ // algorithms available in NSS but not BoringSSL and vice
+ // versa. Note that BoringSSL does not support AES-192.
+ if (key_size_in_bits != 128 && key_size_in_bits != 256)
+ return NULL;
+
size_t key_size_in_bytes = key_size_in_bits / 8;
DCHECK_EQ(key_size_in_bits, key_size_in_bytes * 8);
@@ -46,6 +53,15 @@ SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
size_t iterations,
size_t key_size_in_bits) {
DCHECK(algorithm == AES || algorithm == HMAC_SHA1);
+
+ if (algorithm == AES) {
+ // Whitelist supported key sizes to avoid accidentaly relying on
+ // algorithms available in NSS but not BoringSSL and vice
+ // versa. Note that BoringSSL does not support AES-192.
+ if (key_size_in_bits != 128 && key_size_in_bits != 256)
+ return NULL;
+ }
+
size_t key_size_in_bytes = key_size_in_bits / 8;
DCHECK_EQ(key_size_in_bits, key_size_in_bytes * 8);
@@ -67,6 +83,14 @@ SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
// static
SymmetricKey* SymmetricKey::Import(Algorithm algorithm,
const std::string& raw_key) {
+ if (algorithm == AES) {
+ // Whitelist supported key sizes to avoid accidentaly relying on
+ // algorithms available in NSS but not BoringSSL and vice
+ // versa. Note that BoringSSL does not support AES-192.
+ if (raw_key.size() != 128/8 && raw_key.size() != 256/8)
+ return NULL;
+ }
+
scoped_ptr<SymmetricKey> key(new SymmetricKey);
key->key_ = raw_key;
return key.release();
diff --git a/chromium/crypto/symmetric_key_unittest.cc b/chromium/crypto/symmetric_key_unittest.cc
index f0b4a60a4c5..28e44d27da7 100644
--- a/chromium/crypto/symmetric_key_unittest.cc
+++ b/chromium/crypto/symmetric_key_unittest.cc
@@ -100,7 +100,7 @@ TEST_P(SymmetricKeyDeriveKeyFromPasswordTest, DeriveKeyFromPassword) {
key->GetRawKey(&raw_key);
EXPECT_EQ(test_data.key_size_in_bits / 8, raw_key.size());
EXPECT_EQ(test_data.expected,
- StringToLowerASCII(base::HexEncode(raw_key.data(),
+ base::StringToLowerASCII(base::HexEncode(raw_key.data(),
raw_key.size())));
}
@@ -172,7 +172,7 @@ static const PBKDF2TestVector kTestVectors[] = {
{
crypto::SymmetricKey::HMAC_SHA1,
"password",
- "\0224VxxV4\022", /* 0x1234567878563412 */
+ "\022" "4VxxV4\022", /* 0x1234567878563412 */
5,
160,
"d1daa78615f287e6a1c8b120d7062a493f98d203",
diff --git a/chromium/crypto/wincrypt_shim.h b/chromium/crypto/wincrypt_shim.h
new file mode 100644
index 00000000000..799ac49feeb
--- /dev/null
+++ b/chromium/crypto/wincrypt_shim.h
@@ -0,0 +1,25 @@
+// Copyright 2014 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 NET_CRYPTO_WINCRYPT_SHIM_H_
+#define NET_CRYPTO_WINCRYPT_SHIM_H_
+
+// wincrypt.h defines macros which conflict with OpenSSL's types. This header
+// includes wincrypt and undefines the OpenSSL macros which conflict. Any
+// Chromium headers which include wincrypt should instead include this header.
+
+#include <windows.h>
+#include <wincrypt.h>
+
+// Undefine the macros which conflict with OpenSSL and define replacements. See
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa378145(v=vs.85).aspx
+#undef X509_CERT_PAIR
+#undef X509_EXTENSIONS
+#undef X509_NAME
+
+#define WINCRYPT_X509_CERT_PAIR ((LPCSTR) 53)
+#define WINCRYPT_X509_EXTENSIONS ((LPCSTR) 5)
+#define WINCRYPT_X509_NAME ((LPCSTR) 7)
+
+#endif // NET_CRYPTO_WINCRYPT_SHIM_H_ \ No newline at end of file