--- a/dom/crypto/CryptoKey.cpp
+++ b/dom/crypto/CryptoKey.cpp
@@ -1,17 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CryptoKey.h"
-#include "ScopedNSSTypes.h"
#include "cryptohi.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsNSSComponent.h"
#include "pk11pub.h"
// Templates taken from security/nss/lib/cryptohi/seckey.c
@@ -80,42 +79,44 @@ DestroyPrivateKeyWithoutDestroyingPKCS11
// generates a random ID for each key. The given template must contain an
// attribute slot for a key ID, but it must consist of a null pointer and have a
// length of 0.
SECKEYPrivateKey*
PrivateKeyFromPrivateKeyTemplate(CK_ATTRIBUTE* aTemplate,
CK_ULONG aTemplateSize)
{
// Create a generic object with the contents of the key
- ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ UniquePK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) {
return nullptr;
}
// Generate a random 160-bit object ID. This ID must be unique.
- ScopedSECItem objID(::SECITEM_AllocItem(nullptr, nullptr, 20));
- SECStatus rv = PK11_GenerateRandomOnSlot(slot, objID->data, objID->len);
+ UniqueSECItem objID(::SECITEM_AllocItem(nullptr, nullptr, 20));
+ SECStatus rv = PK11_GenerateRandomOnSlot(slot.get(), objID->data, objID->len);
if (rv != SECSuccess) {
return nullptr;
}
// Check if something is already using this ID.
- SECKEYPrivateKey* preexistingKey = PK11_FindKeyByKeyID(slot, objID, nullptr);
+ SECKEYPrivateKey* preexistingKey = PK11_FindKeyByKeyID(slot.get(),
+ objID.get(),
+ nullptr);
if (preexistingKey) {
// Note that we can't just call SECKEY_DestroyPrivateKey here because that
// will destroy the PKCS#11 object that is backing a preexisting key (that
// we still have a handle on somewhere else in memory). If that object were
// destroyed, cryptographic operations performed by that other key would
// fail.
DestroyPrivateKeyWithoutDestroyingPKCS11Object(preexistingKey);
// Try again with a new ID (but only once - collisions are very unlikely).
- rv = PK11_GenerateRandomOnSlot(slot, objID->data, objID->len);
+ rv = PK11_GenerateRandomOnSlot(slot.get(), objID->data, objID->len);
if (rv != SECSuccess) {
return nullptr;
}
- preexistingKey = PK11_FindKeyByKeyID(slot, objID, nullptr);
+ preexistingKey = PK11_FindKeyByKeyID(slot.get(), objID.get(), nullptr);
if (preexistingKey) {
DestroyPrivateKeyWithoutDestroyingPKCS11Object(preexistingKey);
return nullptr;
}
}
CK_ATTRIBUTE* idAttributeSlot = nullptr;
for (CK_ULONG i = 0; i < aTemplateSize; i++) {
@@ -128,30 +129,30 @@ PrivateKeyFromPrivateKeyTemplate(CK_ATTR
}
}
if (!idAttributeSlot) {
return nullptr;
}
idAttributeSlot->pValue = objID->data;
idAttributeSlot->ulValueLen = objID->len;
- ScopedPK11GenericObject obj(PK11_CreateGenericObject(slot,
+ UniquePK11GenericObject obj(PK11_CreateGenericObject(slot.get(),
aTemplate,
aTemplateSize,
PR_FALSE));
// Unset the ID attribute slot's pointer and length so that data that only
// lives for the scope of this function doesn't escape.
idAttributeSlot->pValue = nullptr;
idAttributeSlot->ulValueLen = 0;
if (!obj) {
return nullptr;
}
// Have NSS translate the object to a private key.
- return PK11_FindKeyByKeyID(slot, objID, nullptr);
+ return PK11_FindKeyByKeyID(slot.get(), objID.get(), nullptr);
}
CryptoKey::CryptoKey(nsIGlobalObject* aGlobal)
: mGlobal(aGlobal)
, mAttributes(0)
, mSymKey()
, mPrivateKey(nullptr)
, mPublicKey(nullptr)
@@ -326,25 +327,26 @@ CryptoKey::AddPublicKeyData(SECKEYPublic
MOZ_ASSERT(mPrivateKey && mPrivateKey->keyType == ecKey);
// The given public key should have the same key type.
MOZ_ASSERT(aPublicKey->keyType == mPrivateKey->keyType);
nsNSSShutDownPreventionLock locker;
// Read EC params.
ScopedAutoSECItem params;
- SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, mPrivateKey,
+ SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, mPrivateKey.get(),
CKA_EC_PARAMS, ¶ms);
if (rv != SECSuccess) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// Read private value.
ScopedAutoSECItem value;
- rv = PK11_ReadRawAttribute(PK11_TypePrivKey, mPrivateKey, CKA_VALUE, &value);
+ rv = PK11_ReadRawAttribute(PK11_TypePrivKey, mPrivateKey.get(), CKA_VALUE,
+ &value);
if (rv != SECSuccess) {
return NS_ERROR_DOM_OPERATION_ERR;
}
SECItem* point = &aPublicKey->u.ec.publicValue;
CK_OBJECT_CLASS privateKeyValue = CKO_PRIVATE_KEY;
CK_BBOOL falseValue = CK_FALSE;
CK_KEY_TYPE ecValue = CKK_EC;
@@ -357,18 +359,18 @@ CryptoKey::AddPublicKeyData(SECKEYPublic
{ CKA_PRIVATE, &falseValue, sizeof(falseValue) },
// PrivateKeyFromPrivateKeyTemplate sets the ID.
{ CKA_ID, nullptr, 0 },
{ CKA_EC_PARAMS, params.data, params.len },
{ CKA_EC_POINT, point->data, point->len },
{ CKA_VALUE, value.data, value.len },
};
- mPrivateKey = PrivateKeyFromPrivateKeyTemplate(keyTemplate,
- ArrayLength(keyTemplate));
+ mPrivateKey = UniqueSECKEYPrivateKey(
+ PrivateKeyFromPrivateKeyTemplate(keyTemplate, ArrayLength(keyTemplate)));
NS_ENSURE_TRUE(mPrivateKey, NS_ERROR_DOM_OPERATION_ERR);
return NS_OK;
}
void
CryptoKey::ClearUsages()
{
@@ -454,31 +456,31 @@ CryptoKey::SetPrivateKey(SECKEYPrivateKe
{
nsNSSShutDownPreventionLock locker;
if (!aPrivateKey || isAlreadyShutDown()) {
mPrivateKey = nullptr;
return NS_OK;
}
- mPrivateKey = SECKEY_CopyPrivateKey(aPrivateKey);
+ mPrivateKey = UniqueSECKEYPrivateKey(SECKEY_CopyPrivateKey(aPrivateKey));
return mPrivateKey ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
nsresult
CryptoKey::SetPublicKey(SECKEYPublicKey* aPublicKey)
{
nsNSSShutDownPreventionLock locker;
if (!aPublicKey || isAlreadyShutDown()) {
mPublicKey = nullptr;
return NS_OK;
}
- mPublicKey = SECKEY_CopyPublicKey(aPublicKey);
+ mPublicKey = UniqueSECKEYPublicKey(SECKEY_CopyPublicKey(aPublicKey));
return mPublicKey ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
const CryptoBuffer&
CryptoKey::GetSymKey() const
{
return mSymKey;
}
@@ -505,40 +507,40 @@ CryptoKey::GetPublicKey() const
void CryptoKey::virtualDestroyNSSReference()
{
destructorSafeDestroyNSSReference();
}
void CryptoKey::destructorSafeDestroyNSSReference()
{
- mPrivateKey.dispose();
- mPublicKey.dispose();
+ mPrivateKey = nullptr;
+ mPublicKey = nullptr;
}
// Serialization and deserialization convenience methods
SECKEYPrivateKey*
CryptoKey::PrivateKeyFromPkcs8(CryptoBuffer& aKeyData,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
SECKEYPrivateKey* privKey;
- ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ UniquePK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) {
return nullptr;
}
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return nullptr;
}
SECItem pkcs8Item = { siBuffer, nullptr, 0 };
- if (!aKeyData.ToSECItem(arena, &pkcs8Item)) {
+ if (!aKeyData.ToSECItem(arena.get(), &pkcs8Item)) {
return nullptr;
}
// Allow everything, we enforce usage ourselves
unsigned int usage = KU_ALL;
SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot.get(), &pkcs8Item, nullptr, nullptr, false, false,
@@ -549,27 +551,28 @@ CryptoKey::PrivateKeyFromPkcs8(CryptoBuf
}
return privKey;
}
SECKEYPublicKey*
CryptoKey::PublicKeyFromSpki(CryptoBuffer& aKeyData,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return nullptr;
}
SECItem spkiItem = { siBuffer, nullptr, 0 };
- if (!aKeyData.ToSECItem(arena, &spkiItem)) {
+ if (!aKeyData.ToSECItem(arena.get(), &spkiItem)) {
return nullptr;
}
- ScopedCERTSubjectPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem));
+ UniqueCERTSubjectPublicKeyInfo spki(
+ SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem));
if (!spki) {
return nullptr;
}
bool isECDHAlgorithm = SECITEM_ItemsAreEqual(&SEC_OID_DATA_EC_DH,
&spki->algorithm.algorithm);
bool isDHAlgorithm = SECITEM_ItemsAreEqual(&SEC_OID_DATA_DH_KEY_AGREEMENT,
&spki->algorithm.algorithm);
@@ -594,30 +597,30 @@ CryptoKey::PublicKeyFromSpki(CryptoBuffe
SECStatus rv = SECITEM_CopyItem(spki->arena, &spki->algorithm.algorithm,
&oidData->oid);
if (rv != SECSuccess) {
return nullptr;
}
}
- ScopedSECKEYPublicKey tmp(SECKEY_ExtractPublicKey(spki.get()));
+ UniqueSECKEYPublicKey tmp(SECKEY_ExtractPublicKey(spki.get()));
if (!tmp.get() || !PublicKeyValid(tmp.get())) {
return nullptr;
}
- return SECKEY_CopyPublicKey(tmp);
+ return SECKEY_CopyPublicKey(tmp.get());
}
nsresult
CryptoKey::PrivateKeyToPkcs8(SECKEYPrivateKey* aPrivKey,
CryptoBuffer& aRetVal,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
- ScopedSECItem pkcs8Item(PK11_ExportDERPrivateKeyInfo(aPrivKey, nullptr));
+ UniqueSECItem pkcs8Item(PK11_ExportDERPrivateKeyInfo(aPrivKey, nullptr));
if (!pkcs8Item.get()) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
if (!aRetVal.Assign(pkcs8Item.get())) {
return NS_ERROR_DOM_OPERATION_ERR;
}
return NS_OK;
}
@@ -656,41 +659,41 @@ PublicDhKeyToSpki(SECKEYPublicKey* aPubK
return NS_OK;
}
nsresult
CryptoKey::PublicKeyToSpki(SECKEYPublicKey* aPubKey,
CryptoBuffer& aRetVal,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
- ScopedCERTSubjectPublicKeyInfo spki;
+ UniqueCERTSubjectPublicKeyInfo spki;
// NSS doesn't support exporting DH public keys.
if (aPubKey->keyType == dhKey) {
// Mimic the behavior of SECKEY_CreateSubjectPublicKeyInfo() and create
// a new arena for the SPKI object.
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return NS_ERROR_DOM_OPERATION_ERR;
}
- spki = PORT_ArenaZNew(arena, CERTSubjectPublicKeyInfo);
+ spki.reset(PORT_ArenaZNew(arena.get(), CERTSubjectPublicKeyInfo));
if (!spki) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// Assign |arena| to |spki| and null the variable afterwards so that the
// arena created above that holds the SPKI object is free'd when |spki|
// goes out of scope, not when |arena| does.
- spki->arena = arena.forget();
+ spki->arena = arena.release();
- nsresult rv = PublicDhKeyToSpki(aPubKey, spki);
+ nsresult rv = PublicDhKeyToSpki(aPubKey, spki.get());
NS_ENSURE_SUCCESS(rv, rv);
} else {
- spki = SECKEY_CreateSubjectPublicKeyInfo(aPubKey);
+ spki.reset(SECKEY_CreateSubjectPublicKeyInfo(aPubKey));
if (!spki) {
return NS_ERROR_DOM_OPERATION_ERR;
}
}
// Per WebCrypto spec we must export ECDH SPKIs with the algorithm OID
// id-ecDH (1.3.132.112) and DH SPKIs with OID dhKeyAgreement
// (1.2.840.113549.1.3.1). NSS doesn't know about these OIDs and there is
@@ -708,17 +711,17 @@ CryptoKey::PublicKeyToSpki(SECKEYPublicK
SECStatus rv = SECITEM_CopyItem(spki->arena, &spki->algorithm.algorithm,
oidData);
if (rv != SECSuccess) {
return NS_ERROR_DOM_OPERATION_ERR;
}
}
const SEC_ASN1Template* tpl = SEC_ASN1_GET(CERT_SubjectPublicKeyInfoTemplate);
- ScopedSECItem spkiItem(SEC_ASN1EncodeItem(nullptr, nullptr, spki, tpl));
+ UniqueSECItem spkiItem(SEC_ASN1EncodeItem(nullptr, nullptr, spki.get(), tpl));
if (!aRetVal.Assign(spkiItem.get())) {
return NS_ERROR_DOM_OPERATION_ERR;
}
return NS_OK;
}
SECItem*
@@ -762,17 +765,17 @@ CryptoKey::PrivateKeyFromJwk(const JsonW
return nullptr;
}
nsString namedCurve;
if (!NormalizeToken(aJwk.mCrv.Value(), namedCurve)) {
return nullptr;
}
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return nullptr;
}
// Create parameters.
SECItem* params = CreateECParamsForCurve(namedCurve, arena.get());
if (!params) {
return nullptr;
@@ -811,21 +814,16 @@ CryptoKey::PrivateKeyFromJwk(const JsonW
!aJwk.mP.WasPassed() || NS_FAILED(p.FromJwkBase64(aJwk.mP.Value())) ||
!aJwk.mQ.WasPassed() || NS_FAILED(q.FromJwkBase64(aJwk.mQ.Value())) ||
!aJwk.mDp.WasPassed() || NS_FAILED(dp.FromJwkBase64(aJwk.mDp.Value())) ||
!aJwk.mDq.WasPassed() || NS_FAILED(dq.FromJwkBase64(aJwk.mDq.Value())) ||
!aJwk.mQi.WasPassed() || NS_FAILED(qi.FromJwkBase64(aJwk.mQi.Value()))) {
return nullptr;
}
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
- if (!arena) {
- return nullptr;
- }
-
// Populate template from parameters
CK_KEY_TYPE rsaValue = CKK_RSA;
CK_ATTRIBUTE keyTemplate[14] = {
{ CKA_CLASS, &privateKeyValue, sizeof(privateKeyValue) },
{ CKA_KEY_TYPE, &rsaValue, sizeof(rsaValue) },
{ CKA_TOKEN, &falseValue, sizeof(falseValue) },
{ CKA_SENSITIVE, &falseValue, sizeof(falseValue) },
{ CKA_PRIVATE, &falseValue, sizeof(falseValue) },
@@ -910,29 +908,31 @@ ECKeyToJwk(const PK11ObjectType aKeyType
return false;
}
// Check length of uncompressed point coordinates.
if (aPublicValue->len != (2 * flen + 1)) {
return false;
}
- ScopedSECItem ecPointX(::SECITEM_AllocItem(nullptr, nullptr, flen));
- ScopedSECItem ecPointY(::SECITEM_AllocItem(nullptr, nullptr, flen));
+ UniqueSECItem ecPointX(::SECITEM_AllocItem(nullptr, nullptr, flen));
+ UniqueSECItem ecPointY(::SECITEM_AllocItem(nullptr, nullptr, flen));
if (!ecPointX || !ecPointY) {
return false;
}
// Extract point data.
memcpy(ecPointX->data, aPublicValue->data + 1, flen);
memcpy(ecPointY->data, aPublicValue->data + 1 + flen, flen);
CryptoBuffer x, y;
- if (!x.Assign(ecPointX) || NS_FAILED(x.ToJwkBase64(aRetVal.mX.Value())) ||
- !y.Assign(ecPointY) || NS_FAILED(y.ToJwkBase64(aRetVal.mY.Value()))) {
+ if (!x.Assign(ecPointX.get()) ||
+ NS_FAILED(x.ToJwkBase64(aRetVal.mX.Value())) ||
+ !y.Assign(ecPointY.get()) ||
+ NS_FAILED(y.ToJwkBase64(aRetVal.mY.Value()))) {
return false;
}
aRetVal.mKty = NS_LITERAL_STRING(JWK_TYPE_EC);
return true;
}
nsresult
@@ -998,51 +998,51 @@ CryptoKey::PrivateKeyToJwk(SECKEYPrivate
default:
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
}
SECKEYPublicKey*
CreateECPublicKey(const SECItem* aKeyData, const nsString& aNamedCurve)
{
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return nullptr;
}
- // It's important that this be a ScopedSECKEYPublicKey, as this ensures that
+ // It's important that this be a UniqueSECKEYPublicKey, as this ensures that
// SECKEY_DestroyPublicKey will be called on it. If this doesn't happen, when
// CryptoKey::PublicKeyValid is called on it and it gets moved to the internal
// PKCS#11 slot, it will leak a reference to the slot.
- ScopedSECKEYPublicKey key(PORT_ArenaZNew(arena, SECKEYPublicKey));
+ UniqueSECKEYPublicKey key(PORT_ArenaZNew(arena.get(), SECKEYPublicKey));
if (!key) {
return nullptr;
}
key->arena = nullptr; // key doesn't own the arena; it won't get double-freed
key->keyType = ecKey;
key->pkcs11Slot = nullptr;
key->pkcs11ID = CK_INVALID_HANDLE;
// Create curve parameters.
- SECItem* params = CreateECParamsForCurve(aNamedCurve, arena);
+ SECItem* params = CreateECParamsForCurve(aNamedCurve, arena.get());
if (!params) {
return nullptr;
}
key->u.ec.DEREncodedParams = *params;
// Set public point.
key->u.ec.publicValue = *aKeyData;
// Ensure the given point is on the curve.
- if (!CryptoKey::PublicKeyValid(key)) {
+ if (!CryptoKey::PublicKeyValid(key.get())) {
return nullptr;
}
- return SECKEY_CopyPublicKey(key);
+ return SECKEY_CopyPublicKey(key.get());
}
SECKEYPublicKey*
CryptoKey::PublicKeyFromJwk(const JsonWebKey& aJwk,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
if (aJwk.mKty.EqualsLiteral(JWK_TYPE_RSA)) {
// Verify that all of the required parameters are present
@@ -1063,17 +1063,17 @@ CryptoKey::PublicKeyFromJwk(const JsonWe
};
const SEC_ASN1Template rsaPublicKeyTemplate[] = {
{SEC_ASN1_SEQUENCE, 0, nullptr, sizeof(RSAPublicKeyData)},
{SEC_ASN1_INTEGER, offsetof(RSAPublicKeyData, n),},
{SEC_ASN1_INTEGER, offsetof(RSAPublicKeyData, e),},
{0,}
};
- ScopedSECItem pkDer(SEC_ASN1EncodeItem(nullptr, nullptr, &input,
+ UniqueSECItem pkDer(SEC_ASN1EncodeItem(nullptr, nullptr, &input,
rsaPublicKeyTemplate));
if (!pkDer.get()) {
return nullptr;
}
return SECKEY_ImportDERPublicKey(pkDer.get(), CKK_RSA);
}
@@ -1081,17 +1081,17 @@ CryptoKey::PublicKeyFromJwk(const JsonWe
// Verify that all of the required parameters are present
CryptoBuffer x, y;
if (!aJwk.mCrv.WasPassed() ||
!aJwk.mX.WasPassed() || NS_FAILED(x.FromJwkBase64(aJwk.mX.Value())) ||
!aJwk.mY.WasPassed() || NS_FAILED(y.FromJwkBase64(aJwk.mY.Value()))) {
return nullptr;
}
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return nullptr;
}
// Create point.
SECItem* point = CreateECPointForCoordinates(x, y, arena.get());
if (!point) {
return nullptr;
@@ -1141,34 +1141,34 @@ CryptoKey::PublicKeyToJwk(SECKEYPublicKe
}
SECKEYPublicKey*
CryptoKey::PublicDhKeyFromRaw(CryptoBuffer& aKeyData,
const CryptoBuffer& aPrime,
const CryptoBuffer& aGenerator,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return nullptr;
}
- SECKEYPublicKey* key = PORT_ArenaZNew(arena, SECKEYPublicKey);
+ SECKEYPublicKey* key = PORT_ArenaZNew(arena.get(), SECKEYPublicKey);
if (!key) {
return nullptr;
}
key->keyType = dhKey;
key->pkcs11Slot = nullptr;
key->pkcs11ID = CK_INVALID_HANDLE;
// Set DH public key params.
- if (!aPrime.ToSECItem(arena, &key->u.dh.prime) ||
- !aGenerator.ToSECItem(arena, &key->u.dh.base) ||
- !aKeyData.ToSECItem(arena, &key->u.dh.publicValue)) {
+ if (!aPrime.ToSECItem(arena.get(), &key->u.dh.prime) ||
+ !aGenerator.ToSECItem(arena.get(), &key->u.dh.base) ||
+ !aKeyData.ToSECItem(arena.get(), &key->u.dh.publicValue)) {
return nullptr;
}
key->u.dh.prime.type = siUnsignedInteger;
key->u.dh.base.type = siUnsignedInteger;
key->u.dh.publicValue.type = siUnsignedInteger;
return SECKEY_CopyPublicKey(key);
@@ -1185,23 +1185,23 @@ CryptoKey::PublicDhKeyToRaw(SECKEYPublic
return NS_OK;
}
SECKEYPublicKey*
CryptoKey::PublicECKeyFromRaw(CryptoBuffer& aKeyData,
const nsString& aNamedCurve,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return nullptr;
}
SECItem rawItem = { siBuffer, nullptr, 0 };
- if (!aKeyData.ToSECItem(arena, &rawItem)) {
+ if (!aKeyData.ToSECItem(arena.get(), &rawItem)) {
return nullptr;
}
uint32_t flen;
if (aNamedCurve.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P256)) {
flen = 32; // bytes
} else if (aNamedCurve.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P384)) {
flen = 48; // bytes
@@ -1234,30 +1234,30 @@ CryptoKey::PublicECKeyToRaw(SECKEYPublic
return NS_ERROR_DOM_OPERATION_ERR;
}
return NS_OK;
}
bool
CryptoKey::PublicKeyValid(SECKEYPublicKey* aPubKey)
{
- ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ UniquePK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot.get()) {
return false;
}
// This assumes that NSS checks the validity of a public key when
// it is imported into a PKCS#11 module, and returns CK_INVALID_HANDLE
// if it is invalid.
- CK_OBJECT_HANDLE id = PK11_ImportPublicKey(slot, aPubKey, PR_FALSE);
+ CK_OBJECT_HANDLE id = PK11_ImportPublicKey(slot.get(), aPubKey, PR_FALSE);
if (id == CK_INVALID_HANDLE) {
return false;
}
- SECStatus rv = PK11_DestroyObject(slot, id);
+ SECStatus rv = PK11_DestroyObject(slot.get(), id);
return (rv == SECSuccess);
}
bool
CryptoKey::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
@@ -1268,23 +1268,24 @@ CryptoKey::WriteStructuredClone(JSStruct
// 1. Attributes
// 2. Symmetric key as raw (if present)
// 3. Private key as pkcs8 (if present)
// 4. Public key as spki (if present)
// 5. Algorithm in whatever form it chooses
CryptoBuffer priv, pub;
if (mPrivateKey) {
- if (NS_FAILED(CryptoKey::PrivateKeyToPkcs8(mPrivateKey, priv, locker))) {
+ if (NS_FAILED(CryptoKey::PrivateKeyToPkcs8(mPrivateKey.get(), priv,
+ locker))) {
return false;
}
}
if (mPublicKey) {
- if (NS_FAILED(CryptoKey::PublicKeyToSpki(mPublicKey, pub, locker))) {
+ if (NS_FAILED(CryptoKey::PublicKeyToSpki(mPublicKey.get(), pub, locker))) {
return false;
}
}
return JS_WriteUint32Pair(aWriter, mAttributes, CRYPTOKEY_SC_VERSION) &&
WriteBuffer(aWriter, mSymKey) &&
WriteBuffer(aWriter, priv) &&
WriteBuffer(aWriter, pub) &&
@@ -1316,20 +1317,22 @@ CryptoKey::ReadStructuredClone(JSStructu
if (!read) {
return false;
}
if (sym.Length() > 0 && !mSymKey.Assign(sym)) {
return false;
}
if (priv.Length() > 0) {
- mPrivateKey = CryptoKey::PrivateKeyFromPkcs8(priv, locker);
+ mPrivateKey = UniqueSECKEYPrivateKey(
+ CryptoKey::PrivateKeyFromPkcs8(priv, locker));
}
if (pub.Length() > 0) {
- mPublicKey = CryptoKey::PublicKeyFromSpki(pub, locker);
+ mPublicKey = UniqueSECKEYPublicKey(
+ CryptoKey::PublicKeyFromSpki(pub, locker));
}
// Ensure that what we've read is consistent
// If the attributes indicate a key type, should have a key of that type
if (!((GetKeyType() == SECRET && mSymKey.Length() > 0) ||
(GetKeyType() == PRIVATE && mPrivateKey) ||
(GetKeyType() == PUBLIC && mPublicKey))) {
return false;