Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions cli/tests/unit/webcrypto_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
24 changes: 18 additions & 6 deletions ext/crypto/00_crypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,7 @@
/**
* @param {AlgorithmIdentifier} algorithm
* @param {CryptoKey} baseKey
* @param {number} length
* @param {number | null} length
* @returns {Promise<ArrayBuffer>}
*/
async deriveBits(algorithm, baseKey, length) {
Expand All @@ -1088,10 +1088,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");
Expand Down Expand Up @@ -4326,7 +4328,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");
}
Expand Down