From 2702ed7468e150d1e0bc20b9cca4099722b5b666 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Thu, 8 Sep 2022 08:07:16 -0400 Subject: [PATCH] Fix win-ca failing on electron renderer on windows Signed-off-by: Sebastian Malton --- .../request-system-cas.injectable.win32.ts | 44 ++++++++++++------- src/common/fs/exec-file.injectable.ts | 24 ++++++++-- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/common/certificate-authorities/request-system-cas.injectable.win32.ts b/src/common/certificate-authorities/request-system-cas.injectable.win32.ts index 7d0f448283..17b2999357 100644 --- a/src/common/certificate-authorities/request-system-cas.injectable.win32.ts +++ b/src/common/certificate-authorities/request-system-cas.injectable.win32.ts @@ -3,26 +3,40 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import wincaAPI from "win-ca/api"; +import execFileInjectable from "../fs/exec-file.injectable"; import { requestSystemCAsInjectionToken } from "./request-system-cas-token"; +const pemEncoding = (hexEncodedCert: String) => { + const certData = Buffer.from(hexEncodedCert, "hex").toString('base64'); + const lines = ['-----BEGIN CERTIFICATE-----']; + + for (let i = 0; i < certData.length; i += 64) { + lines.push(certData.substring(i, i + 64)); + } + + lines.push('-----END CERTIFICATE-----', ''); + + return lines.join("\r\n"); +} + const requestSystemCAsInjectable = getInjectable({ id: "request-system-cas", - instantiate: () => { - return () => new Promise((resolve) => { - const CAs: string[] = []; + instantiate: (di) => { + const wincaRootsExePath: string = __non_webpack_require__.resolve("win-ca/lib/roots.exe"); + const execFile = di.inject(execFileInjectable); - wincaAPI({ - format: wincaAPI.der2.pem, - inject: false, - ondata: (ca: string) => { - CAs.push(ca); - }, - onend: () => { - resolve(CAs); - }, - }); - }); + return async () => { + /** + * This needs to be done manually because for some reason calling the api from "win-ca" + * directly fails to load "child_process" correctly on renderer + */ + const output = await execFile(wincaRootsExePath); + + return output + .split("\r\n") + .filter(Boolean) + .map(pemEncoding); + }; }, causesSideEffects: true, injectionToken: requestSystemCAsInjectionToken, diff --git a/src/common/fs/exec-file.injectable.ts b/src/common/fs/exec-file.injectable.ts index 15d0ad48dc..244f05d0a1 100644 --- a/src/common/fs/exec-file.injectable.ts +++ b/src/common/fs/exec-file.injectable.ts @@ -7,7 +7,11 @@ import type { ExecFileOptions } from "child_process"; import { execFile } from "child_process"; import { promisify } from "util"; -export type ExecFile = (filePath: string, args: string[], options: ExecFileOptions) => Promise; +export interface ExecFile { + (filePath: string): Promise; + (filePath: string, argsOrOptions: string[] | ExecFileOptions): Promise; + (filePath: string, args: string[], options: ExecFileOptions): Promise; +} const execFileInjectable = getInjectable({ id: "exec-file", @@ -15,8 +19,22 @@ const execFileInjectable = getInjectable({ instantiate: (): ExecFile => { const asyncExecFile = promisify(execFile); - return async (filePath, args, options) => { - const result = await asyncExecFile(filePath, args, options); + return async (filePath: string, argsOrOptions?: string[] | ExecFileOptions, maybeOptions?: ExecFileOptions) => { + let args: string[]; + let options: ExecFileOptions; + + if (Array.isArray(argsOrOptions)) { + args = argsOrOptions; + options = maybeOptions ?? {}; + } else { + args = []; + options = maybeOptions ?? argsOrOptions ?? {}; + } + + const result = await asyncExecFile(filePath, args, { + encoding: "utf-8", + ...options, + }); return result.stdout; };