1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

fix(ext/crypto): deriveBits for ECDH not taking length into account (#16128)

Fixes #16047
This commit is contained in:
Aurélien Bertron 2022-10-04 08:10:34 +02:00 committed by GitHub
parent 7742ad77fa
commit 8d20784f7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 6 deletions

View file

@ -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));

View file

@ -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");
}