summaryrefslogtreecommitdiffstats
path: root/crypto/ec_private_key_nss.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/ec_private_key_nss.cc')
-rw-r--r--crypto/ec_private_key_nss.cc38
1 files changed, 36 insertions, 2 deletions
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;