Skip to content

Commit ea5e7f9

Browse files
committed
QuickJS: added WebCrypto import tests forgotten in 75ca26f.
1 parent 8701fd4 commit ea5e7f9

File tree

5 files changed

+353
-17
lines changed

5 files changed

+353
-17
lines changed

external/qjs_webcrypto_module.c

+2-15
Original file line numberDiff line numberDiff line change
@@ -4167,20 +4167,7 @@ qjs_webcrypto_key_algorithm(JSContext *cx, JSValueConst this_val)
41674167
return JS_EXCEPTION;
41684168
}
41694169

4170-
ret = JS_NewObject(cx);
4171-
if (JS_IsException(ret)) {
4172-
JS_FreeValue(cx, obj);
4173-
return JS_EXCEPTION;
4174-
}
4175-
4176-
if (JS_DefinePropertyValueStr(cx, ret, "name", hash, JS_PROP_C_W_E)
4177-
< 0)
4178-
{
4179-
JS_FreeValue(cx, obj);
4180-
return JS_EXCEPTION;
4181-
}
4182-
4183-
if (JS_DefinePropertyValueStr(cx, obj, "hash", ret, JS_PROP_C_W_E)
4170+
if (JS_DefinePropertyValueStr(cx, obj, "hash", hash, JS_PROP_C_W_E)
41844171
< 0)
41854172
{
41864173
JS_FreeValue(cx, obj);
@@ -4377,7 +4364,7 @@ qjs_jwk_kty(JSContext *cx, JSValueConst value)
43774364
}
43784365
}
43794366

4380-
JS_ThrowTypeError(cx, "invalid JWK key type: %s", kty.start);
4367+
JS_ThrowTypeError(cx, "invalid JWK key type: \"%s\"", kty.start);
43814368
JS_FreeCString(cx, (char *) kty.start);
43824369

43834370
return QJS_KEY_JWK_KTY_UNKNOWN;

test/webcrypto/import.t.mjs

+334
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
/*---
2+
includes: [compatNjs.js, compatFs.js, compatWebcrypto.js, runTsuite.js, webCryptoUtils.js, compareArray.js]
3+
flags: [async]
4+
---*/
5+
6+
async function test(params) {
7+
let key = await crypto.subtle.importKey(params.key.fmt,
8+
params.key.key,
9+
params.key.alg,
10+
params.key.extractable,
11+
params.key.usage);
12+
13+
if (params.expected && !validate_key(key, params)) {
14+
throw Error(`failed validate`);
15+
}
16+
17+
return 'SUCCESS';
18+
}
19+
20+
function p(args, default_opts) {
21+
let key, pem;
22+
let params = merge({}, default_opts);
23+
params = merge(params, args);
24+
25+
switch (params.key.fmt) {
26+
case "spki":
27+
pem = fs.readFileSync(`test/webcrypto/${params.key.key}`);
28+
key = pem_to_der(pem, "PUBLIC");
29+
break;
30+
case "pkcs8":
31+
pem = fs.readFileSync(`test/webcrypto/${params.key.key}`);
32+
key = pem_to_der(pem, "PRIVATE");
33+
break;
34+
case "jwk":
35+
key = load_jwk(params.key.key);
36+
break;
37+
case "raw":
38+
key = Buffer.from(params.key.key, "base64url");
39+
break;
40+
default:
41+
throw Error("Unknown encoding key format");
42+
}
43+
44+
params.key.key = key;
45+
46+
return params;
47+
}
48+
49+
function validate_key(key, params) {
50+
let expected = params.expected;
51+
if (expected.algorithm) {
52+
if (!key.algorithm) {
53+
throw Error(`missing import key algorithm`);
54+
}
55+
56+
if (expected.algorithm.name !== key.algorithm.name) {
57+
throw Error(`unexpected import key algorithm name: ${key.algorithm.name} != ${expected.algorithm.name}`);
58+
}
59+
60+
if (has_njs()
61+
&& expected.algorithm.name == "HMAC"
62+
&& (expected.algorithm.hash !== key.algorithm.hash))
63+
{
64+
throw Error(`unexpected import key algorithm hash: ${JSON.stringify(key.algorithm.hash)} != ${expected.algorithm.hash}`);
65+
}
66+
}
67+
68+
if (expected.type !== key.type) {
69+
throw Error(`unexpected import key type: ${key.type} != ${expected.type}`);
70+
}
71+
72+
if (expected.extractable !== key.extractable) {
73+
throw Error(`unexpected import key extractable: ${key.extractable} != ${expected.extractable}`);
74+
}
75+
76+
if (expected.usages && !compareArray(expected.usages, key.usages)) {
77+
throw Error(`unexpected import key usages: ${key.usages} != ${expected.usages}`);
78+
}
79+
80+
return true;
81+
}
82+
83+
let aes_tsuite = {
84+
name: "AES importing",
85+
skip: () => (!has_webcrypto()),
86+
T: test,
87+
prepare_args: p,
88+
opts: {},
89+
90+
tests: [
91+
{ key: { fmt: "jwk",
92+
key: { alg: 'A128CBC', ext: true, k: 'AAAAAAAAAAAAAAAAAAAAAA', key_ops: [ 'decrypt', 'encrypt' ], kty: 'oct'},
93+
alg: { name: "AES-CBC" },
94+
extractable: true,
95+
usage: [ "decrypt", "encrypt" ] },
96+
expected: { algorithm: { name: "AES-CBC" },
97+
extractable: true,
98+
type: "secret",
99+
usages: [ "decrypt", "encrypt" ] } },
100+
{ key: { fmt: "jwk",
101+
key: { alg: 'A128CBC', ext: true, k: 'AAAAAAAAAAAAAAAAAAAAAA', key_ops: [ 'encrypt' ], kty: 'oct' },
102+
alg: { name: "AES-CBC" },
103+
extractable: true,
104+
usage: [ "encrypt" ] },
105+
expected: { algorithm: { name: "AES-CBC" },
106+
extractable: true,
107+
type: "secret",
108+
usages: [ "encrypt" ] } },
109+
{ key: { fmt: "jwk",
110+
key: { alg: 'A128CBC', ext: true, k: 'AAAAAAAAAAAAAAAAAAAAAA', kty: 'oct' },
111+
alg: { name: "AES-CBC" },
112+
extractable: true,
113+
usage: [ "encrypt" ] },
114+
expected: { algorithm: { name: "AES-CBC" },
115+
extractable: true,
116+
type: "secret",
117+
usages: [ "encrypt" ] } },
118+
{ key: { fmt: "jwk",
119+
key: { alg: 'A128CBC', k: 'AAAAAAAAAAAAAAAAAAAAAA', kty: 'oct' },
120+
alg: { name: "AES-CBC" },
121+
extractable: true,
122+
usage: [ "encrypt" ] },
123+
expected: { algorithm: { name: "AES-CBC" },
124+
extractable: true,
125+
type: "secret",
126+
usages: [ "encrypt" ] } },
127+
{ key: { fmt: "jwk",
128+
key: { alg: 'A128CBC', ext: true, k: 'AA', key_ops: [ 'encrypt', 'decrypt' ], kty: 'oct' },
129+
alg: { name: "AES-CBC" },
130+
usage: [ "encrypt", "decrypt" ] },
131+
exception: "TypeError: key size and \"alg\" value \"A128CBC\" mismatch" },
132+
{ key: { fmt: "jwk",
133+
key: { alg: 'A129CBC', ext: true, k: 'AA', key_ops: [ 'encrypt', 'decrypt' ], kty: 'oct' },
134+
alg: { name: "AES-CBC" },
135+
usage: [ "encrypt", "decrypt" ] },
136+
exception: "TypeError: unexpected \"alg\" value \"A129CBC\" for JWK key" },
137+
{ key: { fmt: "jwk",
138+
key: { alg: 'A128CBC', ext: false, k: 'AAAAAAAAAAAAAAAAAAAAAA', kty: 'oct' },
139+
alg: { name: "AES-CBC" },
140+
extractable: true,
141+
usage: [ "encrypt" ] },
142+
exception: "TypeError: JWK oct is not extractable" },
143+
{ key: { fmt: "jwk",
144+
key: { alg: 1, ext: true, k: 'AA', key_ops: ['encrypt', 'decrypt'], kty: 'oct' },
145+
alg: { name: "AES-CBC" },
146+
usage: [ "encrypt", "decrypt" ] },
147+
exception: "TypeError: Invalid JWK oct alg" },
148+
]};
149+
150+
let ec_tsuite = {
151+
name: "EC importing",
152+
skip: () => (!has_webcrypto()),
153+
T: test,
154+
prepare_args: p,
155+
opts: {},
156+
157+
tests: [
158+
{ key: { fmt: "jwk",
159+
key: "ec.jwk",
160+
alg: { name: "ECDSA", namedCurve: "P-256" },
161+
extractable: true,
162+
usage: [ "sign" ] },
163+
expected: { algorithm: { name: "ECDSA", namedCurve: "SHA-256" },
164+
extractable: true,
165+
type: "private",
166+
usages: [ "sign" ] } },
167+
{ key: { fmt: "spki",
168+
key: "ec.spki",
169+
alg: { name: "ECDSA", namedCurve: "P-256" },
170+
extractable: true,
171+
usage: [ "verify" ] },
172+
expected: { algorithm: { name: "ECDSA", namedCurve: "SHA-256" },
173+
extractable: true,
174+
type: "public",
175+
usages: [ "verify" ] } },
176+
{ key: { fmt: "pkcs8",
177+
key: "ec.pkcs8",
178+
alg: { name: "ECDSA", namedCurve: "P-256" },
179+
extractable: true,
180+
usage: [ "sign" ] },
181+
expected: { algorithm: { name: "ECDSA", namedCurve: "SHA-256" },
182+
extractable: true,
183+
type: "private",
184+
usages: [ "sign" ] } },
185+
{ key: { fmt: "raw",
186+
key: "BHFFLGURrlWEXhok0JfTKke4q-nWSIMPvKTPhdKYSVnc4Nzn_7uNz0AA3U4fhpfVxSD4U5QciGyEoM4r3jC7bjI",
187+
alg: { name: "ECDSA", namedCurve: "P-256" },
188+
extractable: true,
189+
usage: [ "verify" ] },
190+
expected: { algorithm: { name: "ECDSA", namedCurve: "SHA-256" },
191+
extractable: true,
192+
type: "public",
193+
usages: [ "verify" ] } },
194+
195+
{ key: { fmt: "pkcs8",
196+
key: "ec.pkcs8",
197+
alg: { name: "ECDSA", namedCurve: "unknown_named_curve" },
198+
extractable: true,
199+
usage: [ "sign" ] },
200+
exception: "TypeError: unknown namedCurve: \"unknown_named_curve\"" },
201+
{ key: { fmt: "spki",
202+
key: "rsa.spki",
203+
alg: { name: "ECDSA", namedCurve: "P-256" },
204+
extractable: true,
205+
usage: [ "verify" ] },
206+
exception: "TypeError: EC key is not found" },
207+
{ key: { fmt: "spki",
208+
key: "ec.spki",
209+
alg: { name: "ECDSA", namedCurve: "P-384" },
210+
extractable: true,
211+
usage: [ "verify" ] },
212+
exception: "TypeError: name curve mismatch" },
213+
{ key: { fmt: "raw",
214+
key: "CHFFLGURrlWEXhok0JfTKke4q-nWSIMPvKTPhdKYSVnc4Nzn_7uNz0AA3U4fhpfVxSD4U5QciGyEoM4r3jC7bjI",
215+
alg: { name: "ECDSA", namedCurve: "P-256" },
216+
extractable: true,
217+
usage: [ "verify" ] },
218+
exception: "TypeError: EC_POINT_oct2point()" },
219+
]};
220+
221+
let hmac_tsuite = {
222+
name: "HMAC importing",
223+
skip: () => (!has_webcrypto()),
224+
T: test,
225+
prepare_args: p,
226+
opts: {},
227+
228+
tests: [
229+
{ key: { fmt: "raw",
230+
key: "AA",
231+
alg: { name: "HMAC", hash: "SHA-256" },
232+
extractable: true,
233+
usage: [ "sign", "verify" ] },
234+
expected: { algorithm: { name: "HMAC", hash: "SHA-256" },
235+
extractable: true,
236+
type: "secret",
237+
usages: [ "sign", "verify" ] } },
238+
{ key: { fmt: "raw",
239+
key: "AA",
240+
alg: { name: "HMAC", hash: "SHA-384" },
241+
extractable: true,
242+
usage: [ "sign", "verify" ] },
243+
expected: { algorithm: { name: "HMAC", hash: "SHA-384" },
244+
extractable: true,
245+
type: "secret",
246+
usages: [ "sign", "verify" ] } },
247+
{ key: { fmt: "raw",
248+
key: "AA",
249+
alg: { name: "HMAC", hash: "SHA-384" },
250+
extractable: false,
251+
usage: [ "sign", "verify" ] },
252+
expected: { algorithm: { name: "HMAC", hash: "SHA-384" },
253+
extractable: false,
254+
type: "secret",
255+
usages: [ "sign", "verify" ] } },
256+
257+
{ key: { fmt: "raw",
258+
key: "AA",
259+
alg: { name: "HMAC", hash: "SHA-385" },
260+
extractable: true,
261+
usage: [ "sign", "verify" ] },
262+
exception: "TypeError: unknown hash name: \"SHA-385\"" },
263+
{ key: { fmt: "spki",
264+
key: "ec.spki",
265+
alg: { name: "HMAC" },
266+
extractable: true,
267+
usage: [ "sign" ] },
268+
exception: "TypeError: unsupported key fmt \"spki\" for \"HMAC\" key" },
269+
{ key: { fmt: "raw",
270+
key: "AA",
271+
alg: { name: "HMAC", hash: "SHA-384" },
272+
extractable: true,
273+
usage: [ "encrypt" ] },
274+
exception: "TypeError: unsupported key usage for \"HMAC\" key" },
275+
{ key: { fmt: "raw",
276+
key: "AA",
277+
alg: { name: "HMAC", hash: "SHA-384" },
278+
extractable: true,
279+
usage: [ "invalid_usage" ] },
280+
exception: "TypeError: unknown key usage: \"invalid_usage\"" },
281+
282+
{ key: { fmt: "jwk",
283+
key: { alg: 'HS384', ext: true, k: 'AA', key_ops: [ 'sign', 'verify' ], kty: 'oct' },
284+
alg: { name: "HMAC", hash: "SHA-384" },
285+
extractable: true,
286+
usage: [ "sign", "verify" ] },
287+
expected: { algorithm: { name: "HMAC", hash: "SHA-384" },
288+
extractable: true,
289+
type: "secret",
290+
usages: [ "sign", "verify" ] } },
291+
{ key: { fmt: "jwk",
292+
key: { alg: 'HS256', ext: true, k: 'AA', key_ops: [ 'sign' ], kty: 'oct' },
293+
alg: { name: "HMAC", hash: "SHA-256" },
294+
extractable: true,
295+
usage: [ "sign" ]},
296+
expected: { algorithm: { name: "HMAC", hash: "SHA-256" },
297+
extractable: true,
298+
type: "secret",
299+
usages: [ "sign" ] } },
300+
{ key: { fmt: "jwk",
301+
key: { alg: 'HS256', k: 'AA', kty: 'oct' },
302+
alg: { name: "HMAC", hash: "SHA-256" },
303+
extractable: true,
304+
usage: [ "sign" ]},
305+
expected: { algorithm: { name: "HMAC", hash: "SHA-256" },
306+
extractable: true,
307+
type: "secret",
308+
usages: [ "sign" ] } },
309+
{ key: { fmt: "jwk",
310+
key: { alg: 'HS385', ext: true, k: 'AA', key_ops: [ 'sign', 'verify' ], kty: 'oct' },
311+
alg: { name: "HMAC", hash: "SHA-385" },
312+
extractable: true,
313+
usage: [ "sign", "verify" ] },
314+
exception: "TypeError: unexpected \"alg\" value \"HS385\" for JWK key" },
315+
{ key: { fmt: "jwk",
316+
key: { alg: 'HS384', ext: true, k: 'AA', key_ops: [ 'sign', 'verify' ], kty: 'invalid_kty' },
317+
alg: { name: "HMAC", hash: "SHA-384" },
318+
extractable: true,
319+
usage: [ "sign", "verify" ] },
320+
exception: "TypeError: invalid JWK key type: \"invalid_kty\"" },
321+
{ key: { fmt: "jwk",
322+
key: { alg: 'HS256', ext: true, key_ops: [ 'sign' ], kty: 'oct' },
323+
alg: { name: "HMAC", hash: "SHA-256" },
324+
extractable: true,
325+
usage: [ "sign" ]},
326+
exception: "TypeError: Invalid JWK oct key" },
327+
]};
328+
329+
run([
330+
aes_tsuite,
331+
ec_tsuite,
332+
hmac_tsuite,
333+
])
334+
.then($DONE, $DONE);

test/webcrypto/rsa.pkcs8.broken2

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGAAMlJsaCQvFQDOYcm
3+
GWvl1AWYNTdcsBTD1KVrBdZGkhnnffD911ID84F/NMKcs3eanRrgC6p39pTHOzvD
4+
6xgbTuWK70JSPejV9I1KOW3OcM9ttKG9wFAnkJ038flBajOKQsI6A0qNj5aYSXVo
5+
BWMphgWgQiYJxDUC/R9Tf/P8jYjfAgMBAAECgYEAj06DQyCopFujYoASi0oWmGEU
6+
SjUYO8BsrdSzVCnsLLsuZBwlZ4Peouyw4Hl2IIoYniCyzYwZJzVtC5Dh2MjgcrJT
7+
G5nX3FfheuabGl4in0583C51ZYWlVpDvBWw8kJTfXjiKH4z6ZA9dWdT5Y3aH/kOf
8+
+znUc7eTvuzISs61x/kCQQD0BJvbLDlvx3u6esW47LLgQNw9ufMSlu5UYBJ4c+qQ
9+
5HAeyp4Zt/AaWENhJitjQcLBSxIFIVw7dIN67RnTNK8VAkEA0yvzzgHo/PGYSlVj
10+
+M3965AwQF2wTXz82MZHv6EfcCHKuBfCSecr+igqLHhzfynAQjjf39VrXuPuRL23
11+
REF1IwJBAKVFydo0peJTljXDmc+aYb0JsSINo9jfaSS0vU3gFOt2DYqNaW+56WGu
12+
jlRqadCcZbBNjDL1WWbbj4HevTMT59ECQEWaKgzPolykwN5XUNE0DCp1ZwIAH1kb
13+
Bjfo+sMVt0f9S1TsN9SmBl+4l1X7CY5zU3RATMH5FR+8ns83fM1ZieMCQQDZEQ+d
14+
FAhouzJrnCXAXDTCHA9oBtNmnaN+C6G2DmCi79iu7sLHP9vzdgU+CgjrG4YTU5ex
15+
aRFNOhLwW4hYKs0F
16+
-----END PRIVATE KEY-----

test/webcrypto/rsa_decoding.t.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ let rsa_tsuite = {
3535
{ pem: "rsa.pkcs8", src: "text.base64.rsa-oaep.enc", expected: "WAKAWAKA" },
3636
{ pem: "ec.pkcs8", src: "text.base64.rsa-oaep.enc", exception: "Error: RSA key is not found" },
3737
{ pem: "rsa.pkcs8.broken", src: "text.base64.rsa-oaep.enc", exception: "Error: d2i_PKCS8_PRIV_KEY_INFO_bio() failed" },
38+
{ pem: "rsa.pkcs8.broken2", src: "text.base64.rsa-oaep.enc", exception: "TypeError: EVP_PKCS82PKEY() failed" },
3839
]};
3940

4041
run([rsa_tsuite])

test/webcrypto/sign.t.mjs

-2
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,6 @@ let ecdsa_tsuite = {
422422
{ verify: true, import_alg: { hash: "SHA-512" }, expected: true },
423423
{ verify: true, import_alg: { hash: "SHA-1" }, expected: true },
424424
{ verify: true, verify_key: { key: "ec2.spki" }, expected: false },
425-
{ verify: true, verify_key: { key: "rsa.spki" }, exception: "Error: EC key is not found" },
426-
{ verify: true, import_alg: { namedCurve: "P-384" }, exception: "Error: name curve mismatch" },
427425

428426
{ verify: true,
429427
verify_key: { key: "BHFFLGURrlWEXhok0JfTKke4q-nWSIMPvKTPhdKYSVnc4Nzn_7uNz0AA3U4fhpfVxSD4U5QciGyEoM4r3jC7bjI",

0 commit comments

Comments
 (0)