@@ -0,0 +1,127 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { inspectCryptoInput } from "../../src/crypto/inspection";
|
||||
import { inspectPkcs12 } from "../../src/crypto/pkcs12";
|
||||
import {
|
||||
EMPTY_PASSWORD_PFX_BASE64,
|
||||
LEGACY_PFX_BASE64,
|
||||
MODERN_PFX_PASSWORD,
|
||||
pfxFixture,
|
||||
} from "../fixtures/pkcs12";
|
||||
|
||||
describe("bounded PKCS #12 inspection", () => {
|
||||
it("inventories supported content without silently using a password", async () => {
|
||||
const result = await inspectPkcs12(pfxFixture());
|
||||
expect(result.mac).toMatchObject({
|
||||
present: true,
|
||||
status: "password-required",
|
||||
algorithm: "SHA-256",
|
||||
iterations: 2_048,
|
||||
});
|
||||
expect(result.contents).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
type: "encryptedData",
|
||||
state: "password-required",
|
||||
}),
|
||||
expect.objectContaining({ type: "data", state: "parsed" }),
|
||||
]),
|
||||
);
|
||||
expect(result.bags).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
bagType: "shrouded-private-key",
|
||||
friendlyName: "Local test identity",
|
||||
state: "password-required",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("verifies MacData and decrypts PBES2 SafeContents/key bags", async () => {
|
||||
const result = await inspectPkcs12(pfxFixture(), {
|
||||
password: MODERN_PFX_PASSWORD,
|
||||
});
|
||||
expect(result.mac.status).toBe("verified");
|
||||
expect(result.contents.every((content) => content.state === "parsed")).toBe(
|
||||
true,
|
||||
);
|
||||
expect(result.bags).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
bagType: "certificate",
|
||||
friendlyName: "Local test identity",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
bagType: "shrouded-private-key",
|
||||
state: "inspected",
|
||||
key: expect.objectContaining({ algorithm: "RSA" }),
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("distinguishes explicit empty passwords from password omission", async () => {
|
||||
const bytes = pfxFixture(EMPTY_PASSWORD_PFX_BASE64);
|
||||
expect((await inspectPkcs12(bytes)).mac.status).toBe("password-required");
|
||||
const inspected = await inspectPkcs12(bytes, { password: "" });
|
||||
expect(inspected.mac.status).toBe("verified");
|
||||
expect(
|
||||
inspected.bags.some(
|
||||
(bag) =>
|
||||
bag.bagType === "shrouded-private-key" &&
|
||||
bag.state === "inspected" &&
|
||||
bag.key?.algorithm === "RSA",
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("fails closed for wrong passwords, damaged nesting and legacy PBE", async () => {
|
||||
await expect(
|
||||
inspectPkcs12(pfxFixture(), { password: "wrong-password" }),
|
||||
).rejects.toThrow(/password is incorrect|MacData\/authSafe/u);
|
||||
|
||||
const truncated = pfxFixture().slice(0, -1);
|
||||
await expect(inspectPkcs12(truncated)).rejects.toThrow(
|
||||
/malformed DER|trailing bytes/u,
|
||||
);
|
||||
|
||||
await expect(
|
||||
inspectPkcs12(pfxFixture(LEGACY_PFX_BASE64), {
|
||||
password: MODERN_PFX_PASSWORD,
|
||||
}),
|
||||
).rejects.toThrow(/legacy PKCS #12 PBE/u);
|
||||
|
||||
await expect(
|
||||
inspectPkcs12(pfxFixture(), { password: "x".repeat(4_097) }),
|
||||
).rejects.toThrow(/at most 4,096 UTF-16 units/u);
|
||||
});
|
||||
|
||||
it("integrates bag and certificate inventory without reporting secrets", async () => {
|
||||
const result = await inspectCryptoInput(pfxFixture(), new Date(), {
|
||||
password: MODERN_PFX_PASSWORD,
|
||||
});
|
||||
expect(result.items[0]).toMatchObject({
|
||||
type: "PKCS #12/PFX",
|
||||
facts: expect.objectContaining({
|
||||
MacData: expect.stringMatching(/Verified/u),
|
||||
}),
|
||||
});
|
||||
expect(result.items.some((item) => item.certificate)).toBe(true);
|
||||
expect(
|
||||
result.items.some((item) =>
|
||||
item.facts["Private-key algorithm"]?.includes("RSA"),
|
||||
),
|
||||
).toBe(true);
|
||||
const reportSurface = JSON.stringify(
|
||||
result.items.map(({ id, type, title, facts, findings }) => ({
|
||||
id,
|
||||
type,
|
||||
title,
|
||||
facts,
|
||||
findings,
|
||||
})),
|
||||
);
|
||||
expect(reportSurface).not.toContain(MODERN_PFX_PASSWORD);
|
||||
expect(reportSurface).not.toContain("PRIVATE KEY-----");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user