56 lines
2.7 KiB
JavaScript
56 lines
2.7 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import { analyzeCertificatePaths } from "../src/path-analysis.js";
|
|
|
|
test("path analysis enumerates two valid issuer alternatives with attributed trust", () => {
|
|
const certificates = [cert("leaf", false), cert("intermediate-a"), cert("intermediate-b"), cert("root-a", true), cert("root-b", true)];
|
|
const relationships = [
|
|
link("leaf", "intermediate-a"), link("leaf", "intermediate-b"),
|
|
link("intermediate-a", "root-a"), link("intermediate-b", "root-b"),
|
|
];
|
|
const result = analyzeCertificatePaths(certificates, relationships, {
|
|
trustedCertificateSha256: ["root-a"],
|
|
});
|
|
|
|
assert.equal(result.paths.length, 2);
|
|
assert.equal(result.paths.find((path) => path.certificateSha256.includes("root-a")).status, "trusted");
|
|
assert.equal(result.paths.find((path) => path.certificateSha256.includes("root-b")).status, "untrusted");
|
|
});
|
|
|
|
test("path analysis explains rejected and missing issuer paths", () => {
|
|
const certificates = [cert("leaf", false), cert("wrong-issuer")];
|
|
const relationships = [{ ...link("leaf", "wrong-issuer"), signatureValid: false }];
|
|
const result = analyzeCertificatePaths(certificates, relationships);
|
|
|
|
assert.equal(result.paths[0].status, "incomplete");
|
|
assert.equal(result.paths[0].terminalReason, "no-acceptable-issuer");
|
|
assert.deepEqual(result.edges[0].reasons, ["signature-invalid"]);
|
|
});
|
|
|
|
test("path analysis rejects issuer certificates that cannot sign certificates", () => {
|
|
const issuer = { ...cert("issuer"), keyUsages: ["digitalSignature"] };
|
|
const result = analyzeCertificatePaths([cert("leaf", false), issuer], [link("leaf", "issuer")]);
|
|
assert.equal(result.edges[0].accepted, false);
|
|
assert.match(result.edges[0].reasons.join(" "), /key-usage/);
|
|
});
|
|
|
|
test("path validation explains an exceeded CA path-length constraint", () => {
|
|
const intermediate = cert("intermediate");
|
|
const root = { ...cert("root", true), pathLengthConstraint: 0 };
|
|
const result = analyzeCertificatePaths(
|
|
[cert("leaf", false), intermediate, root],
|
|
[link("leaf", "intermediate"), link("intermediate", "root")],
|
|
{ trustedCertificateSha256: ["root"] },
|
|
);
|
|
assert.equal(result.paths[0].status, "invalid");
|
|
assert.deepEqual(result.paths[0].validationFailures.map((failure) => failure.code), ["path-length-constraint-exceeded"]);
|
|
});
|
|
|
|
function cert(sha256, selfSigned = false) {
|
|
return { sha256, subject: sha256, isCa: sha256 !== "leaf", keyUsages: ["keyCertSign"], selfSigned, unsupportedCriticalExtensions: [] };
|
|
}
|
|
function link(childSha256, issuerSha256) {
|
|
return { childSha256, issuerSha256, issuerNameMatches: true, signatureValid: true, authorityKeyMatches: true };
|
|
}
|