NSS Channel ID: don't check ECC support on every socket creation.
Add static function to ECPrivateKey to get which NSS slot it uses. BUG=127506 Review URL: https://chromiumcodereview.appspot.com/10700099 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@145777 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@ -34,6 +34,9 @@ class CRYPTO_EXPORT ECPrivateKey {
|
||||
public:
|
||||
~ECPrivateKey();
|
||||
|
||||
// Returns whether the system supports elliptic curve cryptography.
|
||||
static bool IsSupported();
|
||||
|
||||
// Creates a new random instance. Can return NULL if initialization fails.
|
||||
// The created key will use the NIST P-256 curve.
|
||||
// TODO(mattm): Add a curve parameter.
|
||||
|
@ -15,6 +15,7 @@ extern "C" {
|
||||
#include <pk11pub.h>
|
||||
#include <secmod.h>
|
||||
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "crypto/nss_util.h"
|
||||
@ -24,6 +25,34 @@ extern "C" {
|
||||
|
||||
namespace {
|
||||
|
||||
PK11SlotInfo* GetKeySlot() {
|
||||
return crypto::GetPublicNSSKeySlot();
|
||||
}
|
||||
|
||||
class EllipticCurveSupportChecker {
|
||||
public:
|
||||
EllipticCurveSupportChecker() {
|
||||
// NOTE: we can do this check here only because we use the NSS internal
|
||||
// slot. If we support other slots in the future, checking whether they
|
||||
// support ECDSA may block NSS, and the value may also change as devices are
|
||||
// inserted/removed, so we would need to re-check on every use.
|
||||
crypto::EnsureNSSInit();
|
||||
crypto::ScopedPK11Slot slot(GetKeySlot());
|
||||
supported_ = PK11_DoesMechanism(slot.get(), CKM_EC_KEY_PAIR_GEN) &&
|
||||
PK11_DoesMechanism(slot.get(), CKM_ECDSA);
|
||||
}
|
||||
|
||||
bool Supported() {
|
||||
return supported_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool supported_;
|
||||
};
|
||||
|
||||
static base::LazyInstance<EllipticCurveSupportChecker>::Leaky
|
||||
g_elliptic_curve_supported = LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
// Copied from rsa_private_key_nss.cc.
|
||||
static bool ReadAttribute(SECKEYPrivateKey* key,
|
||||
CK_ATTRIBUTE_TYPE type,
|
||||
@ -52,6 +81,11 @@ ECPrivateKey::~ECPrivateKey() {
|
||||
SECKEY_DestroyPublicKey(public_key_);
|
||||
}
|
||||
|
||||
// static
|
||||
bool ECPrivateKey::IsSupported() {
|
||||
return g_elliptic_curve_supported.Get().Supported();
|
||||
}
|
||||
|
||||
// static
|
||||
ECPrivateKey* ECPrivateKey::Create() {
|
||||
return CreateWithParams(PR_FALSE /* not permanent */,
|
||||
@ -114,7 +148,7 @@ bool ECPrivateKey::ImportFromEncryptedPrivateKeyInfo(
|
||||
bool sensitive,
|
||||
SECKEYPrivateKey** key,
|
||||
SECKEYPublicKey** public_key) {
|
||||
ScopedPK11Slot slot(GetPublicNSSKeySlot());
|
||||
ScopedPK11Slot slot(GetKeySlot());
|
||||
if (!slot.get())
|
||||
return false;
|
||||
|
||||
@ -247,7 +281,7 @@ ECPrivateKey* ECPrivateKey::CreateWithParams(bool permanent,
|
||||
|
||||
scoped_ptr<ECPrivateKey> result(new ECPrivateKey);
|
||||
|
||||
ScopedPK11Slot slot(GetPrivateNSSKeySlot());
|
||||
ScopedPK11Slot slot(GetKeySlot());
|
||||
if (!slot.get())
|
||||
return NULL;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@ -10,6 +10,11 @@ namespace crypto {
|
||||
|
||||
ECPrivateKey::~ECPrivateKey() {}
|
||||
|
||||
// static
|
||||
bool ECPrivateKey::IsSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
ECPrivateKey* ECPrivateKey::Create() {
|
||||
NOTIMPLEMENTED();
|
||||
|
@ -1074,13 +1074,7 @@ bool SSLClientSocketNSS::Core::Init(PRFileDesc* socket,
|
||||
}
|
||||
|
||||
if (ssl_config_.channel_id_enabled) {
|
||||
// TODO(mattm): we can do this check on the network task runner only because
|
||||
// we use the NSS internal slot. If we support other slots in the future,
|
||||
// checking whether they support ECDSA may block NSS, and thus this check
|
||||
// would have to be moved to the NSS task runner.
|
||||
crypto::ScopedPK11Slot slot(crypto::GetPublicNSSKeySlot());
|
||||
if (PK11_DoesMechanism(slot.get(), CKM_EC_KEY_PAIR_GEN) &&
|
||||
PK11_DoesMechanism(slot.get(), CKM_ECDSA)) {
|
||||
if (crypto::ECPrivateKey::IsSupported()) {
|
||||
rv = SSL_SetClientChannelIDCallback(
|
||||
nss_fd_, SSLClientSocketNSS::Core::ClientChannelIDHandler, this);
|
||||
if (rv != SECSuccess)
|
||||
@ -2523,7 +2517,8 @@ void SSLClientSocketNSS::Core::RecordChannelIDSupport() const {
|
||||
} supported = DISABLED;
|
||||
if (channel_id_xtn_negotiated_)
|
||||
supported = CLIENT_AND_SERVER;
|
||||
else if (ssl_config_.channel_id_enabled)
|
||||
else if (ssl_config_.channel_id_enabled &&
|
||||
crypto::ECPrivateKey::IsSupported())
|
||||
supported = CLIENT_ONLY;
|
||||
UMA_HISTOGRAM_ENUMERATION("DomainBoundCerts.Support", supported,
|
||||
DOMAIN_BOUND_CERT_USAGE_MAX);
|
||||
|
Reference in New Issue
Block a user