Bug 1001691 - Make GenerateAsymmetricKeyTask::mKeyPair a UniquePtr so that we can explicitly release it on the main thread r=mt

This commit is contained in:
Tim Taubert
2015-09-21 14:52:40 +02:00
parent 9cf7b7b76d
commit 2e010e857c
3 changed files with 49 additions and 39 deletions

View File

@@ -2256,6 +2256,7 @@ private:
GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask( GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask(
JSContext* aCx, const ObjectOrString& aAlgorithm, bool aExtractable, JSContext* aCx, const ObjectOrString& aAlgorithm, bool aExtractable,
const Sequence<nsString>& aKeyUsages) const Sequence<nsString>& aKeyUsages)
: mKeyPair(new CryptoKeyPair())
{ {
nsIGlobalObject* global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx)); nsIGlobalObject* global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
if (!global) { if (!global) {
@@ -2269,9 +2270,9 @@ GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask(
return; return;
} }
// Create an empty key and set easy attributes // Create an empty key pair and set easy attributes
mKeyPair.mPrivateKey = new CryptoKey(global); mKeyPair->mPrivateKey = new CryptoKey(global);
mKeyPair.mPublicKey = new CryptoKey(global); mKeyPair->mPublicKey = new CryptoKey(global);
// Extract algorithm name // Extract algorithm name
mEarlyRv = GetAlgorithmName(aCx, aAlgorithm, mAlgName); mEarlyRv = GetAlgorithmName(aCx, aAlgorithm, mAlgName);
@@ -2303,20 +2304,20 @@ GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask(
} }
// Create algorithm // Create algorithm
if (!mKeyPair.mPublicKey.get()->Algorithm().MakeRsa(mAlgName, if (!mKeyPair->mPublicKey.get()->Algorithm().MakeRsa(mAlgName,
modulusLength,
publicExponent,
hashName)) {
mEarlyRv = NS_ERROR_DOM_OPERATION_ERR;
return;
}
if (!mKeyPair.mPrivateKey.get()->Algorithm().MakeRsa(mAlgName,
modulusLength, modulusLength,
publicExponent, publicExponent,
hashName)) { hashName)) {
mEarlyRv = NS_ERROR_DOM_OPERATION_ERR; mEarlyRv = NS_ERROR_DOM_OPERATION_ERR;
return; return;
} }
if (!mKeyPair->mPrivateKey.get()->Algorithm().MakeRsa(mAlgName,
modulusLength,
publicExponent,
hashName)) {
mEarlyRv = NS_ERROR_DOM_OPERATION_ERR;
return;
}
mMechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; mMechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
// Set up params struct // Set up params struct
@@ -2341,8 +2342,8 @@ GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask(
} }
// Create algorithm. // Create algorithm.
mKeyPair.mPublicKey.get()->Algorithm().MakeEc(mAlgName, mNamedCurve); mKeyPair->mPublicKey.get()->Algorithm().MakeEc(mAlgName, mNamedCurve);
mKeyPair.mPrivateKey.get()->Algorithm().MakeEc(mAlgName, mNamedCurve); mKeyPair->mPrivateKey.get()->Algorithm().MakeEc(mAlgName, mNamedCurve);
mMechanism = CKM_EC_KEY_PAIR_GEN; mMechanism = CKM_EC_KEY_PAIR_GEN;
} else if (mAlgName.EqualsLiteral(WEBCRYPTO_ALG_DH)) { } else if (mAlgName.EqualsLiteral(WEBCRYPTO_ALG_DH)) {
RootedDictionary<DhKeyGenParams> params(aCx); RootedDictionary<DhKeyGenParams> params(aCx);
@@ -2366,15 +2367,15 @@ GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask(
} }
// Create algorithm. // Create algorithm.
if (!mKeyPair.mPublicKey.get()->Algorithm().MakeDh(mAlgName, if (!mKeyPair->mPublicKey.get()->Algorithm().MakeDh(mAlgName,
prime, prime,
generator)) { generator)) {
mEarlyRv = NS_ERROR_DOM_OPERATION_ERR; mEarlyRv = NS_ERROR_DOM_OPERATION_ERR;
return; return;
} }
if (!mKeyPair.mPrivateKey.get()->Algorithm().MakeDh(mAlgName, if (!mKeyPair->mPrivateKey.get()->Algorithm().MakeDh(mAlgName,
prime, prime,
generator)) { generator)) {
mEarlyRv = NS_ERROR_DOM_OPERATION_ERR; mEarlyRv = NS_ERROR_DOM_OPERATION_ERR;
return; return;
} }
@@ -2398,31 +2399,31 @@ GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask(
publicAllowedUsages = 0; publicAllowedUsages = 0;
} }
mKeyPair.mPrivateKey.get()->SetExtractable(aExtractable); mKeyPair->mPrivateKey.get()->SetExtractable(aExtractable);
mKeyPair.mPrivateKey.get()->SetType(CryptoKey::PRIVATE); mKeyPair->mPrivateKey.get()->SetType(CryptoKey::PRIVATE);
mKeyPair.mPublicKey.get()->SetExtractable(true); mKeyPair->mPublicKey.get()->SetExtractable(true);
mKeyPair.mPublicKey.get()->SetType(CryptoKey::PUBLIC); mKeyPair->mPublicKey.get()->SetType(CryptoKey::PUBLIC);
mKeyPair.mPrivateKey.get()->ClearUsages(); mKeyPair->mPrivateKey.get()->ClearUsages();
mKeyPair.mPublicKey.get()->ClearUsages(); mKeyPair->mPublicKey.get()->ClearUsages();
for (uint32_t i=0; i < aKeyUsages.Length(); ++i) { for (uint32_t i=0; i < aKeyUsages.Length(); ++i) {
mEarlyRv = mKeyPair.mPrivateKey.get()->AddUsageIntersecting(aKeyUsages[i], mEarlyRv = mKeyPair->mPrivateKey.get()->AddUsageIntersecting(aKeyUsages[i],
privateAllowedUsages); privateAllowedUsages);
if (NS_FAILED(mEarlyRv)) { if (NS_FAILED(mEarlyRv)) {
return; return;
} }
mEarlyRv = mKeyPair.mPublicKey.get()->AddUsageIntersecting(aKeyUsages[i], mEarlyRv = mKeyPair->mPublicKey.get()->AddUsageIntersecting(aKeyUsages[i],
publicAllowedUsages); publicAllowedUsages);
if (NS_FAILED(mEarlyRv)) { if (NS_FAILED(mEarlyRv)) {
return; return;
} }
} }
// If no usages ended up being allowed, DataError // If no usages ended up being allowed, DataError
if (!mKeyPair.mPublicKey.get()->HasAnyUsage() && if (!mKeyPair->mPublicKey.get()->HasAnyUsage() &&
!mKeyPair.mPrivateKey.get()->HasAnyUsage()) { !mKeyPair->mPrivateKey.get()->HasAnyUsage()) {
mEarlyRv = NS_ERROR_DOM_DATA_ERR; mEarlyRv = NS_ERROR_DOM_DATA_ERR;
return; return;
} }
@@ -2438,6 +2439,8 @@ GenerateAsymmetricKeyTask::ReleaseNSSResources()
nsresult nsresult
GenerateAsymmetricKeyTask::DoCrypto() GenerateAsymmetricKeyTask::DoCrypto()
{ {
MOZ_ASSERT(mKeyPair);
ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
MOZ_ASSERT(slot.get()); MOZ_ASSERT(slot.get());
@@ -2468,15 +2471,15 @@ GenerateAsymmetricKeyTask::DoCrypto()
return NS_ERROR_DOM_UNKNOWN_ERR; return NS_ERROR_DOM_UNKNOWN_ERR;
} }
nsresult rv = mKeyPair.mPrivateKey.get()->SetPrivateKey(mPrivateKey); nsresult rv = mKeyPair->mPrivateKey.get()->SetPrivateKey(mPrivateKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_OPERATION_ERR); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_OPERATION_ERR);
rv = mKeyPair.mPublicKey.get()->SetPublicKey(mPublicKey); rv = mKeyPair->mPublicKey.get()->SetPublicKey(mPublicKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_OPERATION_ERR); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_OPERATION_ERR);
// PK11_GenerateKeyPair() does not set a CKA_EC_POINT attribute on the // 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. // private key, we need this later when exporting to PKCS8 and JWK though.
if (mMechanism == CKM_EC_KEY_PAIR_GEN) { if (mMechanism == CKM_EC_KEY_PAIR_GEN) {
rv = mKeyPair.mPrivateKey->AddPublicKeyData(mPublicKey); rv = mKeyPair->mPrivateKey->AddPublicKeyData(mPublicKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_OPERATION_ERR); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_OPERATION_ERR);
} }
@@ -2486,7 +2489,13 @@ GenerateAsymmetricKeyTask::DoCrypto()
void void
GenerateAsymmetricKeyTask::Resolve() GenerateAsymmetricKeyTask::Resolve()
{ {
mResultPromise->MaybeResolve(mKeyPair); mResultPromise->MaybeResolve(*mKeyPair);
}
void
GenerateAsymmetricKeyTask::Cleanup()
{
mKeyPair = nullptr;
} }
class DerivePbkdfBitsTask : public ReturnArrayBufferViewTask class DerivePbkdfBitsTask : public ReturnArrayBufferViewTask

View File

@@ -233,7 +233,7 @@ public:
const Sequence<nsString>& aKeyUsages); const Sequence<nsString>& aKeyUsages);
protected: protected:
ScopedPLArenaPool mArena; ScopedPLArenaPool mArena;
CryptoKeyPair mKeyPair; UniquePtr<CryptoKeyPair> mKeyPair;
nsString mAlgName; nsString mAlgName;
CK_MECHANISM_TYPE mMechanism; CK_MECHANISM_TYPE mMechanism;
PK11RSAGenParams mRsaParams; PK11RSAGenParams mRsaParams;
@@ -243,6 +243,7 @@ protected:
virtual void ReleaseNSSResources() override; virtual void ReleaseNSSResources() override;
virtual nsresult DoCrypto() override; virtual nsresult DoCrypto() override;
virtual void Resolve() override; virtual void Resolve() override;
virtual void Cleanup() override;
private: private:
ScopedSECKEYPublicKey mPublicKey; ScopedSECKEYPublicKey mPublicKey;

View File

@@ -112,7 +112,7 @@ private:
return NS_ERROR_DOM_UNKNOWN_ERR; return NS_ERROR_DOM_UNKNOWN_ERR;
} }
ScopedSECKEYPublicKey publicKey(mKeyPair.mPublicKey.get()->GetPublicKey()); ScopedSECKEYPublicKey publicKey(mKeyPair->mPublicKey.get()->GetPublicKey());
ScopedCERTSubjectPublicKeyInfo spki( ScopedCERTSubjectPublicKeyInfo spki(
SECKEY_CreateSubjectPublicKeyInfo(publicKey)); SECKEY_CreateSubjectPublicKeyInfo(publicKey));
if (!spki) { if (!spki) {
@@ -180,7 +180,7 @@ private:
return NS_ERROR_DOM_UNKNOWN_ERR; return NS_ERROR_DOM_UNKNOWN_ERR;
} }
ScopedSECKEYPrivateKey privateKey(mKeyPair.mPrivateKey.get()->GetPrivateKey()); ScopedSECKEYPrivateKey privateKey(mKeyPair->mPrivateKey.get()->GetPrivateKey());
rv = SEC_DerSignData(arena, signedCert, innerDER.data, innerDER.len, rv = SEC_DerSignData(arena, signedCert, innerDER.data, innerDER.len,
privateKey, mSignatureAlg); privateKey, mSignatureAlg);
if (rv != SECSuccess) { if (rv != SECSuccess) {
@@ -232,7 +232,7 @@ private:
{ {
// Make copies of the private key and certificate, otherwise, when this // Make copies of the private key and certificate, otherwise, when this
// object is deleted, the structures they reference will be deleted too. // object is deleted, the structures they reference will be deleted too.
SECKEYPrivateKey* key = mKeyPair.mPrivateKey.get()->GetPrivateKey(); SECKEYPrivateKey* key = mKeyPair->mPrivateKey.get()->GetPrivateKey();
CERTCertificate* cert = CERT_DupCertificate(mCertificate); CERTCertificate* cert = CERT_DupCertificate(mCertificate);
nsRefPtr<RTCCertificate> result = nsRefPtr<RTCCertificate> result =
new RTCCertificate(mResultPromise->GetParentObject(), new RTCCertificate(mResultPromise->GetParentObject(),