diff --git a/dom/crypto/WebCryptoTask.cpp b/dom/crypto/WebCryptoTask.cpp index 42864f37413c..cc67f4b4ea1f 100644 --- a/dom/crypto/WebCryptoTask.cpp +++ b/dom/crypto/WebCryptoTask.cpp @@ -1022,8 +1022,7 @@ public: } else if (algName.EqualsLiteral(WEBCRYPTO_ALG_HMAC)) { RootedDictionary params(aCx); mEarlyRv = Coerce(aCx, params, aAlgorithm); - if (NS_FAILED(mEarlyRv) || !params.mLength.WasPassed() || - !params.mHash.WasPassed()) { + if (NS_FAILED(mEarlyRv) || !params.mHash.WasPassed()) { mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR; return; } @@ -1041,7 +1040,25 @@ public: hashName.Assign(hashAlg.mName.Value()); } - mLength = params.mLength.Value(); + if (params.mLength.WasPassed()) { + mLength = params.mLength.Value(); + } else { + KeyAlgorithm hashAlg(global, hashName); + switch (hashAlg.Mechanism()) { + case CKM_SHA_1: mLength = 128; break; + case CKM_SHA224: mLength = 224; break; + case CKM_SHA256: mLength = 256; break; + case CKM_SHA384: mLength = 384; break; + case CKM_SHA512: mLength = 512; break; + default: mLength = 0; break; + } + } + + if (mLength == 0) { + mEarlyRv = NS_ERROR_DOM_DATA_ERR; + return; + } + algorithm = new HmacKeyAlgorithm(global, algName, mLength, hashName); allowedUsages = Key::SIGN | Key::VERIFY; } else { diff --git a/dom/crypto/test/tests.js b/dom/crypto/test/tests.js index 34fdf2157974..c480e37e4cae 100644 --- a/dom/crypto/test/tests.js +++ b/dom/crypto/test/tests.js @@ -309,6 +309,62 @@ TestArray.addTest( } ); +// ----------------------------------------------------------------------------- +TestArray.addTest( + "Generate a 256-bit HMAC-SHA-256 key", + function() { + var that = this; + var alg = { name: "HMAC", length: 256, hash: {name: "SHA-256"} }; + crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then( + complete(that, function(x) { + return hasKeyFields(x) && x.algorithm.length == 256; + }), + error(that) + ); + } +); + +// ----------------------------------------------------------------------------- +TestArray.addTest( + "Generate a 256-bit HMAC-SHA-256 key without specifying a key length", + function() { + var that = this; + var alg = { name: "HMAC", hash: {name: "SHA-256"} }; + crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then( + complete(that, function(x) { + return hasKeyFields(x) && x.algorithm.length == 256; + }), + error(that) + ); + } +); + +// ----------------------------------------------------------------------------- +TestArray.addTest( + "Fail generating an HMAC key when specifying an invalid hash algorithm", + function() { + var that = this; + var alg = { name: "HMAC", hash: {name: "SHA-123"} }; + crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then( + error(that), + complete(that, function() { return true; }) + ); + } +); + +// ----------------------------------------------------------------------------- +TestArray.addTest( + "Fail generating an HMAC key when specifying a zero length", + function() { + var that = this; + var alg = { name: "HMAC", hash: {name: "SHA-256"}, length: 0 }; + crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then( + error(that), + complete(that, function() { return true; }) + ); + } +); + // ----------------------------------------------------------------------------- TestArray.addTest( "Generate a 192-bit AES key",