Skip to content

Commit 3cf7cfb

Browse files
nodejs-github-botmarco-ippolito
authored andcommitted
test: update WPT for WebCryptoAPI to edd42c005c
PR-URL: #57365 Backport-PR-URL: #58589 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jason Zhang <xzha4350@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent f56e628 commit 3cf7cfb

15 files changed

+663
-335
lines changed

lib/internal/crypto/cfrg.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,14 @@ async function cfrgImportKey(
274274
'DataError');
275275
}
276276

277+
if (keyData.alg !== undefined && (name === 'Ed25519' || name === 'Ed448')) {
278+
if (keyData.alg !== name && keyData.alg !== 'EdDSA') {
279+
throw lazyDOMException(
280+
'JWK "alg" does not match the requested algorithm',
281+
'DataError');
282+
}
283+
}
284+
277285
if (!isPublic && typeof keyData.x !== 'string') {
278286
throw lazyDOMException('Invalid JWK', 'DataError');
279287
}

lib/internal/crypto/webcrypto.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ async function exportKeyJWK(key) {
475475
// Fall through
476476
case 'Ed448':
477477
jwk.crv ||= key.algorithm.name;
478+
jwk.alg = key.algorithm.name;
478479
return jwk;
479480
case 'AES-CTR':
480481
// Fall through

test/fixtures/wpt/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Last update:
3131
- user-timing: https://github.com/web-platform-tests/wpt/tree/5ae85bf826/user-timing
3232
- wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/cde25e7e3c/wasm/jsapi
3333
- wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi
34-
- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/b81831169b/WebCryptoAPI
34+
- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/edd42c005c/WebCryptoAPI
3535
- webidl/ecmascript-binding/es-exceptions: https://github.com/web-platform-tests/wpt/tree/a370aad338/webidl/ecmascript-binding/es-exceptions
3636
- webmessaging/broadcastchannel: https://github.com/web-platform-tests/wpt/tree/e97fac4791/webmessaging/broadcastchannel
3737

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// META: title=WebCryptoAPI: CryptoKey cached ECMAScript objects
2+
3+
// https://w3c.github.io/webcrypto/#dom-cryptokey-algorithm
4+
// https://github.com/servo/servo/issues/33908
5+
6+
promise_test(function() {
7+
return self.crypto.subtle.generateKey(
8+
{
9+
name: "AES-CTR",
10+
length: 256,
11+
},
12+
true,
13+
["encrypt"],
14+
).then(
15+
function(key) {
16+
let a = key.algorithm;
17+
let b = key.algorithm;
18+
assert_true(a === b);
19+
},
20+
function(err) {
21+
assert_unreached("generateKey threw an unexpected error: " + err.toString());
22+
}
23+
);
24+
}, "CryptoKey.algorithm getter returns cached object");
25+
26+
promise_test(function() {
27+
return self.crypto.subtle.generateKey(
28+
{
29+
name: "AES-CTR",
30+
length: 256,
31+
},
32+
true,
33+
["encrypt"],
34+
).then(
35+
function(key) {
36+
let a = key.usages;
37+
let b = key.usages;
38+
assert_true(a === b);
39+
},
40+
function(err) {
41+
assert_unreached("generateKey threw an unexpected error: " + err.toString());
42+
}
43+
);
44+
}, "CryptoKey.usages getter returns cached object");

test/fixtures/wpt/WebCryptoAPI/cryptokey_algorithm_returns_cached_object.https.any.js

Lines changed: 0 additions & 24 deletions
This file was deleted.

test/fixtures/wpt/WebCryptoAPI/digest/digest.https.any.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,20 @@
118118
});
119119
});
120120

121+
// Call digest() with empty algorithm object
122+
Object.keys(sourceData).forEach(function(size) {
123+
promise_test(function(test) {
124+
var promise = subtle.digest({}, sourceData[size])
125+
.then(function(result) {
126+
assert_unreached("digest() with missing algorithm name should have thrown a TypeError");
127+
}, function(err) {
128+
assert_equals(err.name, "TypeError", "Missing algorithm name should cause TypeError")
129+
});
130+
131+
return promise;
132+
}, "empty algorithm object with " + size);
133+
});
134+
121135

122136
done();
123137

test/fixtures/wpt/WebCryptoAPI/generateKey/failures.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ function run_test(algorithmNames) {
166166
});
167167
});
168168

169+
// Empty algorithm should fail with TypeError
170+
allValidUsages(["decrypt", "sign", "deriveBits"], true, []) // Small search space, shouldn't matter because should fail before used
171+
.forEach(function(usages) {
172+
[false, true, "RED", 7].forEach(function(extractable){
173+
testError({}, extractable, usages, "TypeError", "Empty algorithm");
174+
});
175+
});
176+
169177

170178
// Algorithms normalize okay, but usages bad (though not empty).
171179
// It shouldn't matter what other extractable is. Should fail

test/fixtures/wpt/WebCryptoAPI/import_export/ec_importKey_failures_fixtures.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ function getMismatchedJWKKeyData(algorithm) {
1919
return [];
2020
}
2121

22+
function getMismatchedKtyField(algorithm) {
23+
return mismatchedKtyField[algorithm.name];
24+
}
25+
26+
function getMismatchedCrvField(algorithm) {
27+
return mismatchedCrvField[algorithm.name];
28+
}
29+
2230
var validKeyData = {
2331
"P-521": [
2432
{
@@ -201,3 +209,17 @@ var missingJWKFieldKeyData = {
201209
}
202210
]
203211
};
212+
213+
// The 'kty' field doesn't match the key algorithm.
214+
var mismatchedKtyField = {
215+
"P-521": "OKP",
216+
"P-256": "OKP",
217+
"P-384": "OKP",
218+
}
219+
220+
// The 'kty' field doesn't match the key algorithm.
221+
var mismatchedCrvField = {
222+
"P-521": "P-256",
223+
"P-256": "P-384",
224+
"P-384": "P-521",
225+
}

test/fixtures/wpt/WebCryptoAPI/import_export/importKey_failures.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,79 @@ function run_test(algorithmNames) {
192192
});
193193
});
194194
});
195+
196+
// Missing mandatory "name" field on algorithm
197+
testVectors.forEach(function(vector) {
198+
var name = vector.name;
199+
// We just need *some* valid keydata, so pick the first available algorithm.
200+
var algorithm = allAlgorithmSpecifiersFor(name)[0];
201+
getValidKeyData(algorithm).forEach(function(test) {
202+
validUsages(vector, test.format, test.data).forEach(function(usages) {
203+
[true, false].forEach(function(extractable) {
204+
testError(test.format, {}, test.data, name, usages, extractable, "TypeError", "Missing algorithm name");
205+
});
206+
});
207+
});
208+
});
209+
210+
// The 'kty' field is not correct.
211+
testVectors.forEach(function(vector) {
212+
var name = vector.name;
213+
allAlgorithmSpecifiersFor(name).forEach(function(algorithm) {
214+
getValidKeyData(algorithm).forEach(function(test) {
215+
if (test.format === "jwk") {
216+
var data = {crv: test.data.crv, kty: test.data.kty, d: test.data.d, x: test.data.x, d: test.data.d};
217+
data.kty = getMismatchedKtyField(algorithm);
218+
var usages = validUsages(vector, 'jwk', test.data);
219+
testError('jwk', algorithm, data, name, usages, true, "DataError", "Invalid 'kty' field");
220+
}
221+
});
222+
});
223+
});
224+
225+
// The 'ext' field is not correct.
226+
testVectors.forEach(function(vector) {
227+
var name = vector.name;
228+
allAlgorithmSpecifiersFor(name).forEach(function(algorithm) {
229+
getValidKeyData(algorithm).forEach(function(test) {
230+
if (test.format === "jwk") {
231+
var data = {crv: test.data.crv, kty: test.data.kty, d: test.data.d, x: test.data.x, d: test.data.d};
232+
data.ext = false;
233+
var usages = validUsages(vector, 'jwk', test.data);
234+
testError('jwk', algorithm, data, name, usages, true, "DataError", "Import from a non-extractable");
235+
}
236+
});
237+
});
238+
});
239+
240+
// The 'use' field is incorrect.
241+
testVectors.forEach(function(vector) {
242+
var name = vector.name;
243+
allAlgorithmSpecifiersFor(name).forEach(function(algorithm) {
244+
getValidKeyData(algorithm).forEach(function(test) {
245+
if (test.format === "jwk") {
246+
var data = {crv: test.data.crv, kty: test.data.kty, d: test.data.d, x: test.data.x, d: test.data.d};
247+
data.use = "invalid";
248+
var usages = validUsages(vector, 'jwk', test.data);
249+
if (usages.length !== 0)
250+
testError('jwk', algorithm, data, name, usages, true, "DataError", "Invalid 'use' field");
251+
}
252+
});
253+
});
254+
});
255+
256+
// The 'crv' field is incorrect.
257+
testVectors.forEach(function(vector) {
258+
var name = vector.name;
259+
allAlgorithmSpecifiersFor(name).forEach(function(algorithm) {
260+
getValidKeyData(algorithm).forEach(function(test) {
261+
if (test.format === "jwk") {
262+
var data = {crv: test.data.crv, kty: test.data.kty, d: test.data.d, x: test.data.x, d: test.data.d};
263+
data.crv = getMismatchedCrvField(algorithm)
264+
var usages = validUsages(vector, 'jwk', test.data);
265+
testError('jwk', algorithm, data, name, usages, true, "DataError", "Invalid 'crv' field");
266+
}
267+
});
268+
});
269+
});
195270
}

test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey.js

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function runTests(algorithmName) {
1111
['spki', 'jwk', 'raw'].forEach(function(format) {
1212
if (format === "jwk") { // Not all fields used for public keys
1313
testFormat(format, algorithm, jwkData, algorithmName, usages, extractable);
14-
// Test for https://github.com/WICG/webcrypto-secure-curves/pull/24
14+
// Test for https://github.com/w3c/webcrypto/pull/401
1515
if (extractable) {
1616
testJwkAlgBehaviours(algorithm, jwkData.jwk, algorithmName, usages);
1717
}
@@ -27,7 +27,7 @@ function runTests(algorithmName) {
2727
['pkcs8', 'jwk'].forEach(function(format) {
2828
testFormat(format, algorithm, data, algorithmName, usages, extractable);
2929

30-
// Test for https://github.com/WICG/webcrypto-secure-curves/pull/24
30+
// Test for https://github.com/w3c/webcrypto/pull/401
3131
if (format === "jwk" && extractable) {
3232
testJwkAlgBehaviours(algorithm, data.jwk, algorithmName, usages);
3333
}
@@ -67,27 +67,34 @@ function testFormat(format, algorithm, keyData, keySize, usages, extractable) {
6767
});
6868
}
6969

70-
// Test importKey/exportKey "alg" behaviours, alg is ignored upon import and alg is missing for Ed25519 and Ed448 JWK export
71-
// https://github.com/WICG/webcrypto-secure-curves/pull/24
70+
// Test importKey/exportKey "alg" behaviours (https://github.com/w3c/webcrypto/pull/401)
71+
// - alg is ignored for ECDH import
72+
// - TODO: alg is checked to be the algorithm.name or EdDSA for Ed25519 and Ed448 import
73+
// - alg is missing for ECDH export
74+
// - alg is the algorithm name for Ed25519 and Ed448 export
7275
function testJwkAlgBehaviours(algorithm, keyData, crv, usages) {
7376
[algorithm, algorithm.name].forEach((alg) => {
74-
promise_test(function(test) {
75-
return subtle.importKey('jwk', { ...keyData, alg: 'this is ignored' }, alg, true, usages).
76-
then(function(key) {
77-
assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object");
78-
79-
return subtle.exportKey('jwk', key).
80-
then(function(result) {
81-
assert_equals(Object.keys(result).length, keyData.d ? 6 : 5, "Correct number of JWK members");
82-
assert_equals(result.alg, undefined, 'No JWK "alg" member is present');
83-
assert_true(equalJwk(keyData, result), "Round trip works");
84-
}, function(err) {
77+
(crv.startsWith('Ed') ? [algorithm.name, 'EdDSA'] : ['this is ignored']).forEach((jwkAlg) => {
78+
promise_test(function(test) {
79+
return subtle.importKey('jwk', { ...keyData, alg: jwkAlg }, alg, true, usages).
80+
then(function(key) {
81+
assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object");
82+
83+
return subtle.exportKey('jwk', key).
84+
then(function(result) {
85+
let expectedKeys = crv.startsWith('Ed') ? 6 : 5
86+
if (keyData.d) expectedKeys++
87+
assert_equals(Object.keys(result).length, expectedKeys, "Correct number of JWK members");
88+
assert_equals(result.alg, crv.startsWith('Ed') ? algorithm.name : undefined, 'Expected JWK "alg" member');
89+
assert_true(equalJwk(keyData, result), "Round trip works");
90+
}, function(err) {
91+
assert_unreached("Threw an unexpected error: " + err.toString());
92+
});
93+
}, function(err) {
8594
assert_unreached("Threw an unexpected error: " + err.toString());
86-
});
87-
}, function(err) {
88-
assert_unreached("Threw an unexpected error: " + err.toString());
89-
});
90-
}, "Good parameters with ignored JWK alg: " + crv.toString() + " " + parameterString('jwk', keyData, alg, true, usages));
95+
});
96+
}, 'Good parameters with JWK alg' + (crv.startsWith('Ed') ? ` ${jwkAlg}: ` : ': ') + crv.toString() + " " + parameterString('jwk', keyData, alg, true, usages, jwkAlg));
97+
});
9198
});
9299
}
93100

test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey_failures_fixtures.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ function getMismatchedJWKKeyData(algorithm) {
1717
return mismatchedJWKKeyData[algorithm.name];
1818
}
1919

20+
function getMismatchedKtyField(algorithm) {
21+
return mismatchedKtyField[algorithm.name];
22+
}
23+
24+
function getMismatchedCrvField(algorithm) {
25+
return mismatchedCrvField[algorithm.name];
26+
}
27+
2028
var validKeyData = {
2129
"Ed25519": [
2230
{
@@ -412,3 +420,19 @@ var mismatchedJWKKeyData = {
412420
},
413421
],
414422
}
423+
424+
// The 'kty' field doesn't match the key algorithm.
425+
var mismatchedKtyField = {
426+
"Ed25519": "EC",
427+
"X25519": "EC",
428+
"Ed448": "EC",
429+
"X448": "EC",
430+
}
431+
432+
// The 'kty' field doesn't match the key algorithm.
433+
var mismatchedCrvField = {
434+
"Ed25519": "X25519",
435+
"X25519": "Ed448",
436+
"Ed448": "X25519",
437+
"X448": "Ed25519",
438+
}

0 commit comments

Comments
 (0)