This commit is contained in:
Reinier Criel 2025-11-10 11:28:05 -08:00
parent 1df4e03b47
commit 214161722e
2 changed files with 11 additions and 5 deletions

View file

@ -43,3 +43,5 @@ export const LOGGING_VERBOSE = "verbose";
// OS trust store paths // OS trust store paths
export const DARWIN_CA_PATH = "/Library/Keychains/System.keychain"; export const DARWIN_CA_PATH = "/Library/Keychains/System.keychain";
export const LINUX_CA_PATH = "/usr/local/share/ca-certificates/safe-chain-ca.crt"; export const LINUX_CA_PATH = "/usr/local/share/ca-certificates/safe-chain-ca.crt";
export const SAFE_CHAIN_CA_COMMON_NAME = "safe-chain proxy";

View file

@ -3,7 +3,7 @@ import path from "path";
import fs from "fs"; import fs from "fs";
import os from "os"; import os from "os";
import { safeSpawn } from "../utils/safeSpawn.js"; import { safeSpawn } from "../utils/safeSpawn.js";
import { DARWIN_CA_PATH, LINUX_CA_PATH } from "../config/settings.js"; import { DARWIN_CA_PATH, LINUX_CA_PATH, SAFE_CHAIN_CA_COMMON_NAME } from "../config/settings.js";
import { ui } from "../environment/userInteraction.js"; import { ui } from "../environment/userInteraction.js";
const certFolder = path.join(os.homedir(), ".safe-chain", "certs"); const certFolder = path.join(os.homedir(), ".safe-chain", "certs");
@ -11,6 +11,10 @@ const ca = loadCa();
const certCache = new Map(); const certCache = new Map();
const OS_DARWIN = "darwin";
const OS_LINUX = "linux";
const OS_WINDOWS = "win32";
export function getCaCertPath() { export function getCaCertPath() {
return path.join(certFolder, "ca-cert.pem"); return path.join(certFolder, "ca-cert.pem");
} }
@ -97,7 +101,7 @@ function generateCa() {
cert.validity.notAfter = new Date(); cert.validity.notAfter = new Date();
cert.validity.notAfter.setDate(cert.validity.notBefore.getDate() + 1); cert.validity.notAfter.setDate(cert.validity.notBefore.getDate() + 1);
const attrs = [{ name: "commonName", value: "safe-chain proxy" }]; const attrs = [{ name: "commonName", value: SAFE_CHAIN_CA_COMMON_NAME }];
cert.setSubject(attrs); cert.setSubject(attrs);
cert.setIssuer(attrs); cert.setIssuer(attrs);
cert.setExtensions([ cert.setExtensions([
@ -129,14 +133,14 @@ export async function isSafeChainCAInstalled() {
try { try {
if (platform === "darwin") { if (platform === "darwin") {
// macOS: check System Keychain for cert // macOS: check System Keychain for cert
const res = await safeSpawn("security", ["find-certificate", "-c", "safe-chain proxy", DARWIN_CA_PATH], { stdio: "pipe" }); const res = await safeSpawn("security", ["find-certificate", "-c", SAFE_CHAIN_CA_COMMON_NAME, DARWIN_CA_PATH], { stdio: "pipe" });
return res.stdout.includes("safe-chain proxy"); return res.stdout.includes(SAFE_CHAIN_CA_COMMON_NAME);
} else if (platform === "linux") { } else if (platform === "linux") {
// Linux: check for CA file // Linux: check for CA file
return fs.existsSync(LINUX_CA_PATH); return fs.existsSync(LINUX_CA_PATH);
} else if (platform === "win32") { } else if (platform === "win32") {
// Windows: check Root store for cert // Windows: check Root store for cert
return await safeSpawn("certutil", ["-store", "Root", "safe-chain proxy"], { stdio: "pipe" }).then(res => res.stdout.includes("safe-chain proxy")); return await safeSpawn("certutil", ["-store", "Root", SAFE_CHAIN_CA_COMMON_NAME], { stdio: "pipe" }).then(res => res.stdout.includes(SAFE_CHAIN_CA_COMMON_NAME));
} }
} catch (/** @type any */ error) { } catch (/** @type any */ error) {
// If check fails, assume not installed // If check fails, assume not installed