--- a/security/manager/ssl/LocalCertService.cpp
+++ b/security/manager/ssl/LocalCertService.cpp
@@ -32,17 +32,17 @@ protected:
}
nsresult RemoveExisting()
{
// Search for any existing certs with this name and remove them
nsresult rv;
for (;;) {
- ScopedCERTCertificate cert(
+ UniqueCERTCertificate cert(
PK11_FindCertFromNickname(mNickname.get(), nullptr));
if (!cert) {
return NS_OK; // All done
}
// Found a cert, check if generated by this service
if (!cert->isRoot) {
return NS_ERROR_UNEXPECTED; // Should be self-signed
@@ -52,17 +52,17 @@ protected:
nsAutoCString subjectNameFromNickname(commonNamePrefix + mNickname);
if (!subjectNameFromNickname.Equals(cert->subjectName)) {
return NS_ERROR_UNEXPECTED; // Subject should match nickname
}
if (!subjectNameFromNickname.Equals(cert->issuerName)) {
return NS_ERROR_UNEXPECTED; // Issuer should match nickname
}
- rv = MapSECStatus(PK11_DeleteTokenCertAndKey(cert, nullptr));
+ rv = MapSECStatus(PK11_DeleteTokenCertAndKey(cert.get(), nullptr));
if (NS_FAILED(rv)) {
return rv; // Some error, abort the loop
}
}
}
nsCString mNickname;
};
@@ -119,17 +119,17 @@ private:
rv = RemoveExisting();
if (NS_FAILED(rv)) {
return rv;
}
// Generate a new cert
NS_NAMED_LITERAL_CSTRING(commonNamePrefix, "CN=");
nsAutoCString subjectNameStr(commonNamePrefix + mNickname);
- ScopedCERTName subjectName(CERT_AsciiToName(subjectNameStr.get()));
+ UniqueCERTName subjectName(CERT_AsciiToName(subjectNameStr.get()));
if (!subjectName) {
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
}
// Use the well-known NIST P-256 curve
SECOidData* curveOidData = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1);
if (!curveOidData) {
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
@@ -137,66 +137,67 @@ private:
// Get key params from the curve
ScopedAutoSECItem keyParams(2 + curveOidData->oid.len);
keyParams.data[0] = SEC_ASN1_OBJECT_ID;
keyParams.data[1] = curveOidData->oid.len;
memcpy(keyParams.data + 2, curveOidData->oid.data, curveOidData->oid.len);
// Generate cert key pair
- ScopedSECKEYPublicKey publicKey;
SECKEYPublicKey* tempPublicKey;
UniqueSECKEYPrivateKey privateKey(
PK11_GenerateKeyPair(slot.get(), CKM_EC_KEY_PAIR_GEN, &keyParams,
&tempPublicKey, true /* token */,
true /* sensitive */, nullptr));
- if (!privateKey) {
+ UniqueSECKEYPublicKey publicKey(tempPublicKey);
+ tempPublicKey = nullptr;
+ if (!privateKey || !publicKey) {
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
}
- publicKey = tempPublicKey;
// Create subject public key info and cert request
- ScopedCERTSubjectPublicKeyInfo spki(
- SECKEY_CreateSubjectPublicKeyInfo(publicKey));
+ UniqueCERTSubjectPublicKeyInfo spki(
+ SECKEY_CreateSubjectPublicKeyInfo(publicKey.get()));
if (!spki) {
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
}
- ScopedCERTCertificateRequest certRequest(
- CERT_CreateCertificateRequest(subjectName, spki, nullptr));
+ UniqueCERTCertificateRequest certRequest(
+ CERT_CreateCertificateRequest(subjectName.get(), spki.get(), nullptr));
if (!certRequest) {
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
}
// Valid from one day before to 1 year after
static const PRTime oneDay = PRTime(PR_USEC_PER_SEC)
* PRTime(60) // sec
* PRTime(60) // min
* PRTime(24); // hours
PRTime now = PR_Now();
PRTime notBefore = now - oneDay;
PRTime notAfter = now + (PRTime(365) * oneDay);
- ScopedCERTValidity validity(CERT_CreateValidity(notBefore, notAfter));
+ UniqueCERTValidity validity(CERT_CreateValidity(notBefore, notAfter));
if (!validity) {
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
}
// Generate random serial
unsigned long serial;
// This serial in principle could collide, but it's unlikely
rv = MapSECStatus(PK11_GenerateRandomOnSlot(
slot.get(), BitwiseCast<unsigned char*, unsigned long*>(&serial),
sizeof(serial)));
if (NS_FAILED(rv)) {
return rv;
}
// Create the cert from these pieces
- ScopedCERTCertificate cert(
- CERT_CreateCertificate(serial, subjectName, validity, certRequest));
+ UniqueCERTCertificate cert(
+ CERT_CreateCertificate(serial, subjectName.get(), validity.get(),
+ certRequest.get()));
if (!cert) {
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
}
// Update the cert version to X509v3
if (!cert->version.data) {
return NS_ERROR_INVALID_POINTER;
}
@@ -211,41 +212,42 @@ private:
rv = MapSECStatus(
SECOID_SetAlgorithmID(arena, &cert->signature,
SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, 0));
if (NS_FAILED(rv)) {
return rv;
}
// Encode and self-sign the cert
- ScopedSECItem certDER(
- SEC_ASN1EncodeItem(nullptr, nullptr, cert,
+ UniqueSECItem certDER(
+ SEC_ASN1EncodeItem(nullptr, nullptr, cert.get(),
SEC_ASN1_GET(CERT_CertificateTemplate)));
if (!certDER) {
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
}
rv = MapSECStatus(
SEC_DerSignData(arena, &cert->derCert, certDER->data, certDER->len,
privateKey.get(),
SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE));
if (NS_FAILED(rv)) {
return rv;
}
// Create a CERTCertificate from the signed data
- ScopedCERTCertificate certFromDER(
+ UniqueCERTCertificate certFromDER(
CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &cert->derCert, nullptr,
true /* perm */, true /* copyDER */));
if (!certFromDER) {
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
}
// Save the cert in the DB
- rv = MapSECStatus(PK11_ImportCert(slot.get(), certFromDER, CK_INVALID_HANDLE,
- mNickname.get(), false /* unused */));
+ rv = MapSECStatus(PK11_ImportCert(slot.get(), certFromDER.get(),
+ CK_INVALID_HANDLE, mNickname.get(),
+ false /* unused */));
if (NS_FAILED(rv)) {
return rv;
}
// We should now have cert in the DB, read it back in nsIX509Cert form
return GetFromDB();
}
--- a/security/manager/ssl/nsNSSU2FToken.cpp
+++ b/security/manager/ssl/nsNSSU2FToken.cpp
@@ -9,16 +9,17 @@
#include "CryptoBuffer.h"
#include "mozilla/Casting.h"
#include "nsNSSComponent.h"
#include "pk11pub.h"
#include "prerror.h"
#include "secerr.h"
#include "WebCryptoCommon.h"
+using namespace mozilla;
using mozilla::dom::CreateECParamsForCurve;
NS_IMPL_ISUPPORTS(nsNSSU2FToken, nsINSSU2FToken)
// Not named "security.webauth.u2f_softtoken_counter" because setting that
// name causes the window.u2f object to disappear until preferences get
// reloaded, as its' pref is a substring!
#define PREF_U2F_NSSTOKEN_COUNTER "security.webauth.softtoken_counter"
@@ -78,172 +79,198 @@ nsNSSU2FToken::virtualDestroyNSSReferenc
}
void
nsNSSU2FToken::destructorSafeDestroyNSSReference()
{
mWrappingKey = nullptr;
}
-static PK11SymKey*
+static UniquePK11SymKey
GetSymKeyByNickname(const UniquePK11SlotInfo& aSlot,
nsCString aNickname,
const nsNSSShutDownPreventionLock&)
{
+ MOZ_ASSERT(aSlot);
+ if (!aSlot) {
+ return nullptr;
+ }
+
MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
("Searching for a symmetric key named %s", aNickname.get()));
PK11SymKey* keyList;
keyList = PK11_ListFixedKeysInSlot(aSlot.get(),
const_cast<char*>(aNickname.get()),
/* wincx */ nullptr);
while (keyList) {
- ScopedPK11SymKey freeKey(keyList);
+ UniquePK11SymKey freeKey(keyList);
UniquePORTString freeKeyName(PK11_GetSymKeyNickname(freeKey.get()));
if (aNickname == freeKeyName.get()) {
MOZ_LOG(gNSSTokenLog, LogLevel::Debug, ("Symmetric key found!"));
- return freeKey.forget();
+ return freeKey;
}
keyList = PK11_GetNextSymKey(keyList);
}
MOZ_LOG(gNSSTokenLog, LogLevel::Debug, ("Symmetric key not found."));
return nullptr;
}
static nsresult
-GenEcKeypair(const UniquePK11SlotInfo& aSlot, ScopedSECKEYPrivateKey& aPrivKey,
- ScopedSECKEYPublicKey& aPubKey, const nsNSSShutDownPreventionLock&)
+GenEcKeypair(const UniquePK11SlotInfo& aSlot,
+ /*out*/ UniqueSECKEYPrivateKey& aPrivKey,
+ /*out*/ UniqueSECKEYPublicKey& aPubKey,
+ const nsNSSShutDownPreventionLock&)
{
+ MOZ_ASSERT(aSlot);
+ if (!aSlot) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return NS_ERROR_OUT_OF_MEMORY;
}
// Set the curve parameters; keyParams belongs to the arena memory space
SECItem* keyParams = CreateECParamsForCurve(kEcAlgorithm, arena.get());
if (!keyParams) {
return NS_ERROR_OUT_OF_MEMORY;
}
// Generate a key pair
CK_MECHANISM_TYPE mechanism = CKM_EC_KEY_PAIR_GEN;
SECKEYPublicKey* pubKeyRaw;
- aPrivKey = PK11_GenerateKeyPair(aSlot.get(), mechanism, keyParams, &pubKeyRaw,
- /* ephemeral */ PR_FALSE, PR_FALSE,
- /* wincx */ nullptr);
- aPubKey = pubKeyRaw;
+ aPrivKey = UniqueSECKEYPrivateKey(
+ PK11_GenerateKeyPair(aSlot.get(), mechanism, keyParams, &pubKeyRaw,
+ /* ephemeral */ false, false,
+ /* wincx */ nullptr));
+ aPubKey = UniqueSECKEYPublicKey(pubKeyRaw);
+ pubKeyRaw = nullptr;
if (!aPrivKey.get() || !aPubKey.get()) {
return NS_ERROR_FAILURE;
}
// Check that the public key has the correct length
if (aPubKey->u.ec.publicValue.len != kPublicKeyLen) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
nsNSSU2FToken::GetOrCreateWrappingKey(const UniquePK11SlotInfo& aSlot,
const nsNSSShutDownPreventionLock& locker)
{
+ MOZ_ASSERT(aSlot);
+ if (!aSlot) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
// Search for an existing wrapping key. If we find it,
// store it for later and mark ourselves initialized.
mWrappingKey = GetSymKeyByNickname(aSlot, mSecretNickname, locker);
if (mWrappingKey) {
MOZ_LOG(gNSSTokenLog, LogLevel::Debug, ("U2F Soft Token Key found."));
mInitialized = true;
return NS_OK;
}
MOZ_LOG(gNSSTokenLog, LogLevel::Info,
("No keys found. Generating new U2F Soft Token wrapping key."));
// We did not find an existing wrapping key, so we generate one in the
// persistent database (e.g, Token).
- mWrappingKey = PK11_TokenKeyGenWithFlags(aSlot.get(), CKM_AES_KEY_GEN,
- /* default params */ nullptr,
- kWrappingKeyByteLen,
- /* empty keyid */ nullptr,
- /* flags */ CKF_WRAP | CKF_UNWRAP,
- /* attributes */ PK11_ATTR_TOKEN |
- PK11_ATTR_PRIVATE,
- /* wincx */ nullptr);
+ mWrappingKey = UniquePK11SymKey(
+ PK11_TokenKeyGenWithFlags(aSlot.get(), CKM_AES_KEY_GEN,
+ /* default params */ nullptr,
+ kWrappingKeyByteLen,
+ /* empty keyid */ nullptr,
+ /* flags */ CKF_WRAP | CKF_UNWRAP,
+ /* attributes */ PK11_ATTR_TOKEN |
+ PK11_ATTR_PRIVATE,
+ /* wincx */ nullptr));
if (!mWrappingKey) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Failed to store wrapping key, NSS error #%d", PORT_GetError()));
return NS_ERROR_FAILURE;
}
- SECStatus srv = PK11_SetSymKeyNickname(mWrappingKey, mSecretNickname.get());
+ SECStatus srv = PK11_SetSymKeyNickname(mWrappingKey.get(),
+ mSecretNickname.get());
if (srv != SECSuccess) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Failed to set nickname, NSS error #%d", PORT_GetError()));
return NS_ERROR_FAILURE;
}
MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
("Key stored, nickname set to %s.", mSecretNickname.get()));
Preferences::SetUint(PREF_U2F_NSSTOKEN_COUNTER, 0);
return NS_OK;
}
static nsresult
GetAttestationCertificate(const UniquePK11SlotInfo& aSlot,
- ScopedSECKEYPrivateKey& aAttestPrivKey,
- ScopedCERTCertificate& aAttestCert,
+ /*out*/ UniqueSECKEYPrivateKey& aAttestPrivKey,
+ /*out*/ UniqueCERTCertificate& aAttestCert,
const nsNSSShutDownPreventionLock& locker)
{
- ScopedSECKEYPublicKey pubKey;
+ MOZ_ASSERT(aSlot);
+ if (!aSlot) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ UniqueSECKEYPublicKey pubKey;
// Construct an ephemeral keypair for this Attestation Certificate
nsresult rv = GenEcKeypair(aSlot, aAttestPrivKey, pubKey, locker);
if (NS_FAILED(rv) || !aAttestPrivKey || !pubKey) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Failed to gen keypair, NSS error #%d", PORT_GetError()));
return NS_ERROR_FAILURE;
}
// Construct the Attestation Certificate itself
- ScopedCERTName subjectName(CERT_AsciiToName(kAttestCertSubjectName.get()));
+ UniqueCERTName subjectName(CERT_AsciiToName(kAttestCertSubjectName.get()));
if (!subjectName) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Failed to set subject name, NSS error #%d", PORT_GetError()));
return NS_ERROR_FAILURE;
}
- ScopedCERTSubjectPublicKeyInfo spki(
- SECKEY_CreateSubjectPublicKeyInfo(pubKey));
+ UniqueCERTSubjectPublicKeyInfo spki(
+ SECKEY_CreateSubjectPublicKeyInfo(pubKey.get()));
if (!spki) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Failed to set SPKI, NSS error #%d", PORT_GetError()));
return NS_ERROR_FAILURE;
}
- ScopedCERTCertificateRequest certreq(
- CERT_CreateCertificateRequest(subjectName, spki, nullptr));
+ UniqueCERTCertificateRequest certreq(
+ CERT_CreateCertificateRequest(subjectName.get(), spki.get(), nullptr));
if (!certreq) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Failed to gen CSR, NSS error #%d", PORT_GetError()));
return NS_ERROR_FAILURE;
}
PRTime now = PR_Now();
PRTime notBefore = now - kExpirationSlack;
PRTime notAfter = now + kExpirationLife;
- ScopedCERTValidity validity(CERT_CreateValidity(notBefore, notAfter));
+ UniqueCERTValidity validity(CERT_CreateValidity(notBefore, notAfter));
if (!validity) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Failed to gen validity, NSS error #%d", PORT_GetError()));
return NS_ERROR_FAILURE;
}
unsigned long serial;
unsigned char* serialBytes =
@@ -259,49 +286,52 @@ GetAttestationCertificate(const UniquePK
// indicate a negative number, which isn't valid for serial
// numbers).
serialBytes[0] &= 0x7f;
// Also ensure that the least significant bit on the most
// significant byte is set (to prevent a leading zero byte,
// which also wouldn't be valid).
serialBytes[0] |= 0x01;
- aAttestCert = CERT_CreateCertificate(serial, subjectName, validity, certreq);
+ aAttestCert = UniqueCERTCertificate(
+ CERT_CreateCertificate(serial, subjectName.get(), validity.get(),
+ certreq.get()));
if (!aAttestCert) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Failed to gen certificate, NSS error #%d", PORT_GetError()));
return NS_ERROR_FAILURE;
}
- PLArenaPool *arena = aAttestCert->arena;
+ PLArenaPool* arena = aAttestCert->arena;
srv = SECOID_SetAlgorithmID(arena, &aAttestCert->signature,
SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE,
/* wincx */ nullptr);
if (srv != SECSuccess) {
return NS_ERROR_FAILURE;
}
// Set version to X509v3.
*(aAttestCert->version.data) = SEC_CERTIFICATE_VERSION_3;
aAttestCert->version.len = 1;
SECItem innerDER = { siBuffer, nullptr, 0 };
- if (!SEC_ASN1EncodeItem(arena, &innerDER, aAttestCert,
+ if (!SEC_ASN1EncodeItem(arena, &innerDER, aAttestCert.get(),
SEC_ASN1_GET(CERT_CertificateTemplate))) {
return NS_ERROR_FAILURE;
}
- SECItem *signedCert = PORT_ArenaZNew(arena, SECItem);
+ SECItem* signedCert = PORT_ArenaZNew(arena, SECItem);
if (!signedCert) {
return NS_ERROR_FAILURE;
}
srv = SEC_DerSignData(arena, signedCert, innerDER.data, innerDER.len,
- aAttestPrivKey, SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
+ aAttestPrivKey.get(),
+ SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
if (srv != SECSuccess) {
return NS_ERROR_FAILURE;
}
aAttestCert->derCert = *signedCert;
MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
("U2F Soft Token attestation certificate generated."));
return NS_OK;
@@ -334,75 +364,89 @@ nsNSSU2FToken::Init()
mInitialized = true;
MOZ_LOG(gNSSTokenLog, LogLevel::Debug, ("U2F Soft Token initialized."));
return NS_OK;
}
// Convert a Private Key object into an opaque key handle, using AES Key Wrap
// and aWrappingKey to convert aPrivKey.
-static SECItem*
+static UniqueSECItem
KeyHandleFromPrivateKey(const UniquePK11SlotInfo& aSlot,
- PK11SymKey* aWrappingKey,
- SECKEYPrivateKey* aPrivKey,
+ const UniquePK11SymKey& aWrappingKey,
+ const UniqueSECKEYPrivateKey& aPrivKey,
const nsNSSShutDownPreventionLock&)
{
- ScopedSECItem wrappedKey(SECITEM_AllocItem(/* default arena */ nullptr,
+ MOZ_ASSERT(aSlot);
+ MOZ_ASSERT(aWrappingKey);
+ MOZ_ASSERT(aPrivKey);
+ if (!aSlot || !aWrappingKey || !aPrivKey) {
+ return nullptr;
+ }
+
+ UniqueSECItem wrappedKey(SECITEM_AllocItem(/* default arena */ nullptr,
/* no buffer */ nullptr,
kWrappedKeyBufLen));
if (!wrappedKey) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Failed to allocate memory, NSS error #%d", PORT_GetError()));
return nullptr;
}
- ScopedSECItem param(PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP_PAD,
+ UniqueSECItem param(PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP_PAD,
/* default IV */ nullptr ));
- SECStatus srv = PK11_WrapPrivKey(aSlot.get(), aWrappingKey, aPrivKey,
- CKM_NSS_AES_KEY_WRAP_PAD, param,
- wrappedKey.get(), /* wincx */ nullptr);
+ SECStatus srv = PK11_WrapPrivKey(aSlot.get(), aWrappingKey.get(),
+ aPrivKey.get(), CKM_NSS_AES_KEY_WRAP_PAD,
+ param.get(), wrappedKey.get(),
+ /* wincx */ nullptr);
if (srv != SECSuccess) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Failed to wrap U2F key, NSS error #%d", PORT_GetError()));
return nullptr;
}
- return wrappedKey.forget();
+ return wrappedKey;
}
// Convert an opaque key handle aKeyHandle back into a Private Key object, using
// aWrappingKey and the AES Key Wrap algorithm.
-static SECKEYPrivateKey*
+static UniqueSECKEYPrivateKey
PrivateKeyFromKeyHandle(const UniquePK11SlotInfo& aSlot,
- PK11SymKey* aWrappingKey,
+ const UniquePK11SymKey& aWrappingKey,
uint8_t* aKeyHandle, uint32_t aKeyHandleLen,
const nsNSSShutDownPreventionLock&)
{
+ MOZ_ASSERT(aSlot);
+ MOZ_ASSERT(aWrappingKey);
+ MOZ_ASSERT(aKeyHandle);
+ if (!aSlot || !aWrappingKey || !aKeyHandle) {
+ return nullptr;
+ }
+
ScopedAutoSECItem pubKey(kPublicKeyLen);
ScopedAutoSECItem keyHandleItem(aKeyHandleLen);
memcpy(keyHandleItem.data, aKeyHandle, keyHandleItem.len);
- ScopedSECItem param(PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP_PAD,
+ UniqueSECItem param(PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP_PAD,
/* default IV */ nullptr ));
CK_ATTRIBUTE_TYPE usages[] = { CKA_SIGN };
int usageCount = 1;
- SECKEYPrivateKey* unwrappedKey;
- unwrappedKey = PK11_UnwrapPrivKey(aSlot.get(), aWrappingKey,
- CKM_NSS_AES_KEY_WRAP_PAD,
- param, &keyHandleItem,
- /* no nickname */ nullptr,
- /* discard pubkey */ &pubKey,
- /* not permanent */ PR_FALSE,
- /* non-exportable */ PR_TRUE,
- CKK_EC, usages, usageCount,
- /* wincx */ nullptr);
+ UniqueSECKEYPrivateKey unwrappedKey(
+ PK11_UnwrapPrivKey(aSlot.get(), aWrappingKey.get(), CKM_NSS_AES_KEY_WRAP_PAD,
+ param.get(), &keyHandleItem,
+ /* no nickname */ nullptr,
+ /* discard pubkey */ &pubKey,
+ /* not permanent */ false,
+ /* non-exportable */ true,
+ CKK_EC, usages, usageCount,
+ /* wincx */ nullptr));
if (!unwrappedKey) {
// Not our key.
MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
("Could not unwrap key handle, NSS Error #%d", PORT_GetError()));
return nullptr;
}
return unwrappedKey;
@@ -440,21 +484,20 @@ nsNSSU2FToken::IsRegistered(uint8_t* aKe
if (!mInitialized) {
return NS_ERROR_FAILURE;
}
UniquePK11SlotInfo slot(PK11_GetInternalSlot());
MOZ_ASSERT(slot.get());
// Decode the key handle
- UniqueSECKEYPrivateKey privKey(PrivateKeyFromKeyHandle(slot,
- mWrappingKey.get(),
- aKeyHandle,
- aKeyHandleLen,
- locker));
+ UniqueSECKEYPrivateKey privKey = PrivateKeyFromKeyHandle(slot, mWrappingKey,
+ aKeyHandle,
+ aKeyHandleLen,
+ locker);
*aResult = (privKey.get() != nullptr);
return NS_OK;
}
// A U2F Register operation causes a new key pair to be generated by the token.
// The token then returns the public key of the key pair, and a handle to the
// private key, which is a fancy way of saying "key wrapped private key", as
// well as the generated attestation certificate and a signature using that
@@ -503,38 +546,37 @@ nsNSSU2FToken::Register(uint8_t* aApplic
// We should already have a wrapping key
MOZ_ASSERT(mWrappingKey);
UniquePK11SlotInfo slot(PK11_GetInternalSlot());
MOZ_ASSERT(slot.get());
// Construct a one-time-use Attestation Certificate
- ScopedSECKEYPrivateKey attestPrivKey;
- ScopedCERTCertificate attestCert;
+ UniqueSECKEYPrivateKey attestPrivKey;
+ UniqueCERTCertificate attestCert;
nsresult rv = GetAttestationCertificate(slot, attestPrivKey, attestCert,
locker);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(attestCert);
MOZ_ASSERT(attestPrivKey);
// Generate a new keypair; the private will be wrapped into a Key Handle
- ScopedSECKEYPrivateKey privKey;
- ScopedSECKEYPublicKey pubKey;
+ UniqueSECKEYPrivateKey privKey;
+ UniqueSECKEYPublicKey pubKey;
rv = GenEcKeypair(slot, privKey, pubKey, locker);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
// The key handle will be the result of keywrap(privKey, key=mWrappingKey)
- UniqueSECItem keyHandleItem(KeyHandleFromPrivateKey(slot, mWrappingKey.get(),
- privKey.get(),
- locker));
+ UniqueSECItem keyHandleItem = KeyHandleFromPrivateKey(slot, mWrappingKey,
+ privKey, locker);
if (!keyHandleItem.get()) {
return NS_ERROR_FAILURE;
}
// Sign the challenge using the Attestation privkey (from attestCert)
mozilla::dom::CryptoBuffer signedDataBuf;
if (!signedDataBuf.SetCapacity(1 + aApplicationLen + aChallengeLen +
keyHandleItem->len + kPublicKeyLen,
@@ -545,17 +587,17 @@ nsNSSU2FToken::Register(uint8_t* aApplic
// It's OK to ignore the return values here because we're writing into
// pre-allocated space
signedDataBuf.AppendElement(0x00, mozilla::fallible);
signedDataBuf.AppendElements(aApplication, aApplicationLen, mozilla::fallible);
signedDataBuf.AppendElements(aChallenge, aChallengeLen, mozilla::fallible);
signedDataBuf.AppendSECItem(keyHandleItem.get());
signedDataBuf.AppendSECItem(pubKey->u.ec.publicValue);
- ScopedSECItem signatureItem(::SECITEM_AllocItem(/* default arena */ nullptr,
+ UniqueSECItem signatureItem(::SECITEM_AllocItem(/* default arena */ nullptr,
/* no buffer */ nullptr, 0));
if (!signatureItem) {
return NS_ERROR_OUT_OF_MEMORY;
}
SECStatus srv = SEC_SignData(signatureItem.get(), signedDataBuf.Elements(),
signedDataBuf.Length(), attestPrivKey.get(),
SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
@@ -638,21 +680,20 @@ nsNSSU2FToken::Sign(uint8_t* aApplicatio
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Parameter lengths are wrong! challenge=%d app=%d expected=%d",
aChallengeLen, aApplicationLen, kParamLen));
return NS_ERROR_ILLEGAL_VALUE;
}
// Decode the key handle
- UniqueSECKEYPrivateKey privKey(PrivateKeyFromKeyHandle(slot,
- mWrappingKey.get(),
- aKeyHandle,
- aKeyHandleLen,
- locker));
+ UniqueSECKEYPrivateKey privKey = PrivateKeyFromKeyHandle(slot, mWrappingKey,
+ aKeyHandle,
+ aKeyHandleLen,
+ locker);
if (!privKey.get()) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning, ("Couldn't get the priv key!"));
return NS_ERROR_FAILURE;
}
// Increment the counter and turn it into a SECItem
uint32_t counter = Preferences::GetUint(PREF_U2F_NSSTOKEN_COUNTER) + 1;
Preferences::SetUint(PREF_U2F_NSSTOKEN_COUNTER, counter);
@@ -670,41 +711,41 @@ nsNSSU2FToken::Sign(uint8_t* aApplicatio
// It's OK to ignore the return values here because we're writing into
// pre-allocated space
signedDataBuf.AppendElements(aApplication, aApplicationLen, mozilla::fallible);
signedDataBuf.AppendElement(0x01, mozilla::fallible);
signedDataBuf.AppendSECItem(counterItem);
signedDataBuf.AppendElements(aChallenge, aChallengeLen, mozilla::fallible);
- ScopedSECItem signatureItem(::SECITEM_AllocItem(/* default arena */ nullptr,
+ UniqueSECItem signatureItem(::SECITEM_AllocItem(/* default arena */ nullptr,
/* no buffer */ nullptr, 0));
if (!signatureItem) {
return NS_ERROR_OUT_OF_MEMORY;
}
SECStatus srv = SEC_SignData(signatureItem.get(), signedDataBuf.Elements(),
signedDataBuf.Length(), privKey.get(),
SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
if (srv != SECSuccess) {
MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
("Signature failure: %d", PORT_GetError()));
return NS_ERROR_FAILURE;
}
- // Assmeble the signature data into a buffer for return
+ // Assemble the signature data into a buffer for return
mozilla::dom::CryptoBuffer signatureBuf;
if (!signatureBuf.SetCapacity(1 + counterItem.len + signatureItem->len,
mozilla::fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
// It's OK to ignore the return values here because we're writing into
// pre-allocated space
signatureBuf.AppendElement(0x01, mozilla::fallible);
signatureBuf.AppendSECItem(counterItem);
- signatureBuf.AppendSECItem(signatureItem);
+ signatureBuf.AppendSECItem(signatureItem.get());
if (!signatureBuf.ToNewUnsignedBuffer(aSignature, aSignatureLen)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}