35 lines
1.7 KiB
JavaScript
35 lines
1.7 KiB
JavaScript
import { createHash, createPrivateKey, createPublicKey, generateKeyPairSync } from "node:crypto";
|
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
const defaultPrivatePath = path.join(
|
|
process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming"),
|
|
"forgeflow",
|
|
"release-signing-private.pem",
|
|
);
|
|
const privatePath = path.resolve(process.env.FORGEFLOW_UPDATE_SIGNING_PRIVATE_KEY || defaultPrivatePath);
|
|
const publicPath = path.join(root, "build", "update-signing-public.pem");
|
|
|
|
let privateKey;
|
|
try {
|
|
privateKey = createPrivateKey(await readFile(privatePath));
|
|
if (privateKey.asymmetricKeyType !== "ed25519") throw new Error("The existing key is not Ed25519.");
|
|
} catch (error) {
|
|
if (error.code !== "ENOENT") throw error;
|
|
privateKey = generateKeyPairSync("ed25519").privateKey;
|
|
await mkdir(path.dirname(privatePath), { recursive: true, mode: 0o700 });
|
|
await writeFile(privatePath, privateKey.export({ type: "pkcs8", format: "pem" }), { mode: 0o600, flag: "wx" });
|
|
}
|
|
|
|
const publicKey = createPublicKey(privateKey);
|
|
const publicPem = publicKey.export({ type: "spki", format: "pem" });
|
|
await mkdir(path.dirname(publicPath), { recursive: true });
|
|
await writeFile(publicPath, publicPem, { mode: 0o644 });
|
|
const fingerprint = createHash("sha256").update(publicKey.export({ type: "spki", format: "der" })).digest("hex");
|
|
console.log(`ForgeFlow Ed25519 update key ready. Public key fingerprint: SHA256:${fingerprint}`);
|
|
console.log(`Private key: ${privatePath}`);
|
|
console.log(`Public key: ${publicPath}`);
|