summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/ec_private_key.h5
-rw-r--r--crypto/ec_private_key_nss.cc38
-rw-r--r--crypto/ec_private_key_openssl.cc7
-rw-r--r--net/socket/ssl_client_socket_nss.cc11
4 files changed, 49 insertions, 12 deletions
diff --git a/crypto/ec_private_key.h b/crypto/ec_private_key.h
index 44f754b..bfd0862 100644
--- a/crypto/ec_private_key.h
+++ b/crypto/ec_private_key.h
@@ -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.
diff --git a/crypto/ec_private_key_nss.cc b/crypto/ec_private_key_nss.cc
index c6c4763..9bb9df1 100644
--- a/crypto/ec_private_key_nss.cc
+++ b/crypto/ec_private_key_nss.cc
@@ -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,
@@ -53,6 +82,11 @@ ECPrivateKey::~ECPrivateKey() {
}
// static
+bool ECPrivateKey::IsSupported() {
+ return g_elliptic_curve_supported.Get().Supported();
+}
+
+// static
ECPrivateKey* ECPrivateKey::Create() {
return CreateWithParams(PR_FALSE /* not permanent */,
PR_FALSE /* not sensitive */);
@@ -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;
diff --git a/crypto/ec_private_key_openssl.cc b/crypto/ec_private_key_openssl.cc
index 40e6f04..20214e6 100644
--- a/crypto/ec_private_key_openssl.cc
+++ b/crypto/ec_private_key_openssl.cc
@@ -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.
@@ -11,6 +11,11 @@ namespace crypto {
ECPrivateKey::~ECPrivateKey() {}
// static
+bool ECPrivateKey::IsSupported() {
+ return false;
+}
+
+// static
ECPrivateKey* ECPrivateKey::Create() {
NOTIMPLEMENTED();
return NULL;
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index c303829..8d677ef 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -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);