43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
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<ProviderTrust | null> {
|
|
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;
|
|
}
|
|
}
|