summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tests/unit/webcrypto_test.ts65
-rw-r--r--ext/crypto/00_crypto.js24
2 files changed, 83 insertions, 6 deletions
diff --git a/cli/tests/unit/webcrypto_test.ts b/cli/tests/unit/webcrypto_test.ts
index 6695b157a..c5f5dc6c2 100644
--- a/cli/tests/unit/webcrypto_test.ts
+++ b/cli/tests/unit/webcrypto_test.ts
@@ -541,6 +541,71 @@ Deno.test(async function testHkdfDeriveBitsWithLargeKeySize() {
);
});
+Deno.test(async function testEcdhDeriveBitsWithShorterLength() {
+ const keypair = await crypto.subtle.generateKey(
+ {
+ name: "ECDH",
+ namedCurve: "P-384",
+ },
+ true,
+ ["deriveBits", "deriveKey"],
+ );
+ const result = await crypto.subtle.deriveBits(
+ {
+ name: "ECDH",
+ public: keypair.publicKey,
+ },
+ keypair.privateKey,
+ 256,
+ );
+ assertEquals(result.byteLength * 8, 256);
+});
+
+Deno.test(async function testEcdhDeriveBitsWithLongerLength() {
+ const keypair = await crypto.subtle.generateKey(
+ {
+ name: "ECDH",
+ namedCurve: "P-384",
+ },
+ true,
+ ["deriveBits", "deriveKey"],
+ );
+ await assertRejects(
+ () =>
+ crypto.subtle.deriveBits(
+ {
+ name: "ECDH",
+ public: keypair.publicKey,
+ },
+ keypair.privateKey,
+ 512,
+ ),
+ DOMException,
+ "Invalid length",
+ );
+});
+
+Deno.test(async function testEcdhDeriveBitsWithNullLength() {
+ const keypair = await crypto.subtle.generateKey(
+ {
+ name: "ECDH",
+ namedCurve: "P-384",
+ },
+ true,
+ ["deriveBits", "deriveKey"],
+ );
+ const result = await crypto.subtle.deriveBits(
+ {
+ name: "ECDH",
+ public: keypair.publicKey,
+ },
+ keypair.privateKey,
+ // @ts-ignore: necessary until .d.ts file allows passing null (see https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1416)
+ null,
+ );
+ assertEquals(result.byteLength * 8, 384);
+});
+
Deno.test(async function testDeriveKey() {
// Test deriveKey
const rawKey = await crypto.getRandomValues(new Uint8Array(16));
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js
index 5e918cc7d..5826132d2 100644
--- a/ext/crypto/00_crypto.js
+++ b/ext/crypto/00_crypto.js
@@ -1078,7 +1078,7 @@
/**
* @param {AlgorithmIdentifier} algorithm
* @param {CryptoKey} baseKey
- * @param {number} length
+ * @param {number | null} length
* @returns {Promise<ArrayBuffer>}
*/
async deriveBits(algorithm, baseKey, length) {
@@ -1093,10 +1093,12 @@
prefix,
context: "Argument 2",
});
- length = webidl.converters["unsigned long"](length, {
- prefix,
- context: "Argument 3",
- });
+ if (length !== null) {
+ length = webidl.converters["unsigned long"](length, {
+ prefix,
+ context: "Argument 3",
+ });
+ }
// 2.
const normalizedAlgorithm = normalizeAlgorithm(algorithm, "deriveBits");
@@ -4391,7 +4393,17 @@
length,
});
- return buf.buffer;
+ // 8.
+ if (length === null) {
+ return buf.buffer;
+ }
+ if (
+ length === 0 || buf.buffer.byteLength * 8 < length ||
+ length % 8 !== 0
+ ) {
+ throw new DOMException("Invalid length", "OperationError");
+ }
+ return buf.buffer.slice(0, length / 8);
} else {
throw new DOMException("Not implemented", "NotSupportedError");
}