--- a/dom/crypto/WebCryptoTask.cpp
+++ b/dom/crypto/WebCryptoTask.cpp
@@ -2,17 +2,16 @@
/* 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 "pk11pub.h"
#include "cryptohi.h"
#include "secerr.h"
-#include "ScopedNSSTypes.h"
#include "nsNSSComponent.h"
#include "nsProxyRelease.h"
#include "jsapi.h"
#include "mozilla/Telemetry.h"
#include "mozilla/dom/CryptoBuffer.h"
#include "mozilla/dom/CryptoKey.h"
#include "mozilla/dom/KeyAlgorithmProxy.h"
@@ -665,28 +664,28 @@ private:
virtual nsresult DoCrypto() override
{
nsresult rv;
if (!mDataIsSet) {
return NS_ERROR_DOM_OPERATION_ERR;
}
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// Construct the parameters object depending on algorithm
SECItem param = { siBuffer, nullptr, 0 };
CK_AES_CTR_PARAMS ctrParams;
CK_GCM_PARAMS gcmParams;
switch (mMechanism) {
case CKM_AES_CBC_PAD:
- ATTEMPT_BUFFER_TO_SECITEM(arena, ¶m, mIv);
+ ATTEMPT_BUFFER_TO_SECITEM(arena.get(), ¶m, mIv);
break;
case CKM_AES_CTR:
ctrParams.ulCounterBits = mCounterLength;
MOZ_ASSERT(mIv.Length() == 16);
memcpy(&ctrParams.cb, mIv.Elements(), 16);
param.type = siBuffer;
param.data = (unsigned char*) &ctrParams;
param.len = sizeof(ctrParams);
@@ -702,21 +701,22 @@ private:
param.len = sizeof(gcmParams);
break;
default:
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
// Import the key
SECItem keyItem = { siBuffer, nullptr, 0 };
- ATTEMPT_BUFFER_TO_SECITEM(arena, &keyItem, mSymKey);
- ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ ATTEMPT_BUFFER_TO_SECITEM(arena.get(), &keyItem, mSymKey);
+ UniquePK11SlotInfo slot(PK11_GetInternalSlot());
MOZ_ASSERT(slot.get());
- ScopedPK11SymKey symKey(PK11_ImportSymKey(slot, mMechanism, PK11_OriginUnwrap,
- CKA_ENCRYPT, &keyItem, nullptr));
+ UniquePK11SymKey symKey(PK11_ImportSymKey(slot.get(), mMechanism,
+ PK11_OriginUnwrap, CKA_ENCRYPT,
+ &keyItem, nullptr));
if (!symKey) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
// Initialize the output buffer (enough space for padding / a full tag)
uint32_t dataLen = mData.Length();
uint32_t maxLen = dataLen + 16;
if (!mResult.SetLength(maxLen, fallible)) {
@@ -805,43 +805,44 @@ private:
return NS_ERROR_DOM_OPERATION_ERR;
}
// Check that the input is a multiple of 64 bits long
if (mData.Length() == 0 || mData.Length() % 8 != 0) {
return NS_ERROR_DOM_DATA_ERR;
}
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// Import the key
SECItem keyItem = { siBuffer, nullptr, 0 };
- ATTEMPT_BUFFER_TO_SECITEM(arena, &keyItem, mSymKey);
- ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ ATTEMPT_BUFFER_TO_SECITEM(arena.get(), &keyItem, mSymKey);
+ UniquePK11SlotInfo slot(PK11_GetInternalSlot());
MOZ_ASSERT(slot.get());
- ScopedPK11SymKey symKey(PK11_ImportSymKey(slot, mMechanism, PK11_OriginUnwrap,
- CKA_WRAP, &keyItem, nullptr));
+ UniquePK11SymKey symKey(PK11_ImportSymKey(slot.get(), mMechanism,
+ PK11_OriginUnwrap, CKA_WRAP,
+ &keyItem, nullptr));
if (!symKey) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
// Import the data to a SECItem
SECItem dataItem = { siBuffer, nullptr, 0 };
- ATTEMPT_BUFFER_TO_SECITEM(arena, &dataItem, mData);
+ ATTEMPT_BUFFER_TO_SECITEM(arena.get(), &dataItem, mData);
// Parameters for the fake keys
CK_MECHANISM_TYPE fakeMechanism = CKM_SHA_1_HMAC;
CK_ATTRIBUTE_TYPE fakeOperation = CKA_SIGN;
if (mEncrypt) {
// Import the data into a fake PK11SymKey structure
- ScopedPK11SymKey keyToWrap(PK11_ImportSymKey(slot, fakeMechanism,
+ UniquePK11SymKey keyToWrap(PK11_ImportSymKey(slot.get(), fakeMechanism,
PK11_OriginUnwrap, fakeOperation,
&dataItem, nullptr));
if (!keyToWrap) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// Encrypt and return the wrapped key
// AES-KW encryption results in a wrapped key 64 bits longer
@@ -852,29 +853,29 @@ private:
(unsigned int) mResult.Length()};
rv = MapSECStatus(PK11_WrapSymKey(mMechanism, nullptr, symKey.get(),
keyToWrap.get(), &resultItem));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_OPERATION_ERR);
} else {
// Decrypt the ciphertext into a temporary PK11SymKey
// Unwrapped key should be 64 bits shorter
int keySize = mData.Length() - 8;
- ScopedPK11SymKey unwrappedKey(PK11_UnwrapSymKey(symKey, mMechanism, nullptr,
- &dataItem, fakeMechanism,
- fakeOperation, keySize));
+ UniquePK11SymKey unwrappedKey(
+ PK11_UnwrapSymKey(symKey.get(), mMechanism, nullptr, &dataItem,
+ fakeMechanism, fakeOperation, keySize));
if (!unwrappedKey) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// Export the key to get the cleartext
- rv = MapSECStatus(PK11_ExtractKeyValue(unwrappedKey));
+ rv = MapSECStatus(PK11_ExtractKeyValue(unwrappedKey.get()));
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
- ATTEMPT_BUFFER_ASSIGN(mResult, PK11_GetKeyData(unwrappedKey));
+ ATTEMPT_BUFFER_ASSIGN(mResult, PK11_GetKeyData(unwrappedKey.get()));
}
return rv;
}
};
class RsaOaepTask : public ReturnArrayBufferViewTask,
public DeferredData
@@ -907,23 +908,23 @@ public:
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_RSA_OAEP);
if (mEncrypt) {
if (!mPubKey) {
mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR;
return;
}
- mStrength = SECKEY_PublicKeyStrength(mPubKey);
+ mStrength = SECKEY_PublicKeyStrength(mPubKey.get());
} else {
if (!mPrivKey) {
mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR;
return;
}
- mStrength = PK11_GetPrivateModulusLen(mPrivKey);
+ mStrength = PK11_GetPrivateModulusLen(mPrivKey.get());
}
// The algorithm could just be given as a string
// in which case there would be no label specified.
if (!aAlgorithm.IsString()) {
RootedDictionary<RsaOaepParams> params(aCx);
mEarlyRv = Coerce(aCx, params, aAlgorithm);
if (NS_FAILED(mEarlyRv)) {
@@ -947,18 +948,18 @@ public:
mEarlyRv = NS_ERROR_DOM_NOT_SUPPORTED_ERR;
return;
}
}
private:
CK_MECHANISM_TYPE mHashMechanism;
CK_MECHANISM_TYPE mMgfMechanism;
- ScopedSECKEYPrivateKey mPrivKey;
- ScopedSECKEYPublicKey mPubKey;
+ UniqueSECKEYPrivateKey mPrivKey;
+ UniqueSECKEYPublicKey mPubKey;
CryptoBuffer mLabel;
uint32_t mStrength;
bool mEncrypt;
virtual nsresult DoCrypto() override
{
nsresult rv;
@@ -1057,29 +1058,30 @@ private:
virtual nsresult DoCrypto() override
{
// Initialize the output buffer
if (!mResult.SetLength(HASH_LENGTH_MAX, fallible)) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// Import the key
uint32_t outLen;
SECItem keyItem = { siBuffer, nullptr, 0 };
- ATTEMPT_BUFFER_TO_SECITEM(arena, &keyItem, mSymKey);
- ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ ATTEMPT_BUFFER_TO_SECITEM(arena.get(), &keyItem, mSymKey);
+ UniquePK11SlotInfo slot(PK11_GetInternalSlot());
MOZ_ASSERT(slot.get());
- ScopedPK11SymKey symKey(PK11_ImportSymKey(slot, mMechanism, PK11_OriginUnwrap,
- CKA_SIGN, &keyItem, nullptr));
+ UniquePK11SymKey symKey(PK11_ImportSymKey(slot.get(), mMechanism,
+ PK11_OriginUnwrap, CKA_SIGN,
+ &keyItem, nullptr));
if (!symKey) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
// Compute the MAC
SECItem param = { siBuffer, nullptr, 0 };
UniquePK11Context ctx(PK11_CreateContextBySymKey(mMechanism, CKA_SIGN,
symKey.get(), ¶m));
@@ -1221,51 +1223,53 @@ public:
return;
}
}
private:
SECOidTag mOidTag;
CK_MECHANISM_TYPE mHashMechanism;
CK_MECHANISM_TYPE mMgfMechanism;
- ScopedSECKEYPrivateKey mPrivKey;
- ScopedSECKEYPublicKey mPubKey;
+ UniqueSECKEYPrivateKey mPrivKey;
+ UniqueSECKEYPublicKey mPubKey;
CryptoBuffer mSignature;
CryptoBuffer mData;
uint32_t mSaltLength;
bool mSign;
bool mVerified;
// The signature algorithm to use.
enum class Algorithm: uint8_t {ECDSA, RSA_PKCS1, RSA_PSS, UNKNOWN};
Algorithm mAlgorithm;
virtual nsresult DoCrypto() override
{
SECStatus rv;
- ScopedSECItem hash(::SECITEM_AllocItem(nullptr, nullptr,
+ UniqueSECItem hash(::SECITEM_AllocItem(nullptr, nullptr,
HASH_ResultLenByOidTag(mOidTag)));
if (!hash) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// Compute digest over given data.
rv = PK11_HashBuf(mOidTag, hash->data, mData.Elements(), mData.Length());
NS_ENSURE_SUCCESS(MapSECStatus(rv), NS_ERROR_DOM_OPERATION_ERR);
// Wrap hash in a digest info template (RSA-PKCS1 only).
if (mAlgorithm == Algorithm::RSA_PKCS1) {
- ScopedSGNDigestInfo di(SGN_CreateDigestInfo(mOidTag, hash->data, hash->len));
+ UniqueSGNDigestInfo di(SGN_CreateDigestInfo(mOidTag, hash->data,
+ hash->len));
if (!di) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// Reuse |hash|.
- SECITEM_FreeItem(hash, false);
- if (!SEC_ASN1EncodeItem(nullptr, hash, di, SGN_DigestInfoTemplate)) {
+ SECITEM_FreeItem(hash.get(), false);
+ if (!SEC_ASN1EncodeItem(nullptr, hash.get(), di.get(),
+ SGN_DigestInfoTemplate)) {
return NS_ERROR_DOM_OPERATION_ERR;
}
}
SECItem* params = nullptr;
CK_MECHANISM_TYPE mech = PK11_MapSignKeyType((mSign ? mPrivKey->keyType :
mPubKey->keyType));
@@ -1281,35 +1285,37 @@ private:
rsaPssParamsItem.data = (unsigned char*)&rsaPssParams;
rsaPssParamsItem.len = sizeof(rsaPssParams);
params = &rsaPssParamsItem;
mech = CKM_RSA_PKCS_PSS;
}
// Allocate SECItem to hold the signature.
- uint32_t len = mSign ? PK11_SignatureLen(mPrivKey) : 0;
- ScopedSECItem sig(::SECITEM_AllocItem(nullptr, nullptr, len));
+ uint32_t len = mSign ? PK11_SignatureLen(mPrivKey.get()) : 0;
+ UniqueSECItem sig(::SECITEM_AllocItem(nullptr, nullptr, len));
if (!sig) {
return NS_ERROR_DOM_OPERATION_ERR;
}
if (mSign) {
// Sign the hash.
- rv = PK11_SignWithMechanism(mPrivKey, mech, params, sig, hash);
+ rv = PK11_SignWithMechanism(mPrivKey.get(), mech, params, sig.get(),
+ hash.get());
NS_ENSURE_SUCCESS(MapSECStatus(rv), NS_ERROR_DOM_OPERATION_ERR);
- ATTEMPT_BUFFER_ASSIGN(mSignature, sig);
+ ATTEMPT_BUFFER_ASSIGN(mSignature, sig.get());
} else {
// Copy the given signature to the SECItem.
- if (!mSignature.ToSECItem(nullptr, sig)) {
+ if (!mSignature.ToSECItem(nullptr, sig.get())) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// Verify the signature.
- rv = PK11_VerifyWithMechanism(mPubKey, mech, params, sig, hash, nullptr);
+ rv = PK11_VerifyWithMechanism(mPubKey.get(), mech, params, sig.get(),
+ hash.get(), nullptr);
mVerified = NS_SUCCEEDED(MapSECStatus(rv));
}
return NS_OK;
}
virtual void Resolve() override
{
@@ -1762,57 +1768,61 @@ private:
uint32_t mModulusLength;
CryptoBuffer mPublicExponent;
virtual nsresult DoCrypto() override
{
nsNSSShutDownPreventionLock locker;
// Import the key data itself
- ScopedSECKEYPublicKey pubKey;
- ScopedSECKEYPrivateKey privKey;
+ UniqueSECKEYPublicKey pubKey;
+ UniqueSECKEYPrivateKey privKey;
if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI) ||
(mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK) &&
!mJwk.mD.WasPassed())) {
// Public key import
if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI)) {
- pubKey = CryptoKey::PublicKeyFromSpki(mKeyData, locker);
+ pubKey = UniqueSECKEYPublicKey(
+ CryptoKey::PublicKeyFromSpki(mKeyData, locker));
} else {
- pubKey = CryptoKey::PublicKeyFromJwk(mJwk, locker);
+ pubKey = UniqueSECKEYPublicKey(
+ CryptoKey::PublicKeyFromJwk(mJwk, locker));
}
if (!pubKey) {
return NS_ERROR_DOM_DATA_ERR;
}
if (NS_FAILED(mKey->SetPublicKey(pubKey.get()))) {
return NS_ERROR_DOM_OPERATION_ERR;
}
mKey->SetType(CryptoKey::PUBLIC);
} else if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_PKCS8) ||
(mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK) &&
mJwk.mD.WasPassed())) {
// Private key import
if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_PKCS8)) {
- privKey = CryptoKey::PrivateKeyFromPkcs8(mKeyData, locker);
+ privKey = UniqueSECKEYPrivateKey(
+ CryptoKey::PrivateKeyFromPkcs8(mKeyData, locker));
} else {
- privKey = CryptoKey::PrivateKeyFromJwk(mJwk, locker);
+ privKey = UniqueSECKEYPrivateKey(
+ CryptoKey::PrivateKeyFromJwk(mJwk, locker));
}
if (!privKey) {
return NS_ERROR_DOM_DATA_ERR;
}
if (NS_FAILED(mKey->SetPrivateKey(privKey.get()))) {
return NS_ERROR_DOM_OPERATION_ERR;
}
mKey->SetType(CryptoKey::PRIVATE);
- pubKey = SECKEY_ConvertToPublicKey(privKey.get());
+ pubKey = UniqueSECKEYPublicKey(SECKEY_ConvertToPublicKey(privKey.get()));
if (!pubKey) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
} else {
// Invalid key format
return NS_ERROR_DOM_SYNTAX_ERR;
}
@@ -1908,43 +1918,47 @@ public:
}
private:
nsString mNamedCurve;
virtual nsresult DoCrypto() override
{
// Import the key data itself
- ScopedSECKEYPublicKey pubKey;
- ScopedSECKEYPrivateKey privKey;
+ UniqueSECKEYPublicKey pubKey;
+ UniqueSECKEYPrivateKey privKey;
nsNSSShutDownPreventionLock locker;
if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK) && mJwk.mD.WasPassed()) {
// Private key import
- privKey = CryptoKey::PrivateKeyFromJwk(mJwk, locker);
+ privKey = UniqueSECKEYPrivateKey(
+ CryptoKey::PrivateKeyFromJwk(mJwk, locker));
if (!privKey) {
return NS_ERROR_DOM_DATA_ERR;
}
if (NS_FAILED(mKey->SetPrivateKey(privKey.get()))) {
return NS_ERROR_DOM_OPERATION_ERR;
}
mKey->SetType(CryptoKey::PRIVATE);
} else if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW) ||
mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI) ||
(mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK) &&
!mJwk.mD.WasPassed())) {
// Public key import
if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW)) {
- pubKey = CryptoKey::PublicECKeyFromRaw(mKeyData, mNamedCurve, locker);
+ pubKey = UniqueSECKEYPublicKey(
+ CryptoKey::PublicECKeyFromRaw(mKeyData, mNamedCurve, locker));
} else if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI)) {
- pubKey = CryptoKey::PublicKeyFromSpki(mKeyData, locker);
+ pubKey = UniqueSECKEYPublicKey(
+ CryptoKey::PublicKeyFromSpki(mKeyData, locker));
} else if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK)) {
- pubKey = CryptoKey::PublicKeyFromJwk(mJwk, locker);
+ pubKey = UniqueSECKEYPublicKey(
+ CryptoKey::PublicKeyFromJwk(mJwk, locker));
} else {
MOZ_ASSERT(false);
}
if (!pubKey) {
return NS_ERROR_DOM_DATA_ERR;
}
@@ -2061,26 +2075,28 @@ public:
private:
CryptoBuffer mPrime;
CryptoBuffer mGenerator;
virtual nsresult DoCrypto() override
{
// Import the key data itself
- ScopedSECKEYPublicKey pubKey;
+ UniqueSECKEYPublicKey pubKey;
nsNSSShutDownPreventionLock locker;
if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW) ||
mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI)) {
// Public key import
if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW)) {
- pubKey = CryptoKey::PublicDhKeyFromRaw(mKeyData, mPrime, mGenerator, locker);
+ pubKey = UniqueSECKEYPublicKey(
+ CryptoKey::PublicDhKeyFromRaw(mKeyData, mPrime, mGenerator, locker));
} else if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI)) {
- pubKey = CryptoKey::PublicKeyFromSpki(mKeyData, locker);
+ pubKey = UniqueSECKEYPublicKey(
+ CryptoKey::PublicKeyFromSpki(mKeyData, locker));
} else {
MOZ_ASSERT(false);
}
if (!pubKey) {
return NS_ERROR_DOM_DATA_ERR;
}
@@ -2129,47 +2145,49 @@ public:
{
aKey.GetUsages(mKeyUsages);
}
protected:
nsString mFormat;
CryptoBuffer mSymKey;
- ScopedSECKEYPrivateKey mPrivateKey;
- ScopedSECKEYPublicKey mPublicKey;
+ UniqueSECKEYPrivateKey mPrivateKey;
+ UniqueSECKEYPublicKey mPublicKey;
CryptoKey::KeyType mKeyType;
bool mExtractable;
nsString mAlg;
nsTArray<nsString> mKeyUsages;
CryptoBuffer mResult;
JsonWebKey mJwk;
private:
virtual void ReleaseNSSResources() override
{
- mPrivateKey.dispose();
- mPublicKey.dispose();
+ mPrivateKey = nullptr;
+ mPublicKey = nullptr;
}
virtual nsresult DoCrypto() override
{
nsNSSShutDownPreventionLock locker;
if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW)) {
if (mPublicKey && mPublicKey->keyType == dhKey) {
- nsresult rv = CryptoKey::PublicDhKeyToRaw(mPublicKey, mResult, locker);
+ nsresult rv = CryptoKey::PublicDhKeyToRaw(mPublicKey.get(), mResult,
+ locker);
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_OPERATION_ERR;
}
return NS_OK;
}
if (mPublicKey && mPublicKey->keyType == ecKey) {
- nsresult rv = CryptoKey::PublicECKeyToRaw(mPublicKey, mResult, locker);
+ nsresult rv = CryptoKey::PublicECKeyToRaw(mPublicKey.get(), mResult,
+ locker);
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_OPERATION_ERR;
}
return NS_OK;
}
mResult = mSymKey;
if (mResult.Length() == 0) {
@@ -2208,26 +2226,27 @@ private:
}
mJwk.mK.Construct(k);
mJwk.mKty = NS_LITERAL_STRING(JWK_TYPE_SYMMETRIC);
} else if (mKeyType == CryptoKey::PUBLIC) {
if (!mPublicKey) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
- nsresult rv = CryptoKey::PublicKeyToJwk(mPublicKey, mJwk, locker);
+ nsresult rv = CryptoKey::PublicKeyToJwk(mPublicKey.get(), mJwk, locker);
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_OPERATION_ERR;
}
} else if (mKeyType == CryptoKey::PRIVATE) {
if (!mPrivateKey) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
- nsresult rv = CryptoKey::PrivateKeyToJwk(mPrivateKey, mJwk, locker);
+ nsresult rv = CryptoKey::PrivateKeyToJwk(mPrivateKey.get(), mJwk,
+ locker);
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_OPERATION_ERR;
}
}
if (!mAlg.IsEmpty()) {
mJwk.mAlg.Construct(mAlg);
}
@@ -2342,34 +2361,34 @@ public:
private:
RefPtr<CryptoKey> mKey;
size_t mLength;
CK_MECHANISM_TYPE mMechanism;
CryptoBuffer mKeyData;
virtual nsresult DoCrypto() override
{
- ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ UniquePK11SlotInfo slot(PK11_GetInternalSlot());
MOZ_ASSERT(slot.get());
- ScopedPK11SymKey symKey(PK11_KeyGen(slot.get(), mMechanism, nullptr,
+ UniquePK11SymKey symKey(PK11_KeyGen(slot.get(), mMechanism, nullptr,
mLength, nullptr));
if (!symKey) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
- nsresult rv = MapSECStatus(PK11_ExtractKeyValue(symKey));
+ nsresult rv = MapSECStatus(PK11_ExtractKeyValue(symKey.get()));
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
// This doesn't leak, because the SECItem* returned by PK11_GetKeyData
// just refers to a buffer managed by symKey. The assignment copies the
// data, so mKeyData manages one copy, while symKey manages another.
- ATTEMPT_BUFFER_ASSIGN(mKeyData, PK11_GetKeyData(symKey));
+ ATTEMPT_BUFFER_ASSIGN(mKeyData, PK11_GetKeyData(symKey.get()));
return NS_OK;
}
virtual void Resolve() override
{
if (NS_SUCCEEDED(mKey->SetSymKey(mKeyData))) {
mResultPromise->MaybeResolve(mKey);
} else {
@@ -2383,17 +2402,17 @@ private:
}
};
GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask(
nsIGlobalObject* aGlobal, JSContext* aCx, const ObjectOrString& aAlgorithm,
bool aExtractable, const Sequence<nsString>& aKeyUsages)
: mKeyPair(new CryptoKeyPair())
{
- mArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ mArena = UniquePLArenaPool(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!mArena) {
mEarlyRv = NS_ERROR_DOM_UNKNOWN_ERR;
return;
}
// Create an empty key pair and set easy attributes
mKeyPair->mPrivateKey = new CryptoKey(aGlobal);
mKeyPair->mPublicKey = new CryptoKey(aGlobal);
@@ -2480,18 +2499,18 @@ GenerateAsymmetricKeyTask::GenerateAsymm
CryptoBuffer prime;
ATTEMPT_BUFFER_INIT(prime, params.mPrime);
CryptoBuffer generator;
ATTEMPT_BUFFER_INIT(generator, params.mGenerator);
// Set up params.
- if (!prime.ToSECItem(mArena, &mDhParams.prime) ||
- !generator.ToSECItem(mArena, &mDhParams.base)) {
+ if (!prime.ToSECItem(mArena.get(), &mDhParams.prime) ||
+ !generator.ToSECItem(mArena.get(), &mDhParams.base)) {
mEarlyRv = NS_ERROR_DOM_UNKNOWN_ERR;
return;
}
// Create algorithm.
if (!mKeyPair->mPublicKey.get()->Algorithm().MakeDh(mAlgName,
prime,
generator)) {
@@ -2555,64 +2574,66 @@ GenerateAsymmetricKeyTask::GenerateAsymm
mEarlyRv = NS_ERROR_DOM_DATA_ERR;
return;
}
}
void
GenerateAsymmetricKeyTask::ReleaseNSSResources()
{
- mPublicKey.dispose();
- mPrivateKey.dispose();
+ mPublicKey = nullptr;
+ mPrivateKey = nullptr;
}
nsresult
GenerateAsymmetricKeyTask::DoCrypto()
{
MOZ_ASSERT(mKeyPair);
- ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ UniquePK11SlotInfo slot(PK11_GetInternalSlot());
MOZ_ASSERT(slot.get());
void* param;
switch (mMechanism) {
case CKM_RSA_PKCS_KEY_PAIR_GEN:
param = &mRsaParams;
break;
case CKM_DH_PKCS_KEY_PAIR_GEN:
param = &mDhParams;
break;
case CKM_EC_KEY_PAIR_GEN: {
- param = CreateECParamsForCurve(mNamedCurve, mArena);
+ param = CreateECParamsForCurve(mNamedCurve, mArena.get());
if (!param) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
break;
}
default:
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
SECKEYPublicKey* pubKey = nullptr;
- mPrivateKey = PK11_GenerateKeyPair(slot.get(), mMechanism, param, &pubKey,
- PR_FALSE, PR_FALSE, nullptr);
- mPublicKey = pubKey;
+ mPrivateKey = UniqueSECKEYPrivateKey(
+ PK11_GenerateKeyPair(slot.get(), mMechanism, param, &pubKey, PR_FALSE,
+ PR_FALSE, nullptr));
+ mPublicKey = UniqueSECKEYPublicKey(pubKey);
+ pubKey = nullptr;
if (!mPrivateKey.get() || !mPublicKey.get()) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
- nsresult rv = mKeyPair->mPrivateKey.get()->SetPrivateKey(mPrivateKey);
+ nsresult rv = mKeyPair->mPrivateKey.get()->SetPrivateKey(mPrivateKey.get());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_OPERATION_ERR);
- rv = mKeyPair->mPublicKey.get()->SetPublicKey(mPublicKey);
+ rv = mKeyPair->mPublicKey.get()->SetPublicKey(mPublicKey.get());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_OPERATION_ERR);
// PK11_GenerateKeyPair() does not set a CKA_EC_POINT attribute on the
// private key, we need this later when exporting to PKCS8 and JWK though.
if (mMechanism == CKM_EC_KEY_PAIR_GEN) {
- rv = mKeyPair->mPrivateKey->AddPublicKeyData(mPublicKey);
+ rv = mKeyPair->mPrivateKey->AddPublicKeyData(mPublicKey.get());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_OPERATION_ERR);
}
return NS_OK;
}
void
GenerateAsymmetricKeyTask::Resolve()
@@ -2702,66 +2723,66 @@ private:
size_t mLengthInBytes;
CryptoBuffer mSalt;
CryptoBuffer mInfo;
CryptoBuffer mSymKey;
CK_MECHANISM_TYPE mMechanism;
virtual nsresult DoCrypto() override
{
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// Import the key
SECItem keyItem = { siBuffer, nullptr, 0 };
- ATTEMPT_BUFFER_TO_SECITEM(arena, &keyItem, mSymKey);
-
- ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ ATTEMPT_BUFFER_TO_SECITEM(arena.get(), &keyItem, mSymKey);
+
+ UniquePK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot.get()) {
return NS_ERROR_DOM_OPERATION_ERR;
}
- ScopedPK11SymKey baseKey(PK11_ImportSymKey(slot, mMechanism,
+ UniquePK11SymKey baseKey(PK11_ImportSymKey(slot.get(), mMechanism,
PK11_OriginUnwrap, CKA_WRAP,
&keyItem, nullptr));
if (!baseKey) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
SECItem salt = { siBuffer, nullptr, 0 };
SECItem info = { siBuffer, nullptr, 0 };
- ATTEMPT_BUFFER_TO_SECITEM(arena, &salt, mSalt);
- ATTEMPT_BUFFER_TO_SECITEM(arena, &info, mInfo);
+ ATTEMPT_BUFFER_TO_SECITEM(arena.get(), &salt, mSalt);
+ ATTEMPT_BUFFER_TO_SECITEM(arena.get(), &info, mInfo);
CK_NSS_HKDFParams hkdfParams = { true, salt.data, salt.len,
true, info.data, info.len };
SECItem params = { siBuffer, (unsigned char*)&hkdfParams,
sizeof(hkdfParams) };
// CKM_SHA512_HMAC and CKA_SIGN are key type and usage attributes of the
// derived symmetric key and don't matter because we ignore them anyway.
- ScopedPK11SymKey symKey(PK11_Derive(baseKey, mMechanism, ¶ms,
+ UniquePK11SymKey symKey(PK11_Derive(baseKey.get(), mMechanism, ¶ms,
CKM_SHA512_HMAC, CKA_SIGN,
mLengthInBytes));
if (!symKey.get()) {
return NS_ERROR_DOM_OPERATION_ERR;
}
- nsresult rv = MapSECStatus(PK11_ExtractKeyValue(symKey));
+ nsresult rv = MapSECStatus(PK11_ExtractKeyValue(symKey.get()));
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// This doesn't leak, because the SECItem* returned by PK11_GetKeyData
// just refers to a buffer managed by symKey. The assignment copies the
// data, so mResult manages one copy, while symKey manages another.
- ATTEMPT_BUFFER_ASSIGN(mResult, PK11_GetKeyData(symKey));
+ ATTEMPT_BUFFER_ASSIGN(mResult, PK11_GetKeyData(symKey.get()));
if (mLengthInBytes > mResult.Length()) {
return NS_ERROR_DOM_DATA_ERR;
}
if (!mResult.SetLength(mLengthInBytes, fallible)) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
@@ -2850,70 +2871,72 @@ private:
size_t mLength;
size_t mIterations;
CryptoBuffer mSalt;
CryptoBuffer mSymKey;
SECOidTag mHashOidTag;
virtual nsresult DoCrypto() override
{
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return NS_ERROR_DOM_OPERATION_ERR;
}
SECItem salt = { siBuffer, nullptr, 0 };
- ATTEMPT_BUFFER_TO_SECITEM(arena, &salt, mSalt);
+ ATTEMPT_BUFFER_TO_SECITEM(arena.get(), &salt, mSalt);
// PK11_CreatePBEV2AlgorithmID will "helpfully" create PBKDF2 parameters
// with a random salt if given a SECItem* that is either null or has a null
// data pointer. This obviously isn't what we want, so we have to fake it
// out by passing in a SECItem* with a non-null data pointer but with zero
// length.
if (!salt.data) {
MOZ_ASSERT(salt.len == 0);
- salt.data = reinterpret_cast<unsigned char*>(PORT_ArenaAlloc(arena, 1));
+ salt.data =
+ reinterpret_cast<unsigned char*>(PORT_ArenaAlloc(arena.get(), 1));
if (!salt.data) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
}
// Always pass in cipherAlg=SEC_OID_HMAC_SHA1 (i.e. PBMAC1) as this
// parameter is unused for key generation. It is currently only used
// for PBKDF2 authentication or key (un)wrapping when specifying an
// encryption algorithm (PBES2).
- ScopedSECAlgorithmID alg_id(PK11_CreatePBEV2AlgorithmID(
+ UniqueSECAlgorithmID algID(PK11_CreatePBEV2AlgorithmID(
SEC_OID_PKCS5_PBKDF2, SEC_OID_HMAC_SHA1, mHashOidTag,
mLength, mIterations, &salt));
- if (!alg_id.get()) {
+ if (!algID) {
return NS_ERROR_DOM_OPERATION_ERR;
}
- ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ UniquePK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot.get()) {
return NS_ERROR_DOM_OPERATION_ERR;
}
SECItem keyItem = { siBuffer, nullptr, 0 };
- ATTEMPT_BUFFER_TO_SECITEM(arena, &keyItem, mSymKey);
-
- ScopedPK11SymKey symKey(PK11_PBEKeyGen(slot, alg_id, &keyItem, false, nullptr));
+ ATTEMPT_BUFFER_TO_SECITEM(arena.get(), &keyItem, mSymKey);
+
+ UniquePK11SymKey symKey(PK11_PBEKeyGen(slot.get(), algID.get(), &keyItem,
+ false, nullptr));
if (!symKey.get()) {
return NS_ERROR_DOM_OPERATION_ERR;
}
- nsresult rv = MapSECStatus(PK11_ExtractKeyValue(symKey));
+ nsresult rv = MapSECStatus(PK11_ExtractKeyValue(symKey.get()));
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// This doesn't leak, because the SECItem* returned by PK11_GetKeyData
// just refers to a buffer managed by symKey. The assignment copies the
// data, so mResult manages one copy, while symKey manages another.
- ATTEMPT_BUFFER_ASSIGN(mResult, PK11_GetKeyData(symKey));
+ ATTEMPT_BUFFER_ASSIGN(mResult, PK11_GetKeyData(symKey.get()));
return NS_OK;
}
};
template<class DeriveBitsTask>
class DeriveKeyTask : public DeriveBitsTask
{
public:
@@ -2997,17 +3020,17 @@ public:
RootedDictionary<EcdhKeyDeriveParams> params(aCx);
mEarlyRv = Coerce(aCx, params, aAlgorithm);
if (NS_FAILED(mEarlyRv)) {
mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
return;
}
CryptoKey* publicKey = params.mPublic;
- mPubKey = publicKey->GetPublicKey();
+ mPubKey = UniqueSECKEYPublicKey(publicKey->GetPublicKey());
if (!mPubKey) {
mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR;
return;
}
CHECK_KEY_ALGORITHM(publicKey->Algorithm(), WEBCRYPTO_ALG_ECDH);
// Both keys must use the same named curve.
@@ -3017,40 +3040,41 @@ public:
if (!curve1.Equals(curve2)) {
mEarlyRv = NS_ERROR_DOM_DATA_ERR;
return;
}
}
private:
size_t mLength;
- ScopedSECKEYPrivateKey mPrivKey;
- ScopedSECKEYPublicKey mPubKey;
+ UniqueSECKEYPrivateKey mPrivKey;
+ UniqueSECKEYPublicKey mPubKey;
virtual nsresult DoCrypto() override
{
// CKM_SHA512_HMAC and CKA_SIGN are key type and usage attributes of the
// derived symmetric key and don't matter because we ignore them anyway.
- ScopedPK11SymKey symKey(PK11_PubDeriveWithKDF(
- mPrivKey, mPubKey, PR_FALSE, nullptr, nullptr, CKM_ECDH1_DERIVE,
- CKM_SHA512_HMAC, CKA_SIGN, 0, CKD_NULL, nullptr, nullptr));
+ UniquePK11SymKey symKey(PK11_PubDeriveWithKDF(
+ mPrivKey.get(), mPubKey.get(), PR_FALSE, nullptr, nullptr,
+ CKM_ECDH1_DERIVE, CKM_SHA512_HMAC, CKA_SIGN, 0, CKD_NULL, nullptr,
+ nullptr));
if (!symKey.get()) {
return NS_ERROR_DOM_OPERATION_ERR;
}
- nsresult rv = MapSECStatus(PK11_ExtractKeyValue(symKey));
+ nsresult rv = MapSECStatus(PK11_ExtractKeyValue(symKey.get()));
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// This doesn't leak, because the SECItem* returned by PK11_GetKeyData
// just refers to a buffer managed by symKey. The assignment copies the
// data, so mResult manages one copy, while symKey manages another.
- ATTEMPT_BUFFER_ASSIGN(mResult, PK11_GetKeyData(symKey));
+ ATTEMPT_BUFFER_ASSIGN(mResult, PK11_GetKeyData(symKey.get()));
if (mLength > mResult.Length()) {
return NS_ERROR_DOM_DATA_ERR;
}
if (!mResult.SetLength(mLength, fallible)) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}
@@ -3096,17 +3120,17 @@ public:
RootedDictionary<DhKeyDeriveParams> params(aCx);
mEarlyRv = Coerce(aCx, params, aAlgorithm);
if (NS_FAILED(mEarlyRv)) {
mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
return;
}
CryptoKey* publicKey = params.mPublic;
- mPubKey = publicKey->GetPublicKey();
+ mPubKey = UniqueSECKEYPublicKey(publicKey->GetPublicKey());
if (!mPubKey) {
mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR;
return;
}
KeyAlgorithmProxy alg1 = publicKey->Algorithm();
CHECK_KEY_ALGORITHM(alg1, WEBCRYPTO_ALG_DH);
@@ -3116,40 +3140,41 @@ public:
alg1.mDh.mGenerator != alg2.mDh.mGenerator) {
mEarlyRv = NS_ERROR_DOM_DATA_ERR;
return;
}
}
private:
size_t mLength;
- ScopedSECKEYPrivateKey mPrivKey;
- ScopedSECKEYPublicKey mPubKey;
+ UniqueSECKEYPrivateKey mPrivKey;
+ UniqueSECKEYPublicKey mPubKey;
virtual nsresult DoCrypto() override
{
// CKM_SHA512_HMAC and CKA_SIGN are key type and usage attributes of the
// derived symmetric key and don't matter because we ignore them anyway.
- ScopedPK11SymKey symKey(PK11_PubDeriveWithKDF(
- mPrivKey, mPubKey, PR_FALSE, nullptr, nullptr, CKM_DH_PKCS_DERIVE,
- CKM_SHA512_HMAC, CKA_SIGN, 0, CKD_NULL, nullptr, nullptr));
+ UniquePK11SymKey symKey(PK11_PubDeriveWithKDF(
+ mPrivKey.get(), mPubKey.get(), PR_FALSE, nullptr, nullptr,
+ CKM_DH_PKCS_DERIVE, CKM_SHA512_HMAC, CKA_SIGN, 0, CKD_NULL, nullptr,
+ nullptr));
if (!symKey.get()) {
return NS_ERROR_DOM_OPERATION_ERR;
}
- nsresult rv = MapSECStatus(PK11_ExtractKeyValue(symKey));
+ nsresult rv = MapSECStatus(PK11_ExtractKeyValue(symKey.get()));
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_OPERATION_ERR;
}
// This doesn't leak, because the SECItem* returned by PK11_GetKeyData
// just refers to a buffer managed by symKey. The assignment copies the
// data, so mResult manages one copy, while symKey manages another.
- ATTEMPT_BUFFER_ASSIGN(mResult, PK11_GetKeyData(symKey));
+ ATTEMPT_BUFFER_ASSIGN(mResult, PK11_GetKeyData(symKey.get()));
if (mLength > mResult.Length()) {
return NS_ERROR_DOM_DATA_ERR;
}
if (!mResult.SetLength(mLength, fallible)) {
return NS_ERROR_DOM_UNKNOWN_ERR;
}