86 lines
2.6 KiB
TypeScript
86 lines
2.6 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { createP256ImageCapabilityVerifier } from "../../src/adapters/browser-transfer/image-cdn/p256-image-capability-verifier.ts";
|
|
import { base64Url } from "./image-cdn-test-fixture.ts";
|
|
|
|
describe("P-256 image capability verifier", () => {
|
|
it("rejects an ECDSA public key on any curve other than P-256", async () => {
|
|
const generated = await globalThis.crypto.subtle.generateKey(
|
|
{ name: "ECDSA", namedCurve: "P-384" },
|
|
false,
|
|
["sign", "verify"],
|
|
);
|
|
if (!("publicKey" in generated)) {
|
|
throw new TypeError("Expected an ECDSA key pair.");
|
|
}
|
|
expect(() =>
|
|
createP256ImageCapabilityVerifier({
|
|
subtle: globalThis.crypto.subtle,
|
|
publicKeys: [
|
|
{
|
|
keyId: "image-signing-wrong-curve",
|
|
key: generated.publicKey,
|
|
},
|
|
],
|
|
}),
|
|
).toThrow(/public key binding/u);
|
|
});
|
|
|
|
it("verifies the exact canonical payload and rejects tampering", async () => {
|
|
const generated = await globalThis.crypto.subtle.generateKey(
|
|
{ name: "ECDSA", namedCurve: "P-256" },
|
|
false,
|
|
["sign", "verify"],
|
|
);
|
|
if (!("privateKey" in generated)) {
|
|
throw new TypeError("Expected an ECDSA key pair.");
|
|
}
|
|
const payload = new TextEncoder().encode(
|
|
'["image-cdn-capability-v1","bound"]',
|
|
);
|
|
const payloadBuffer = new Uint8Array(payload.byteLength);
|
|
payloadBuffer.set(payload);
|
|
const signature = await globalThis.crypto.subtle.sign(
|
|
{ name: "ECDSA", hash: "SHA-256" },
|
|
generated.privateKey,
|
|
payloadBuffer.buffer,
|
|
);
|
|
const verifier = createP256ImageCapabilityVerifier({
|
|
subtle: globalThis.crypto.subtle,
|
|
publicKeys: [
|
|
{
|
|
keyId: "image-signing-2026-01",
|
|
key: generated.publicKey,
|
|
},
|
|
],
|
|
});
|
|
expect(verifier.acceptsKey("image-signing-2026-01")).toBe(
|
|
true,
|
|
);
|
|
expect(verifier.acceptsKey("image-signing-unknown")).toBe(
|
|
false,
|
|
);
|
|
const signatureBase64Url = base64Url(
|
|
new Uint8Array(signature),
|
|
);
|
|
await expect(
|
|
verifier.verify({
|
|
algorithm: "ECDSA_P256_SHA256",
|
|
keyId: "image-signing-2026-01",
|
|
canonicalPayload: payload,
|
|
signatureBase64Url,
|
|
}),
|
|
).resolves.toBe(true);
|
|
const tampered = Uint8Array.from(payload);
|
|
tampered[0] ^= 1;
|
|
await expect(
|
|
verifier.verify({
|
|
algorithm: "ECDSA_P256_SHA256",
|
|
keyId: "image-signing-2026-01",
|
|
canonicalPayload: tampered,
|
|
signatureBase64Url,
|
|
}),
|
|
).resolves.toBe(false);
|
|
});
|
|
});
|