/*
RFC-0715/RFC-0871/RFC-0921: nachweis.verify-signature command handler — verifies the Ed25519 operator signature and RFC 3161 timestamp for a Nachweis record, reporting timestamp assurance metadata via shared signing core.
- Does not cryptographically verify the RFC 3161 timestamp token against the TSA certificate chain — that requires TSA trust anchor configuration and is deferred to a future RFC.
- RFC-0871: report timestampAssurance and qualificationEvidenceRef from Bordbuch metadata, default rfc3161 for legacy entries.
- RFC-0921: delegate verification to shared signing core (verify, canonicalBytes, fromHex). Remove @noble/ed25519 import. Remove canonicalRecordPayload import.
- RFC-1097: step 6 — compass.migrate codemod run
Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.
- RFC-1097: sweep — werkstatt-engine clean
Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.
- RFC-1254: drop unused io-migration leftovers
RFC-0715
*/
import path from "node:path";
import { verify as signingVerify, fromHex } from "@warpgogol/werkstatt-engine/signing";
import type {
KernelCommandInput,
KernelCommandResult,
KernelRuntimeContext,
} from "@warpgogol/werkstatt-engine/kernel";
import { parseMarkdownFrontmatter } from "@warpgogol/werkstatt-shared/content";
import { readBordbuch } from "../bordbuch/bordbuch-io.ts";
import {
isNachweisEntitled,
makeSkipResult,
resolveNachweisCachePath,
resolveDefaultLang,
resolvePbpEntityDir,
flagString,
type NachweisVerifySignatureResult,
type TimestampAssurance,
} from "./nachweis-n3-types.ts";
import type { NachweisRecordPayload } from "./nachweis-sign.ts";
export async function runNachweisVerifySignature(
input: KernelCommandInput,
context: KernelRuntimeContext,
): Promise> {
const { workspaceRoot } = context;
const systemId = flagString(input, "system") ?? context.site?.name;
const slug = flagString(input, "slug");
if (!systemId) throw new Error("[nachweis.verify-signature] --system is required");
if (!slug) throw new Error("[nachweis.verify-signature] --slug is required");
const entitled = await isNachweisEntitled(workspaceRoot, systemId);
if (!entitled) {
return makeSkipResult(
"nachweis.verify-signature",
systemId,
) as unknown as KernelCommandResult;
}
const cachePath = await resolveNachweisCachePath(workspaceRoot, systemId);
const lang = await resolveDefaultLang(cachePath);
const evidenceDir = resolvePbpEntityDir(cachePath, lang, "evidence-source");
const evidenceFile = path.join(evidenceDir, `${slug}.md`);
if (!(await context.io.exists(evidenceFile))) {
throw new Error(
`[nachweis.verify-signature] NOT_FOUND: evidence-source '${slug}' not found at ${evidenceFile}`,
);
}
const rawEvidence = await context.io.readFile(evidenceFile);
const { data: evidenceData } = parseMarkdownFrontmatter(rawEvidence);
const payload: NachweisRecordPayload = {
recordId: (evidenceData.recordId as string | undefined) ?? `nr_${slug}`,
slug,
kind: (evidenceData.kind as string | undefined) ?? "evidence",
name: (evidenceData.name as string | undefined) ?? slug,
items: (evidenceData.items as Record | undefined) ?? {},
};
const bordbuchEntries = await readBordbuch(workspaceRoot, systemId);
const signedEntry = bordbuchEntries.find(
(e) => e.kind === "nachweis-signed" && e.metadata?.slug === slug,
);
const timestampedEntry = bordbuchEntries.find(
(e) => e.kind === "nachweis-timestamped" && e.metadata?.slug === slug,
);
if (!signedEntry) {
return {
data: {
slug,
systemId,
signatureValid: false,
timestampVerified: false,
timestampAssurance: "rfc3161",
publicKeyHex: null,
details: "No nachweis-signed Bordbuch entry found for this slug.",
},
exitCode: 1,
summary: `[nachweis.verify-signature] ${systemId}: FAIL — no signature found for '${slug}'`,
nextSteps: [
{
action: `Sign the nachweis: pnpm exec werkstatt run nachweis.sign --site ${systemId} --slug ${slug}`,
kind: "required",
},
],
};
}
const signatureHex = signedEntry.metadata?.signatureHex as string | undefined;
const publicKeyHex = signedEntry.metadata?.publicKeyHex as string | undefined;
if (!signatureHex || !publicKeyHex) {
return {
data: {
slug,
systemId,
signatureValid: false,
timestampVerified: false,
timestampAssurance: "rfc3161",
publicKeyHex: publicKeyHex ?? null,
details: "Signature or public key metadata missing from Bordbuch entry.",
},
exitCode: 1,
summary: `[nachweis.verify-signature] ${systemId}: FAIL — incomplete signature metadata for '${slug}'`,
nextSteps: [
{
action: `Re-sign the nachweis: pnpm exec werkstatt run nachweis.sign --site ${systemId} --slug ${slug}`,
kind: "required",
},
],
};
}
const signatureBytes = fromHex(signatureHex);
const publicKeyBytes = fromHex(publicKeyHex);
let signatureValid = false;
try {
signatureValid = await signingVerify(
publicKeyBytes,
payload as unknown as Record,
signatureBytes,
);
} catch {
signatureValid = false;
}
const timestampVerified = timestampedEntry != null;
const timestampAssurance: TimestampAssurance =
(timestampedEntry?.metadata?.timestampAssurance as TimestampAssurance | undefined) ?? "rfc3161";
const qualificationEvidenceRef = timestampedEntry?.metadata?.qualificationEvidenceRef as
string | undefined;
const assuranceLabel =
timestampAssurance === "eidas-qualified" ? "eIDAS qualified timestamp" : "RFC 3161 timestamp";
const details = signatureValid
? timestampVerified
? `Signature valid, ${assuranceLabel} token present.`
: "Signature valid, but no RFC 3161 timestamp token found."
: "Signature verification failed — canonical payload does not match.";
return {
data: {
slug,
systemId,
signatureValid,
timestampVerified,
timestampAssurance,
...(qualificationEvidenceRef ? { qualificationEvidenceRef } : {}),
publicKeyHex,
details,
},
exitCode: signatureValid ? 0 : 1,
summary: `[nachweis.verify-signature] ${systemId}: ${signatureValid ? "PASS" : "FAIL"} — '${slug}' (signature: ${signatureValid}, timestamp: ${timestampVerified}, assurance: ${timestampAssurance})`,
nextSteps: signatureValid
? undefined
: [
{
action: `Re-sign the nachweis: pnpm exec werkstatt run nachweis.sign --site ${systemId} --slug ${slug}`,
kind: "required",
},
],
};
}