// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. Object.defineProperty(exports, "__esModule", { value: true }); exports.verifyCertificates = exports.isCaCertificateInstalled = exports.outputMarker = void 0; const child_process_1 = require("child_process"); const crypto = require("crypto"); const fs = require("fs"); const path = require("path"); const defaults = require("./defaults"); const defaults_1 = require("./defaults"); const office_addin_usage_data_1 = require("office-addin-usage-data"); // On win32 this is a unique hash used with PowerShell command to reliably delineate command output exports.outputMarker = process.platform === "win32" ? `[${crypto.createHash("md5").update(`${defaults.certificateName}${defaults.caCertificatePath}`).digest("hex")}]` : ""; /* global process, Buffer, __dirname */ function getVerifyCommand(returnInvalidCertificate) { switch (process.platform) { case "win32": { const script = path.resolve(__dirname, "..\\scripts\\verify.ps1"); const defaultCommand = `powershell -ExecutionPolicy Bypass -File "${script}" -CaCertificateName "${defaults.certificateName}" -CaCertificatePath "${defaults.caCertificatePath}" -LocalhostCertificatePath "${defaults.localhostCertificatePath}" -OutputMarker "${exports.outputMarker}"`; if (returnInvalidCertificate) { return defaultCommand + ` -ReturnInvalidCertificate`; } return defaultCommand; } case "darwin": { // macOS const script = path.resolve(__dirname, "../scripts/verify.sh"); return `sh '${script}' '${defaults.certificateName}'`; } case "linux": const script = path.resolve(__dirname, "../scripts/verify_linux.sh"); return `sh '${script}' '${defaults.caCertificateFileName}'`; default: throw new office_addin_usage_data_1.ExpectedError(`Platform not supported: ${process.platform}`); } } function isCaCertificateInstalled(returnInvalidCertificate = false) { const command = getVerifyCommand(returnInvalidCertificate); try { const output = (0, child_process_1.execSync)(command, { stdio: "pipe" }).toString(); if (process.platform === "win32") { // Remove any PowerShell output that preceeds invoking the actual certificate check command return output.slice(output.lastIndexOf(exports.outputMarker) + exports.outputMarker.length).trim().length !== 0; } // script files return empty string if the certificate not found or expired if (output.length !== 0) { return true; } } catch (error) { // Some commands throw errors if the certifcate is not found or expired } return false; } exports.isCaCertificateInstalled = isCaCertificateInstalled; function validateCertificateAndKey(certificatePath, keyPath) { let certificate = ""; let key = ""; try { certificate = fs.readFileSync(certificatePath).toString(); } catch (err) { throw new Error(`Unable to read the certificate.\n${err}`); } try { key = fs.readFileSync(keyPath).toString(); } catch (err) { throw new Error(`Unable to read the certificate key.\n${err}`); } let encrypted; try { encrypted = crypto.publicEncrypt(certificate, Buffer.from("test")); } catch (err) { throw new Error(`The certificate is not valid.\n${err}`); } try { crypto.privateDecrypt(key, encrypted); } catch (err) { throw new Error(`The certificate key is not valid.\n${err}`); } } function verifyCertificates(certificatePath = defaults.localhostCertificatePath, keyPath = defaults.localhostKeyPath) { try { let isCertificateValid = true; try { validateCertificateAndKey(certificatePath, keyPath); } catch (err) { isCertificateValid = false; } let output = isCertificateValid && isCaCertificateInstalled(); defaults_1.usageDataObject.reportSuccess("verifyCertificates()"); return output; } catch (err) { defaults_1.usageDataObject.reportException("verifyCertificates()", err); throw err; } } exports.verifyCertificates = verifyCertificates; //# sourceMappingURL=verify.js.map