aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Volyntsev <xeioex@nginx.com>2025-05-07 19:11:24 -0700
committerDmitry Volyntsev <xeioexception@gmail.com>2025-05-08 09:30:06 -0700
commit7bbb8c2753ea236a1202f4664532f06da97a0d0e (patch)
tree01bfeac4e791393f7d144f2337c0bfc69ee448c6
parent0c7bbc4091853f75d7236cfbb8ed2e18e1c95164 (diff)
downloadnjs-7bbb8c2753ea236a1202f4664532f06da97a0d0e.tar.gz
njs-7bbb8c2753ea236a1202f4664532f06da97a0d0e.zip
WebCrypto: added support for HMAC as derivedKeyAlgorithm.
In crypto.subtle.deriveKey(). This closes #905 issue on Github.
-rw-r--r--external/njs_webcrypto_module.c3
-rw-r--r--external/qjs_webcrypto_module.c3
-rw-r--r--test/webcrypto/derive.t.mjs30
3 files changed, 32 insertions, 4 deletions
diff --git a/external/njs_webcrypto_module.c b/external/njs_webcrypto_module.c
index d2918891..6f4b49e1 100644
--- a/external/njs_webcrypto_module.c
+++ b/external/njs_webcrypto_module.c
@@ -1532,6 +1532,9 @@ njs_ext_derive(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
break;
+ case NJS_ALGORITHM_HMAC:
+ break;
+
default:
njs_vm_internal_error(vm, "not implemented deriveKey: \"%V\"",
njs_algorithm_string(dalg));
diff --git a/external/qjs_webcrypto_module.c b/external/qjs_webcrypto_module.c
index a28a8581..29aea329 100644
--- a/external/qjs_webcrypto_module.c
+++ b/external/qjs_webcrypto_module.c
@@ -1756,6 +1756,9 @@ qjs_webcrypto_derive(JSContext *cx, JSValueConst this_val, int argc,
break;
+ case QJS_ALGORITHM_HMAC:
+ break;
+
default:
JS_ThrowTypeError(cx, "not implemented deriveKey: \"%s\"",
qjs_algorithm_string(dalg));
diff --git a/test/webcrypto/derive.t.mjs b/test/webcrypto/derive.t.mjs
index 5ac13459..4d865da3 100644
--- a/test/webcrypto/derive.t.mjs
+++ b/test/webcrypto/derive.t.mjs
@@ -3,6 +3,16 @@ includes: [compatFs.js, compatBuffer.js, compatWebcrypto.js, runTsuite.js, webCr
flags: [async]
---*/
+function has_usage(usage, x) {
+ for (let i = 0; i < usage.length; i++) {
+ if (x === usage[i]) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
async function test(params) {
let r;
let encoder = new TextEncoder();
@@ -12,10 +22,17 @@ async function test(params) {
if (params.derive === "key") {
let key = await crypto.subtle.deriveKey(params.algorithm, keyMaterial,
params.derivedAlgorithm,
- true, [ "encrypt", "decrypt" ]);
+ true, params.usage);
+
+ if (has_usage(params.usage, "encrypt")) {
+ r = await crypto.subtle.encrypt(params.derivedAlgorithm, key,
+ encoder.encode(params.text));
+
+ } else if (has_usage(params.usage, "sign")) {
+ r = await crypto.subtle.sign(params.derivedAlgorithm, key,
+ encoder.encode(params.text));
+ }
- r = await crypto.subtle.encrypt(params.derivedAlgorithm, key,
- encoder.encode(params.text));
} else {
r = await crypto.subtle.deriveBits(params.algorithm, keyMaterial, params.length);
@@ -63,7 +80,8 @@ let derive_tsuite = {
name: "AES-GCM",
length: 256,
iv: "55667788556677885566778855667788"
- }
+ },
+ usage: [ "encrypt", "decrypt" ]
},
tests: [
@@ -92,6 +110,10 @@ let derive_tsuite = {
{ algorithm: { name: "HKDF" }, optional: true,
expected: "18ea069ee3317d2db02e02f4a228f50dc80d9a2396e6" },
+ { algorithm: { name: "HKDF" },
+ derivedAlgorithm: { name: "HMAC", hash: "SHA-256", length: 256 },
+ usage: [ "sign", "verify" ], optional: true,
+ expected: "0b06bd37de54c08cedde2cbb649d6f26d066acfd51717d83b52091e2ae6829c2" },
{ derive: "bits", algorithm: { name: "HKDF" }, optional: true,
expected: "e089c7491711306c69e077aa19fae6bfd2d4a6d240b0d37317d50472d7291a3e" },
]};