mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1034855 - Implement deriveKey() for ECDH r=rbarnes
This commit is contained in:
parent
5b5fc12a02
commit
ad2acd36ae
@ -2327,17 +2327,18 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class DerivePbkdfKeyTask : public DerivePbkdfBitsTask
|
||||
template<class DeriveBitsTask>
|
||||
class DeriveKeyTask : public DeriveBitsTask
|
||||
{
|
||||
public:
|
||||
DerivePbkdfKeyTask(JSContext* aCx,
|
||||
const ObjectOrString& aAlgorithm, CryptoKey& aBaseKey,
|
||||
const ObjectOrString& aDerivedKeyType, bool aExtractable,
|
||||
const Sequence<nsString>& aKeyUsages)
|
||||
: DerivePbkdfBitsTask(aCx, aAlgorithm, aBaseKey, aDerivedKeyType)
|
||||
DeriveKeyTask(JSContext* aCx,
|
||||
const ObjectOrString& aAlgorithm, CryptoKey& aBaseKey,
|
||||
const ObjectOrString& aDerivedKeyType, bool aExtractable,
|
||||
const Sequence<nsString>& aKeyUsages)
|
||||
: DeriveBitsTask(aCx, aAlgorithm, aBaseKey, aDerivedKeyType)
|
||||
, mResolved(false)
|
||||
{
|
||||
if (NS_FAILED(mEarlyRv)) {
|
||||
if (NS_FAILED(this->mEarlyRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2352,8 +2353,8 @@ protected:
|
||||
|
||||
private:
|
||||
virtual void Resolve() MOZ_OVERRIDE {
|
||||
mTask->SetKeyData(mResult);
|
||||
mTask->DispatchWithPromise(mResultPromise);
|
||||
mTask->SetKeyData(this->mResult);
|
||||
mTask->DispatchWithPromise(this->mResultPromise);
|
||||
mResolved = true;
|
||||
}
|
||||
|
||||
@ -2737,8 +2738,15 @@ WebCryptoTask::CreateDeriveKeyTask(JSContext* aCx,
|
||||
}
|
||||
|
||||
if (algName.EqualsASCII(WEBCRYPTO_ALG_PBKDF2)) {
|
||||
return new DerivePbkdfKeyTask(aCx, aAlgorithm, aBaseKey, aDerivedKeyType,
|
||||
aExtractable, aKeyUsages);
|
||||
return new DeriveKeyTask<DerivePbkdfBitsTask>(aCx, aAlgorithm, aBaseKey,
|
||||
aDerivedKeyType, aExtractable,
|
||||
aKeyUsages);
|
||||
}
|
||||
|
||||
if (algName.EqualsASCII(WEBCRYPTO_ALG_ECDH)) {
|
||||
return new DeriveKeyTask<DeriveEcdhBitsTask>(aCx, aAlgorithm, aBaseKey,
|
||||
aDerivedKeyType, aExtractable,
|
||||
aKeyUsages);
|
||||
}
|
||||
|
||||
return new FailureTask(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
|
@ -2143,3 +2143,51 @@ TestArray.addTest(
|
||||
.then(error(that), complete(that));
|
||||
}
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
TestArray.addTest(
|
||||
"Derive an HMAC key from two ECDH keys and test sign/verify",
|
||||
function() {
|
||||
var that = this;
|
||||
var alg = { name: "ECDH" };
|
||||
var algDerived = { name: "HMAC", hash: {name: "SHA-1"} };
|
||||
|
||||
var pubKey, privKey;
|
||||
function setPub(x) { pubKey = x; }
|
||||
function setPriv(x) { privKey = x; }
|
||||
|
||||
function doDerive() {
|
||||
var alg = { name: "ECDH", public: pubKey };
|
||||
return crypto.subtle.deriveKey(alg, privKey, algDerived, false, ["sign", "verify"])
|
||||
.then(function (x) {
|
||||
if (!hasKeyFields(x)) {
|
||||
throw "Invalid key; missing field(s)";
|
||||
}
|
||||
|
||||
// 512 bit is the default for HMAC-SHA1.
|
||||
if (x.algorithm.length != 512) {
|
||||
throw "Invalid key; incorrect length";
|
||||
}
|
||||
|
||||
return x;
|
||||
});
|
||||
}
|
||||
|
||||
function doSignAndVerify(x) {
|
||||
var data = crypto.getRandomValues(new Uint8Array(1024));
|
||||
return crypto.subtle.sign("HMAC", x, data)
|
||||
.then(function (sig) {
|
||||
return crypto.subtle.verify("HMAC", x, sig, data);
|
||||
});
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
crypto.subtle.importKey("jwk", tv.ecdh_p521.jwk_priv, alg, false, ["deriveBits"])
|
||||
.then(setPriv, error(that)),
|
||||
crypto.subtle.importKey("jwk", tv.ecdh_p521.jwk_pub, alg, false, ["deriveBits"])
|
||||
.then(setPub, error(that))
|
||||
]).then(doDerive, error(that))
|
||||
.then(doSignAndVerify, error(that))
|
||||
.then(complete(that), error(that));
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user