mirror of
https://github.com/denoland/deno.git
synced 2024-12-25 08:39:09 -05:00
fix(ext/node): timingSafeEqual account for AB byteOffset (#26292)
Fixes https://github.com/denoland/deno/issues/26276
This commit is contained in:
parent
661882f10d
commit
21fa953f32
2 changed files with 21 additions and 10 deletions
|
@ -5,10 +5,11 @@
|
|||
|
||||
import { Buffer } from "node:buffer";
|
||||
|
||||
function assert(cond) {
|
||||
if (!cond) {
|
||||
throw new Error("assertion failed");
|
||||
function toDataView(ab: ArrayBufferLike | ArrayBufferView): DataView {
|
||||
if (ArrayBuffer.isView(ab)) {
|
||||
return new DataView(ab.buffer, ab.byteOffset, ab.byteLength);
|
||||
}
|
||||
return new DataView(ab);
|
||||
}
|
||||
|
||||
/** Compare to array buffers or data views in a way that timing based attacks
|
||||
|
@ -21,13 +22,11 @@ function stdTimingSafeEqual(
|
|||
return false;
|
||||
}
|
||||
if (!(a instanceof DataView)) {
|
||||
a = new DataView(ArrayBuffer.isView(a) ? a.buffer : a);
|
||||
a = toDataView(a);
|
||||
}
|
||||
if (!(b instanceof DataView)) {
|
||||
b = new DataView(ArrayBuffer.isView(b) ? b.buffer : b);
|
||||
b = toDataView(b);
|
||||
}
|
||||
assert(a instanceof DataView);
|
||||
assert(b instanceof DataView);
|
||||
const length = a.byteLength;
|
||||
let out = 0;
|
||||
let i = -1;
|
||||
|
@ -41,7 +40,11 @@ export const timingSafeEqual = (
|
|||
a: Buffer | DataView | ArrayBuffer,
|
||||
b: Buffer | DataView | ArrayBuffer,
|
||||
): boolean => {
|
||||
if (a instanceof Buffer) a = new DataView(a.buffer);
|
||||
if (a instanceof Buffer) b = new DataView(a.buffer);
|
||||
if (a instanceof Buffer) {
|
||||
a = new DataView(a.buffer, a.byteOffset, a.byteLength);
|
||||
}
|
||||
if (b instanceof Buffer) {
|
||||
b = new DataView(b.buffer, b.byteOffset, b.byteLength);
|
||||
}
|
||||
return stdTimingSafeEqual(a, b);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
import { randomFillSync, randomUUID } from "node:crypto";
|
||||
import { randomFillSync, randomUUID, timingSafeEqual } from "node:crypto";
|
||||
import { Buffer } from "node:buffer";
|
||||
import { assert, assertEquals } from "../../unit/test_util.ts";
|
||||
import { assertNotEquals } from "@std/assert";
|
||||
|
||||
|
@ -28,3 +29,10 @@ Deno.test("[node/crypto.randomFillSync] array buffer view", () => {
|
|||
assertEquals(buf.subarray(0, 8), new Uint8Array(8));
|
||||
assertEquals(buf.subarray(24, 32), new Uint8Array(8));
|
||||
});
|
||||
|
||||
Deno.test("[node/crypto.timingSafeEqual] compares equal Buffer with different byteOffset", () => {
|
||||
const a = Buffer.from([212, 213]);
|
||||
const b = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 212, 213]).subarray(8);
|
||||
|
||||
assert(timingSafeEqual(a, b));
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue