]> git.kaiwu.me - njs.git/commitdiff
WebCrypto: added support for HMAC as derivedKeyAlgorithm.
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 8 May 2025 02:11:24 +0000 (19:11 -0700)
committerDmitry Volyntsev <xeioexception@gmail.com>
Thu, 8 May 2025 16:30:06 +0000 (09:30 -0700)
In crypto.subtle.deriveKey().

This closes #905 issue on Github.

external/njs_webcrypto_module.c
external/qjs_webcrypto_module.c
test/webcrypto/derive.t.mjs

index d291889123f3dd5dec602b919e034e6601df90a7..6f4b49e1004107f4e971b607a574c45d9934ef0a 100644 (file)
@@ -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));
index a28a8581bc60177584247a6a190cf9052c2a194d..29aea329115b25ee31d2dd442a3c2258055bd69e 100644 (file)
@@ -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));
index 5ac1345917d53469a8c77c413c612dd376ced3ff..4d865da397fe4967c98d50e128cfc71880326772 100644 (file)
@@ -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" },
 ]};