import { createPublicKey } from "node:crypto"; import path from "node:path"; import { readBoundedRegularFile } from "./ci-artifact-validator.ts"; import { providerPublicKeyFingerprint, type ProviderTrust, } from "./provider-evidence.ts"; export async function readProviderTrust( configuredRoot: string, publicKeyPath: string | undefined, keyId: string | undefined, ): Promise { if (!publicKeyPath || !keyId?.trim()) return null; try { const root = path.resolve(configuredRoot); const absolute = path.resolve(root, publicKeyPath); const relative = path.relative(root, absolute); const outside = relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative); const bytes = await readBoundedRegularFile({ root: outside ? path.dirname(absolute) : root, relativePath: outside ? path.basename(absolute) : relative.replaceAll(path.sep, "/"), maxBytes: 1_048_576, }); const publicKey = createPublicKey( new TextDecoder("utf-8", { fatal: true }).decode(bytes), ); return Object.freeze({ keyId, publicKey, publicKeyFingerprint: providerPublicKeyFingerprint(publicKey), }); } catch { return null; } }