Skip to content

Commit

Permalink
test,crypto: update WebCryptoAPI WPT
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Sep 20, 2024
1 parent 260f1f4 commit 0816051
Show file tree
Hide file tree
Showing 20 changed files with 405 additions and 328 deletions.
2 changes: 1 addition & 1 deletion test/fixtures/wpt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Last update:
- user-timing: https://github.com/web-platform-tests/wpt/tree/5ae85bf826/user-timing
- wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/cde25e7e3c/wasm/jsapi
- wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi
- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/272064ebf9/WebCryptoAPI
- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/203d2ac459/WebCryptoAPI
- webidl/ecmascript-binding/es-exceptions: https://github.com/web-platform-tests/wpt/tree/a370aad338/webidl/ecmascript-binding/es-exceptions
- webmessaging/broadcastchannel: https://github.com/web-platform-tests/wpt/tree/e97fac4791/webmessaging/broadcastchannel
- webstorage: https://github.com/web-platform-tests/wpt/tree/9dafa89214/webstorage
Expand Down
48 changes: 30 additions & 18 deletions test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
function define_tests_25519() {
return define_tests("X25519");
}

function define_tests_448() {
return define_tests("X448");
}

function define_tests() {
function define_tests(algorithmName) {
// May want to test prefixed implementations.
var subtle = self.crypto.subtle;

// Verify the derive functions perform checks against the all-zero value results,
// ensuring small-order points are rejected.
// https://www.rfc-editor.org/rfc/rfc7748#section-6.1
Object.keys(kSmallOrderPoint).forEach(function(algorithmName) {
{
kSmallOrderPoint[algorithmName].forEach(function(test) {
promise_test(async() => {
let derived;
Expand All @@ -28,15 +35,16 @@ function define_tests() {
assert_equals(derived, undefined, "Operation succeeded, but should not have.");
}, algorithmName + " key derivation checks for all-zero value result with a key of order " + test.order);
});
});
}

return importKeys(pkcs8, spki, sizes)
.then(function(results) {
publicKeys = results.publicKeys;
privateKeys = results.privateKeys;
noDeriveBitsKeys = results.noDeriveBitsKeys;
ecdhKeys = results.ecdhKeys;

Object.keys(sizes).forEach(function(algorithmName) {
{
// Basic success case
promise_test(function(test) {
return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName])
Expand Down Expand Up @@ -101,11 +109,7 @@ function define_tests() {

// - wrong algorithm
promise_test(function(test) {
publicKey = publicKeys["X25519"];
if (algorithmName === "X25519") {
publicKey = publicKeys["X448"];
}
return subtle.deriveBits({name: algorithmName, public: publicKey}, privateKeys[algorithmName], 8 * sizes[algorithmName])
return subtle.deriveBits({name: algorithmName, public: ecdhKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName])
.then(function(derivation) {
assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError");
}, function(err) {
Expand Down Expand Up @@ -165,16 +169,17 @@ function define_tests() {
assert_equals(err.name, "OperationError", "Should throw correct error, not " + err.name + ": " + err.message);
});
}, algorithmName + " asking for too many bits");
});
}
});

function importKeys(pkcs8, spki, sizes) {
var privateKeys = {};
var publicKeys = {};
var noDeriveBitsKeys = {};
var ecdhPublicKeys = {};

var promises = [];
Object.keys(pkcs8).forEach(function(algorithmName) {
{
var operation = subtle.importKey("pkcs8", pkcs8[algorithmName],
{name: algorithmName},
false, ["deriveBits", "deriveKey"])
Expand All @@ -184,8 +189,8 @@ function define_tests() {
privateKeys[algorithmName] = null;
});
promises.push(operation);
});
Object.keys(pkcs8).forEach(function(algorithmName) {
}
{
var operation = subtle.importKey("pkcs8", pkcs8[algorithmName],
{name: algorithmName},
false, ["deriveKey"])
Expand All @@ -195,8 +200,8 @@ function define_tests() {
noDeriveBitsKeys[algorithmName] = null;
});
promises.push(operation);
});
Object.keys(spki).forEach(function(algorithmName) {
}
{
var operation = subtle.importKey("spki", spki[algorithmName],
{name: algorithmName},
false, [])
Expand All @@ -206,10 +211,17 @@ function define_tests() {
publicKeys[algorithmName] = null;
});
promises.push(operation);
});

}
{
var operation = subtle.importKey("spki", ecSPKI,
{name: "ECDH", namedCurve: "P-256"},
false, [])
.then(function(key) {
ecdhPublicKeys[algorithmName] = key;
});
}
return Promise.all(promises)
.then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveBitsKeys: noDeriveBitsKeys}});
.then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveBitsKeys: noDeriveBitsKeys, ecdhKeys: ecdhPublicKeys}});
}

// Compares two ArrayBuffer or ArrayBufferView objects. If bitCount is
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves
// META: script=cfrg_curves_bits_fixtures.js
// META: script=cfrg_curves_bits.js

// Define subtests from a `promise_test` to ensure the harness does not
// complete before the subtests are available. `explicit_done` cannot be used
// for this purpose because the global `done` function is automatically invoked
// by the WPT infrastructure in dedicated worker tests defined using the
// "multi-global" pattern.
promise_test(define_tests_25519, 'setup - define tests');
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// META: title=WebCryptoAPI: deriveBits() Using ECDH with CFRG Elliptic Curves
// META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves
// META: script=cfrg_curves_bits_fixtures.js
// META: script=cfrg_curves_bits.js

Expand All @@ -7,4 +7,4 @@
// for this purpose because the global `done` function is automatically invoked
// by the WPT infrastructure in dedicated worker tests defined using the
// "multi-global" pattern.
promise_test(define_tests, 'setup - define tests');
promise_test(define_tests_448, 'setup - define tests');

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 32 additions & 19 deletions test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
function define_tests_25519() {
return define_tests("X25519");
}

function define_tests_448() {
return define_tests("X448");
}

function define_tests() {
function define_tests(algorithmName) {
// May want to test prefixed implementations.
var subtle = self.crypto.subtle;

Expand All @@ -8,7 +15,7 @@ function define_tests() {
// https://www.rfc-editor.org/rfc/rfc7748#section-6.1
// TODO: The spec states that the check must be done on use, but there is discussion about doing it on import.
// https://github.com/WICG/webcrypto-secure-curves/pull/13
Object.keys(kSmallOrderPoint).forEach(function(algorithmName) {
{
kSmallOrderPoint[algorithmName].forEach(function(test) {
promise_test(async() => {
let derived;
Expand All @@ -32,10 +39,10 @@ function define_tests() {
assert_equals(derived, undefined, "Operation succeeded, but should not have.");
}, algorithmName + " deriveBits checks for all-zero value result with a key of order " + test.order);
});
});
}

// Ensure the keys generated by each algorithm are valid for key derivation.
Object.keys(sizes).forEach(function(algorithmName) {
{
promise_test(async() => {
let derived;
try {
Expand All @@ -46,15 +53,16 @@ function define_tests() {
}
assert_false (derived === undefined, "Key derivation failed.");
}, "Key derivation using a " + algorithmName + " generated keys.");
});
}

return importKeys(pkcs8, spki, sizes)
.then(function(results) {
publicKeys = results.publicKeys;
privateKeys = results.privateKeys;
noDeriveKeyKeys = results.noDeriveKeyKeys;
ecdhKeys = results.ecdhKeys;

Object.keys(sizes).forEach(function(algorithmName) {
{
// Basic success case
promise_test(function(test) {
return subtle.deriveKey({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"])
Expand Down Expand Up @@ -102,11 +110,7 @@ function define_tests() {

// - wrong algorithm
promise_test(function(test) {
publicKey = publicKeys["X25519"];
if (algorithmName === "X25519") {
publicKey = publicKeys["X448"];
}
return subtle.deriveKey({name: algorithmName, public: publicKey}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"])
return subtle.deriveKey({name: algorithmName, public: ecdhKeys[algorithmName]}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"])
.then(function(key) {return crypto.subtle.exportKey("raw", key);})
.then(function(exportedKey) {
assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError");
Expand Down Expand Up @@ -161,16 +165,17 @@ function define_tests() {
});
});
}, algorithmName + " public property value is a secret key");
});
}
});

function importKeys(pkcs8, spki, sizes) {
var privateKeys = {};
var publicKeys = {};
var noDeriveKeyKeys = {};
var ecdhPublicKeys = {};

var promises = [];
Object.keys(pkcs8).forEach(function(algorithmName) {
{
var operation = subtle.importKey("pkcs8", pkcs8[algorithmName],
{name: algorithmName},
false, ["deriveBits", "deriveKey"])
Expand All @@ -180,8 +185,8 @@ function define_tests() {
privateKeys[algorithmName] = null;
});
promises.push(operation);
});
Object.keys(pkcs8).forEach(function(algorithmName) {
}
{
var operation = subtle.importKey("pkcs8", pkcs8[algorithmName],
{name: algorithmName},
false, ["deriveBits"])
Expand All @@ -191,8 +196,8 @@ function define_tests() {
noDeriveKeyKeys[algorithmName] = null;
});
promises.push(operation);
});
Object.keys(spki).forEach(function(algorithmName) {
}
{
var operation = subtle.importKey("spki", spki[algorithmName],
{name: algorithmName},
false, [])
Expand All @@ -202,10 +207,18 @@ function define_tests() {
publicKeys[algorithmName] = null;
});
promises.push(operation);
});
}
{
var operation = subtle.importKey("spki", ecSPKI,
{name: "ECDH", namedCurve: "P-256"},
false, [])
.then(function(key) {
ecdhPublicKeys[algorithmName] = key;
});
}

return Promise.all(promises)
.then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveKeyKeys: noDeriveKeyKeys}});
.then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveKeyKeys: noDeriveKeyKeys, ecdhKeys: ecdhPublicKeys}});
}

// Compares two ArrayBuffer or ArrayBufferView objects. If bitCount is
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves
// META: script=cfrg_curves_bits_fixtures.js
// META: script=cfrg_curves_keys.js

// Define subtests from a `promise_test` to ensure the harness does not
// complete before the subtests are available. `explicit_done` cannot be used
// for this purpose because the global `done` function is automatically invoked
// by the WPT infrastructure in dedicated worker tests defined using the
// "multi-global" pattern.
promise_test(define_tests_25519, 'setup - define tests');
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
// for this purpose because the global `done` function is automatically invoked
// by the WPT infrastructure in dedicated worker tests defined using the
// "multi-global" pattern.
promise_test(define_tests, 'setup - define tests');
promise_test(define_tests_448, 'setup - define tests');
Loading

0 comments on commit 0816051

Please sign in to comment.