summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/webcrypto/algorithms/pbkdf2.cc3
-rw-r--r--components/webcrypto/status.cc5
-rw-r--r--components/webcrypto/status.h3
-rw-r--r--third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/deriveBits-failures-expected.txt9
-rw-r--r--third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/deriveBits-failures.html74
-rw-r--r--third_party/WebKit/LayoutTests/crypto/subtle/resources/common.js40
6 files changed, 101 insertions, 33 deletions
diff --git a/components/webcrypto/algorithms/pbkdf2.cc b/components/webcrypto/algorithms/pbkdf2.cc
index b5cf5ca..c3449f5 100644
--- a/components/webcrypto/algorithms/pbkdf2.cc
+++ b/components/webcrypto/algorithms/pbkdf2.cc
@@ -63,6 +63,9 @@ class Pbkdf2Implementation : public AlgorithmImplementation {
const blink::WebCryptoPbkdf2Params* params = algorithm.pbkdf2Params();
+ if (params->iterations() == 0)
+ return Status::ErrorPbkdf2Iterations0();
+
const EVP_MD* digest_algorithm = GetDigest(params->hash());
if (!digest_algorithm)
return Status::ErrorUnsupported();
diff --git a/components/webcrypto/status.cc b/components/webcrypto/status.cc
index 54efffe..4747a7f 100644
--- a/components/webcrypto/status.cc
+++ b/components/webcrypto/status.cc
@@ -351,6 +351,11 @@ Status Status::ErrorPbkdf2DeriveBitsLengthNotSpecified() {
"No length was specified for the PBKDF2 Derive Bits operation.");
}
+Status Status::ErrorPbkdf2Iterations0() {
+ return Status(blink::WebCryptoErrorTypeOperation,
+ "PBKDF2 requires iterations > 0");
+}
+
Status::Status(blink::WebCryptoErrorType error_type,
const std::string& error_details_utf8)
: type_(TYPE_ERROR),
diff --git a/components/webcrypto/status.h b/components/webcrypto/status.h
index 94124db..7143a29 100644
--- a/components/webcrypto/status.h
+++ b/components/webcrypto/status.h
@@ -265,6 +265,9 @@ class Status {
// No length parameter was provided for PBKDF2's Derive Bits operation.
static Status ErrorPbkdf2DeriveBitsLengthNotSpecified();
+ // PBKDF2 was called with iterations == 0.
+ static Status ErrorPbkdf2Iterations0();
+
private:
enum Type { TYPE_ERROR, TYPE_SUCCESS };
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/deriveBits-failures-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/deriveBits-failures-expected.txt
index 9b375d6..ac0a31b 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/deriveBits-failures-expected.txt
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/deriveBits-failures-expected.txt
@@ -3,11 +3,18 @@ Tests deriveBits() with various bad parameters for PBKDF2
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
Importing the password...
+SUCCESS
Deriving 100 bits...
-error is: OperationError: Length for PBKDF2 key derivation must be a multiple of 8 bits.
+SUCCESS (rejected): OperationError: Length for PBKDF2 key derivation must be a multiple of 8 bits.
+
+Deriving using iterations=0...
+SUCCESS (rejected): OperationError: PBKDF2 requires iterations > 0
+Deriving using iterations=-10...
+SUCCESS (rejected): TypeError: Pbkdf2Params: iterations: Outside of numeric range
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/deriveBits-failures.html b/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/deriveBits-failures.html
index 9562e28..71052f4 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/deriveBits-failures.html
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/deriveBits-failures.html
@@ -13,47 +13,57 @@ description("Tests deriveBits() with various bad parameters for PBKDF2");
jsTestIsAsync = true;
-var testCase = {
- password: "password",
- salt: "salt",
- c: 1,
- hash: "SHA-1"
- };
+var pbkdf2Key = null;
+// Imports a PBKDF2 key and saves the result to pbkdf2Key.
function importPbkdf2Key() {
- var key = null;
-
- debug("Importing the password...");
-
- var algorithm = {name: 'PBKDF2'};
+ var algorithm = {name: "PBKDF2"};
- var password = asciiToUint8Array(testCase.password);
- var usages = ['deriveBits', 'deriveKey'];
+ var password = asciiToUint8Array("password");
+ var usages = ["deriveBits", "deriveKey"];
var extractable = false;
// (1) Import the password
- return crypto.subtle.importKey('raw', password, algorithm, extractable, usages).then(function(result) {
- key = result;
- return key;
- });
+ return expectSuccess(
+ "Importing the password...",
+ crypto.subtle.importKey("raw", password, algorithm, extractable, usages).then(function(result) {
+ pbkdf2Key = result;
+ }));
}
-var pbkdf2Key = null;
+importPbkdf2Key().then(function() {
+ var algorithm = {
+ name: "PBKDF2",
+ salt: asciiToUint8Array("salt"),
+ iterations: 1,
+ hash: "SHA-1"
+ };
+
+ return expectFailure(
+ "Deriving 100 bits...",
+ crypto.subtle.deriveBits(algorithm, pbkdf2Key, 100));
+}).then(function() {
+ var algorithm = {
+ name: "PBKDF2",
+ salt: asciiToUint8Array("salt"),
+ iterations: 0,
+ hash: "SHA-1"
+ };
+
+ return expectFailure(
+ "Deriving using iterations=0...",
+ crypto.subtle.deriveBits(algorithm, pbkdf2Key, 16));
+}).then(function() {
+ var algorithm = {
+ name: "PBKDF2",
+ salt: asciiToUint8Array("salt"),
+ iterations: -10,
+ hash: "SHA-1"
+ };
-var params = {
- name: 'PBKDF2',
- salt: asciiToUint8Array(testCase.salt),
- iterations: testCase.c,
- hash: {name: testCase.hash}
-};
-importPbkdf2Key().then(function(result) {
- pbkdf2Key = result;
- debug("\nDeriving 100 bits...");
- return crypto.subtle.deriveBits(params, pbkdf2Key, 100);
-}).then(failAndFinishJSTest, function(result) {
- logError(result);
-
- debug("");
+ return expectFailure(
+ "Deriving using iterations=-10...",
+ crypto.subtle.deriveBits(algorithm, pbkdf2Key, 16));
}).then(finishJSTest, failAndFinishJSTest);
</script>
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/resources/common.js b/third_party/WebKit/LayoutTests/crypto/subtle/resources/common.js
index 0f195f6..bdfae25 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/resources/common.js
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/resources/common.js
@@ -124,3 +124,43 @@ function shouldEvaluateAs(actual, expectedValue)
return shouldBeEqualToString(actual, expectedValue);
return shouldEvaluateTo(actual, expectedValue);
}
+
+// expectFailure() is a helper to convert a Promise that is expect
+// to fail into one that is epxected to succeed, for use in chaining
+// promises.
+//
+// For instance:
+//
+// // Catches and logs the failure from importKey().
+// return expectFailue("Import key...", crypto.subtle.importKey(...));
+function expectFailure(message, promise)
+{
+ debug("\n" + message);
+
+ return promise.then(function(result) {
+ debug("FAILED: Expected failure but got: " + result);
+
+ // Re-throw the error.
+ throw new Error("Test FAILED: " + message);
+ }, function(error) {
+ // Expected to fail, so consider this a success.
+ debug("SUCCESS (rejected): " + error.toString());
+ return error;
+ });
+}
+
+function expectSuccess(message, promise)
+{
+ debug("\n" + message);
+
+ return promise.then(function(result) {
+ // Expected to succeed.
+ debug("SUCCESS");
+ return result;
+ }, function(error) {
+ debug("FAILED: " + error.toString());
+
+ // Re-throw the error.
+ throw new Error("Test FAILED: " + message);
+ });
+}