@rushstack/debug-certificate-manager 1.3.65 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.json CHANGED
@@ -1,6 +1,36 @@
1
1
  {
2
2
  "name": "@rushstack/debug-certificate-manager",
3
3
  "entries": [
4
+ {
5
+ "version": "1.4.0",
6
+ "tag": "@rushstack/debug-certificate-manager_v1.4.0",
7
+ "date": "Sat, 21 Sep 2024 00:10:27 GMT",
8
+ "comments": {
9
+ "minor": [
10
+ {
11
+ "comment": "Add a `skipCertificateTrust` option to `CertificateManager.ensureCertificateAsync` that skips automatically trusting the generated certificate and untrusting an existing certificate with issues."
12
+ }
13
+ ]
14
+ }
15
+ },
16
+ {
17
+ "version": "1.3.66",
18
+ "tag": "@rushstack/debug-certificate-manager_v1.3.66",
19
+ "date": "Fri, 13 Sep 2024 00:11:42 GMT",
20
+ "comments": {
21
+ "dependency": [
22
+ {
23
+ "comment": "Updating dependency \"@rushstack/node-core-library\" to `5.9.0`"
24
+ },
25
+ {
26
+ "comment": "Updating dependency \"@rushstack/terminal\" to `0.14.2`"
27
+ },
28
+ {
29
+ "comment": "Updating dependency \"@rushstack/heft\" to `0.67.2`"
30
+ }
31
+ ]
32
+ }
33
+ },
4
34
  {
5
35
  "version": "1.3.65",
6
36
  "tag": "@rushstack/debug-certificate-manager_v1.3.65",
package/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # Change Log - @rushstack/debug-certificate-manager
2
2
 
3
- This log was last generated on Tue, 10 Sep 2024 20:08:11 GMT and should not be manually modified.
3
+ This log was last generated on Sat, 21 Sep 2024 00:10:27 GMT and should not be manually modified.
4
+
5
+ ## 1.4.0
6
+ Sat, 21 Sep 2024 00:10:27 GMT
7
+
8
+ ### Minor changes
9
+
10
+ - Add a `skipCertificateTrust` option to `CertificateManager.ensureCertificateAsync` that skips automatically trusting the generated certificate and untrusting an existing certificate with issues.
11
+
12
+ ## 1.3.66
13
+ Fri, 13 Sep 2024 00:11:42 GMT
14
+
15
+ _Version update only_
4
16
 
5
17
  ## 1.3.65
6
18
  Tue, 10 Sep 2024 20:08:11 GMT
@@ -30,7 +30,7 @@ export declare class CertificateManager {
30
30
  *
31
31
  * @public
32
32
  */
33
- ensureCertificateAsync(canGenerateNewCertificate: boolean, terminal: ITerminal, generationOptions?: ICertificateGenerationOptions): Promise<ICertificate>;
33
+ ensureCertificateAsync(canGenerateNewCertificate: boolean, terminal: ITerminal, options?: ICertificateGenerationOptions): Promise<ICertificate>;
34
34
  /**
35
35
  * Attempt to locate a previously generated debug certificate and untrust it.
36
36
  *
@@ -130,6 +130,10 @@ export declare interface ICertificateGenerationOptions {
130
130
  * How many days the certificate should be valid for.
131
131
  */
132
132
  validityInDays?: number;
133
+ /**
134
+ * Skip trusting a certificate. Defaults to false.
135
+ */
136
+ skipCertificateTrust?: boolean;
133
137
  }
134
138
 
135
139
  export { }
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.47.7"
8
+ "packageVersion": "7.47.9"
9
9
  }
10
10
  ]
11
11
  }
@@ -49,6 +49,10 @@ export interface ICertificateGenerationOptions {
49
49
  * How many days the certificate should be valid for.
50
50
  */
51
51
  validityInDays?: number;
52
+ /**
53
+ * Skip trusting a certificate. Defaults to false.
54
+ */
55
+ skipCertificateTrust?: boolean;
52
56
  }
53
57
  /**
54
58
  * A utility class to handle generating, trusting, and untrustring a debug certificate.
@@ -64,7 +68,7 @@ export declare class CertificateManager {
64
68
  *
65
69
  * @public
66
70
  */
67
- ensureCertificateAsync(canGenerateNewCertificate: boolean, terminal: ITerminal, generationOptions?: ICertificateGenerationOptions): Promise<ICertificate>;
71
+ ensureCertificateAsync(canGenerateNewCertificate: boolean, terminal: ITerminal, options?: ICertificateGenerationOptions): Promise<ICertificate>;
68
72
  /**
69
73
  * Attempt to locate a previously generated debug certificate and untrust it.
70
74
  *
@@ -1 +1 @@
1
- {"version":3,"file":"CertificateManager.d.ts","sourceRoot":"","sources":["../src/CertificateManager.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAarD;;;GAGG;AACH,eAAO,MAAM,iCAAiC,EAAE,aAAa,CAAC,MAAM,CAAiB,CAAC;AAEtF;;;GAGG;AACH,eAAO,MAAM,wCAAwC,EAAE,aAAa,CAAC,MAAM,CAAiB,CAAC;AAK7F;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IAErC;;OAEG;IACH,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnC;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAE3B;;OAEG;IACH,eAAe,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAChD;AAmCD;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;OAEG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC;;OAEG;IACH,kBAAkB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3C;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAID;;;;GAIG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,iBAAiB,CAAmB;;IAM5C;;;;;OAKG;IACU,sBAAsB,CACjC,yBAAyB,EAAE,OAAO,EAClC,QAAQ,EAAE,SAAS,EACnB,iBAAiB,CAAC,EAAE,6BAA6B,GAChD,OAAO,CAAC,YAAY,CAAC;IAuHxB;;;;OAIG;IACU,uBAAuB,CAAC,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;YA6E7D,yBAAyB;YA2EzB,kCAAkC;YAsGlC,yBAAyB;YA0FzB,kCAAkC;YAwElC,wBAAwB;YAsCxB,+BAA+B;IAmD7C,OAAO,CAAC,kCAAkC;CAe3C"}
1
+ {"version":3,"file":"CertificateManager.d.ts","sourceRoot":"","sources":["../src/CertificateManager.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAarD;;;GAGG;AACH,eAAO,MAAM,iCAAiC,EAAE,aAAa,CAAC,MAAM,CAAiB,CAAC;AAEtF;;;GAGG;AACH,eAAO,MAAM,wCAAwC,EAAE,aAAa,CAAC,MAAM,CAAiB,CAAC;AAK7F;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IAErC;;OAEG;IACH,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnC;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAE3B;;OAEG;IACH,eAAe,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAChD;AAmCD;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;OAEG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC;;OAEG;IACH,kBAAkB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3C;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAID;;;;GAIG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,iBAAiB,CAAmB;;IAM5C;;;;;OAKG;IACU,sBAAsB,CACjC,yBAAyB,EAAE,OAAO,EAClC,QAAQ,EAAE,SAAS,EACnB,OAAO,CAAC,EAAE,6BAA6B,GACtC,OAAO,CAAC,YAAY,CAAC;IAwHxB;;;;OAIG;IACU,uBAAuB,CAAC,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;YA6E7D,yBAAyB;YA2EzB,kCAAkC;YAsGlC,yBAAyB;YA0FzB,kCAAkC;YAwElC,wBAAwB;YAsCxB,+BAA+B;IAkD7C,OAAO,CAAC,kCAAkC;CAe3C"}
@@ -65,8 +65,8 @@ class CertificateManager {
65
65
  *
66
66
  * @public
67
67
  */
68
- async ensureCertificateAsync(canGenerateNewCertificate, terminal, generationOptions) {
69
- const optionsWithDefaults = applyDefaultOptions(generationOptions);
68
+ async ensureCertificateAsync(canGenerateNewCertificate, terminal, options) {
69
+ const optionsWithDefaults = applyDefaultOptions(options);
70
70
  const { certificateData: existingCert, keyData: existingKey } = this._certificateStore;
71
71
  if (process.env[DISABLE_CERT_GENERATION_VARIABLE_NAME] === '1') {
72
72
  // Allow the environment (e.g. GitHub codespaces) to forcibly disable dev cert generation
@@ -123,7 +123,9 @@ class CertificateManager {
123
123
  if (canGenerateNewCertificate) {
124
124
  messages.push('Attempting to untrust the certificate and generate a new one.');
125
125
  terminal.writeWarningLine(messages.join(' '));
126
- await this.untrustCertificateAsync(terminal);
126
+ if (!(options === null || options === void 0 ? void 0 : options.skipCertificateTrust)) {
127
+ await this.untrustCertificateAsync(terminal);
128
+ }
127
129
  return await this._ensureCertificateInternalAsync(optionsWithDefaults, terminal);
128
130
  }
129
131
  else {
@@ -529,7 +531,9 @@ class CertificateManager {
529
531
  ensureFolderExists: true
530
532
  });
531
533
  }
532
- const trustCertificateResult = await this._tryTrustCertificateAsync(tempCertificatePath, terminal);
534
+ const trustCertificateResult = options.skipCertificateTrust
535
+ ? true
536
+ : await this._tryTrustCertificateAsync(tempCertificatePath, terminal);
533
537
  let subjectAltNames;
534
538
  if (trustCertificateResult) {
535
539
  certificateStore.caCertificateData = generatedCertificate.pemCaCertificate;
@@ -575,12 +579,14 @@ function applyDefaultOptions(options) {
575
579
  var _a;
576
580
  const subjectNames = options === null || options === void 0 ? void 0 : options.subjectAltNames;
577
581
  const subjectIpAddresses = options === null || options === void 0 ? void 0 : options.subjectIPAddresses;
582
+ const skipCertificateTrust = (options === null || options === void 0 ? void 0 : options.skipCertificateTrust) || false;
578
583
  return {
579
584
  subjectAltNames: (subjectNames === null || subjectNames === void 0 ? void 0 : subjectNames.length) ? subjectNames : exports.DEFAULT_CERTIFICATE_SUBJECT_NAMES,
580
585
  subjectIPAddresses: (subjectIpAddresses === null || subjectIpAddresses === void 0 ? void 0 : subjectIpAddresses.length)
581
586
  ? subjectIpAddresses
582
587
  : exports.DEFAULT_CERTIFICATE_SUBJECT_IP_ADDRESSES,
583
- validityInDays: Math.min(MAX_CERTIFICATE_VALIDITY_DAYS, (_a = options === null || options === void 0 ? void 0 : options.validityInDays) !== null && _a !== void 0 ? _a : MAX_CERTIFICATE_VALIDITY_DAYS)
588
+ validityInDays: Math.min(MAX_CERTIFICATE_VALIDITY_DAYS, (_a = options === null || options === void 0 ? void 0 : options.validityInDays) !== null && _a !== void 0 ? _a : MAX_CERTIFICATE_VALIDITY_DAYS),
589
+ skipCertificateTrust: skipCertificateTrust
584
590
  };
585
591
  }
586
592
  function isIPAddress(altName) {
@@ -1 +1 @@
1
- {"version":3,"file":"CertificateManager.js","sourceRoot":"","sources":["../src/CertificateManager.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { pki } from 'node-forge';\nimport * as path from 'path';\nimport { EOL } from 'os';\nimport { FileSystem } from '@rushstack/node-core-library';\nimport type { ITerminal } from '@rushstack/terminal';\n\nimport { runSudoAsync, type IRunResult, runAsync } from './runCommand';\nimport { CertificateStore } from './CertificateStore';\n\nconst CA_SERIAL_NUMBER: string = '731c321744e34650a202e3ef91c3c1b0';\nconst TLS_SERIAL_NUMBER: string = '731c321744e34650a202e3ef00000001';\nconst FRIENDLY_NAME: string = 'debug-certificate-manager Development Certificate';\nconst MAC_KEYCHAIN: string = '/Library/Keychains/System.keychain';\nconst CERTUTIL_EXE_NAME: string = 'certutil';\nconst CA_ALT_NAME: string = 'rushstack-certificate-manager.localhost';\nconst ONE_DAY_IN_MILLISECONDS: number = 24 * 60 * 60 * 1000;\n\n/**\n * The set of names the certificate should be generated for, by default.\n * @public\n */\nexport const DEFAULT_CERTIFICATE_SUBJECT_NAMES: ReadonlyArray<string> = ['localhost'];\n\n/**\n * The set of ip addresses the certificate should be generated for, by default.\n * @public\n */\nexport const DEFAULT_CERTIFICATE_SUBJECT_IP_ADDRESSES: ReadonlyArray<string> = ['127.0.0.1'];\n\nconst DISABLE_CERT_GENERATION_VARIABLE_NAME: 'RUSHSTACK_DISABLE_DEV_CERT_GENERATION' =\n 'RUSHSTACK_DISABLE_DEV_CERT_GENERATION';\n\n/**\n * The interface for a debug certificate instance\n *\n * @public\n */\nexport interface ICertificate {\n /**\n * Generated pem Certificate Authority certificate contents\n */\n pemCaCertificate: string | undefined;\n\n /**\n * Generated pem TLS Server certificate contents\n */\n pemCertificate: string | undefined;\n\n /**\n * Private key for the TLS server certificate, used to sign TLS communications\n */\n pemKey: string | undefined;\n\n /**\n * The subject names the TLS server certificate is valid for\n */\n subjectAltNames: readonly string[] | undefined;\n}\n\ninterface ICaCertificate {\n /**\n * Certificate\n */\n certificate: pki.Certificate;\n\n /**\n * Private key for the CA cert. Delete after signing the TLS cert.\n */\n privateKey: pki.PrivateKey;\n}\n\ninterface ISubjectAltNameExtension {\n altNames: readonly IAltName[];\n}\n\n/**\n * Fields for a Subject Alternative Name of type DNS Name\n */\ninterface IDnsAltName {\n type: 2;\n value: string;\n}\n/**\n * Fields for a Subject Alternative Name of type IP Address\n * `node-forge` requires the field name to be \"ip\" instead of \"value\", likely due to subtle encoding differences.\n */\ninterface IIPAddressAltName {\n type: 7;\n ip: string;\n}\ntype IAltName = IDnsAltName | IIPAddressAltName;\n\n/**\n * Options to use if needing to generate a new certificate\n * @public\n */\nexport interface ICertificateGenerationOptions {\n /**\n * The DNS Subject names to issue the certificate for. Defaults to ['localhost'].\n */\n subjectAltNames?: ReadonlyArray<string>;\n /**\n * The IP Address Subject names to issue the certificate for. Defaults to ['127.0.0.1'].\n */\n subjectIPAddresses?: ReadonlyArray<string>;\n /**\n * How many days the certificate should be valid for.\n */\n validityInDays?: number;\n}\n\nconst MAX_CERTIFICATE_VALIDITY_DAYS: 365 = 365;\n\n/**\n * A utility class to handle generating, trusting, and untrustring a debug certificate.\n * Contains two public methods to `ensureCertificate` and `untrustCertificate`.\n * @public\n */\nexport class CertificateManager {\n private _certificateStore: CertificateStore;\n\n public constructor() {\n this._certificateStore = new CertificateStore();\n }\n\n /**\n * Get a development certificate from the store, or optionally, generate a new one\n * and trust it if one doesn't exist in the store.\n *\n * @public\n */\n public async ensureCertificateAsync(\n canGenerateNewCertificate: boolean,\n terminal: ITerminal,\n generationOptions?: ICertificateGenerationOptions\n ): Promise<ICertificate> {\n const optionsWithDefaults: Required<ICertificateGenerationOptions> =\n applyDefaultOptions(generationOptions);\n\n const { certificateData: existingCert, keyData: existingKey } = this._certificateStore;\n\n if (process.env[DISABLE_CERT_GENERATION_VARIABLE_NAME] === '1') {\n // Allow the environment (e.g. GitHub codespaces) to forcibly disable dev cert generation\n terminal.writeLine(\n `Found environment variable ${DISABLE_CERT_GENERATION_VARIABLE_NAME}=1, disabling certificate generation.`\n );\n canGenerateNewCertificate = false;\n }\n\n if (existingCert && existingKey) {\n const messages: string[] = [];\n\n const forge: typeof import('node-forge') = await import('node-forge');\n const certificate: pki.Certificate = forge.pki.certificateFromPem(existingCert);\n const altNamesExtension: ISubjectAltNameExtension | undefined = certificate.getExtension(\n 'subjectAltName'\n ) as ISubjectAltNameExtension;\n if (!altNamesExtension) {\n messages.push(\n 'The existing development certificate is missing the subjectAltName ' +\n 'property and will not work with the latest versions of some browsers.'\n );\n } else {\n const missingSubjectNames: Set<string> = new Set(optionsWithDefaults.subjectAltNames);\n for (const altName of altNamesExtension.altNames) {\n missingSubjectNames.delete(isIPAddress(altName) ? altName.ip : altName.value);\n }\n if (missingSubjectNames.size) {\n messages.push(\n `The existing development certificate does not include the following expected subjectAltName values: ` +\n Array.from(missingSubjectNames, (name: string) => `\"${name}\"`).join(', ')\n );\n }\n }\n\n const { notBefore, notAfter } = certificate.validity;\n const now: Date = new Date();\n if (now < notBefore) {\n messages.push(\n `The existing development certificate's validity period does not start until ${notBefore}. It is currently ${now}.`\n );\n }\n\n if (now > notAfter) {\n messages.push(\n `The existing development certificate's validity period ended ${notAfter}. It is currently ${now}.`\n );\n }\n\n now.setUTCDate(now.getUTCDate() + optionsWithDefaults.validityInDays);\n if (notAfter > now) {\n messages.push(\n `The existing development certificate's expiration date ${notAfter} exceeds the allowed limit ${now}. ` +\n `This will be rejected by many browsers.`\n );\n }\n\n if (\n notBefore.getTime() - notAfter.getTime() >\n optionsWithDefaults.validityInDays * ONE_DAY_IN_MILLISECONDS\n ) {\n messages.push(\n \"The existing development certificate's validity period is longer \" +\n `than ${optionsWithDefaults.validityInDays} days.`\n );\n }\n\n const { caCertificateData } = this._certificateStore;\n\n if (!caCertificateData) {\n messages.push(\n 'The existing development certificate is missing a separate CA cert as the root ' +\n 'of trust and will not work with the latest versions of some browsers.'\n );\n }\n\n const isTrusted: boolean = await this._detectIfCertificateIsTrustedAsync(terminal);\n if (!isTrusted) {\n messages.push('The existing development certificate is not currently trusted by your system.');\n }\n\n if (messages.length > 0) {\n if (canGenerateNewCertificate) {\n messages.push('Attempting to untrust the certificate and generate a new one.');\n terminal.writeWarningLine(messages.join(' '));\n await this.untrustCertificateAsync(terminal);\n return await this._ensureCertificateInternalAsync(optionsWithDefaults, terminal);\n } else {\n messages.push(\n 'Untrust the certificate and generate a new one, or set the ' +\n '`canGenerateNewCertificate` parameter to `true` when calling `ensureCertificateAsync`.'\n );\n throw new Error(messages.join(' '));\n }\n } else {\n return {\n pemCaCertificate: caCertificateData,\n pemCertificate: existingCert,\n pemKey: existingKey,\n subjectAltNames: altNamesExtension.altNames.map((entry) =>\n isIPAddress(entry) ? entry.ip : entry.value\n )\n };\n }\n } else if (canGenerateNewCertificate) {\n return await this._ensureCertificateInternalAsync(optionsWithDefaults, terminal);\n } else {\n throw new Error(\n 'No development certificate found. Generate a new certificate manually, or set the ' +\n '`canGenerateNewCertificate` parameter to `true` when calling `ensureCertificateAsync`.'\n );\n }\n }\n\n /**\n * Attempt to locate a previously generated debug certificate and untrust it.\n *\n * @public\n */\n public async untrustCertificateAsync(terminal: ITerminal): Promise<boolean> {\n this._certificateStore.certificateData = undefined;\n this._certificateStore.keyData = undefined;\n\n switch (process.platform) {\n case 'win32':\n const winUntrustResult: IRunResult = await runAsync(CERTUTIL_EXE_NAME, [\n '-user',\n '-delstore',\n 'root',\n CA_SERIAL_NUMBER\n ]);\n\n if (winUntrustResult.exitCode !== 0) {\n terminal.writeErrorLine(`Error: ${winUntrustResult.stderr.join(' ')}`);\n return false;\n } else {\n terminal.writeVerboseLine('Successfully untrusted development certificate.');\n return true;\n }\n\n case 'darwin':\n terminal.writeVerboseLine('Trying to find the signature of the development certificate.');\n\n const macFindCertificateResult: IRunResult = await runAsync('security', [\n 'find-certificate',\n '-c',\n 'localhost',\n '-a',\n '-Z',\n MAC_KEYCHAIN\n ]);\n if (macFindCertificateResult.exitCode !== 0) {\n terminal.writeErrorLine(\n `Error finding the development certificate: ${macFindCertificateResult.stderr.join(' ')}`\n );\n return false;\n }\n\n const shaHash: string | undefined = this._parseMacOsMatchingCertificateHash(\n macFindCertificateResult.stdout.join(EOL)\n );\n\n if (!shaHash) {\n terminal.writeErrorLine('Unable to find the development certificate.');\n return false;\n } else {\n terminal.writeVerboseLine(`Found the development certificate. SHA is ${shaHash}`);\n }\n\n const macUntrustResult: IRunResult = await runSudoAsync('security', [\n 'delete-certificate',\n '-Z',\n shaHash,\n MAC_KEYCHAIN\n ]);\n\n if (macUntrustResult.exitCode === 0) {\n terminal.writeVerboseLine('Successfully untrusted development certificate.');\n return true;\n } else {\n terminal.writeErrorLine(macUntrustResult.stderr.join(' '));\n return false;\n }\n\n default:\n // Linux + others: Have the user manually untrust the cert\n terminal.writeLine(\n 'Automatic certificate untrust is only implemented for debug-certificate-manager on Windows ' +\n 'and macOS. To untrust the development certificate, remove this certificate from your trusted ' +\n `root certification authorities: \"${this._certificateStore.certificatePath}\". The ` +\n `certificate has serial number \"${CA_SERIAL_NUMBER}\".`\n );\n return false;\n }\n }\n\n private async _createCACertificateAsync(\n validityInDays: number,\n forge: typeof import('node-forge')\n ): Promise<ICaCertificate> {\n const keys: pki.KeyPair = forge.pki.rsa.generateKeyPair(2048);\n const certificate: pki.Certificate = forge.pki.createCertificate();\n certificate.publicKey = keys.publicKey;\n\n certificate.serialNumber = CA_SERIAL_NUMBER;\n\n const notBefore: Date = new Date();\n const notAfter: Date = new Date(notBefore);\n notAfter.setUTCDate(notBefore.getUTCDate() + validityInDays);\n certificate.validity.notBefore = notBefore;\n certificate.validity.notAfter = notAfter;\n\n const attrs: pki.CertificateField[] = [\n {\n name: 'commonName',\n value: CA_ALT_NAME\n }\n ];\n\n certificate.setSubject(attrs);\n certificate.setIssuer(attrs);\n\n const altNames: readonly IAltName[] = [\n {\n type: 2, // DNS\n value: CA_ALT_NAME\n }\n ];\n\n certificate.setExtensions([\n {\n name: 'basicConstraints',\n cA: true,\n pathLenConstraint: 0,\n critical: true\n },\n {\n name: 'subjectAltName',\n altNames,\n critical: true\n },\n {\n name: 'issuerAltName',\n altNames,\n critical: false\n },\n {\n name: 'keyUsage',\n keyCertSign: true,\n critical: true\n },\n {\n name: 'extKeyUsage',\n serverAuth: true,\n critical: true\n },\n {\n name: 'friendlyName',\n value: FRIENDLY_NAME\n }\n ]);\n\n // self-sign certificate\n certificate.sign(keys.privateKey, forge.md.sha256.create());\n\n return {\n certificate,\n privateKey: keys.privateKey\n };\n }\n\n private async _createDevelopmentCertificateAsync(\n options: Required<ICertificateGenerationOptions>\n ): Promise<ICertificate> {\n const forge: typeof import('node-forge') = await import('node-forge');\n const keys: pki.KeyPair = forge.pki.rsa.generateKeyPair(2048);\n const certificate: pki.Certificate = forge.pki.createCertificate();\n\n certificate.publicKey = keys.publicKey;\n certificate.serialNumber = TLS_SERIAL_NUMBER;\n\n const { subjectAltNames: subjectNames, subjectIPAddresses: subjectIpAddresses, validityInDays } = options;\n\n const { certificate: caCertificate, privateKey: caPrivateKey } = await this._createCACertificateAsync(\n validityInDays,\n forge\n );\n\n const notBefore: Date = new Date();\n const notAfter: Date = new Date(notBefore);\n notAfter.setUTCDate(notBefore.getUTCDate() + validityInDays);\n certificate.validity.notBefore = notBefore;\n certificate.validity.notAfter = notAfter;\n\n const subjectAttrs: pki.CertificateField[] = [\n {\n name: 'commonName',\n value: subjectNames[0]\n }\n ];\n const issuerAttrs: pki.CertificateField[] = caCertificate.subject.attributes;\n\n certificate.setSubject(subjectAttrs);\n certificate.setIssuer(issuerAttrs);\n\n const subjectAltNames: IAltName[] = [\n ...subjectNames.map<IDnsAltName>((subjectName) => ({\n type: 2, // DNS\n value: subjectName\n })),\n ...subjectIpAddresses.map<IIPAddressAltName>((ip) => ({\n type: 7, // IP\n ip\n }))\n ];\n\n const issuerAltNames: readonly IAltName[] = [\n {\n type: 2, // DNS\n value: CA_ALT_NAME\n }\n ];\n\n certificate.setExtensions([\n {\n name: 'basicConstraints',\n cA: false,\n critical: true\n },\n {\n name: 'subjectAltName',\n altNames: subjectAltNames,\n critical: true\n },\n {\n name: 'issuerAltName',\n altNames: issuerAltNames,\n critical: false\n },\n {\n name: 'keyUsage',\n digitalSignature: true,\n keyEncipherment: true,\n dataEncipherment: true,\n critical: true\n },\n {\n name: 'extKeyUsage',\n serverAuth: true,\n critical: true\n },\n {\n name: 'friendlyName',\n value: FRIENDLY_NAME\n }\n ]);\n\n // Sign certificate with CA\n certificate.sign(caPrivateKey, forge.md.sha256.create());\n\n // convert a Forge certificate to PEM\n const caPem: string = forge.pki.certificateToPem(caCertificate);\n const pem: string = forge.pki.certificateToPem(certificate);\n const pemKey: string = forge.pki.privateKeyToPem(keys.privateKey);\n\n return {\n pemCaCertificate: caPem,\n pemCertificate: pem,\n pemKey: pemKey,\n subjectAltNames: options.subjectAltNames\n };\n }\n\n private async _tryTrustCertificateAsync(certificatePath: string, terminal: ITerminal): Promise<boolean> {\n switch (process.platform) {\n case 'win32':\n terminal.writeLine(\n 'Attempting to trust a development certificate. This self-signed certificate only points to localhost ' +\n 'and will be stored in your local user profile to be used by other instances of ' +\n 'debug-certificate-manager. If you do not consent to trust this certificate, click \"NO\" in the dialog.'\n );\n\n const winTrustResult: IRunResult = await runAsync(CERTUTIL_EXE_NAME, [\n '-user',\n '-addstore',\n 'root',\n certificatePath\n ]);\n\n if (winTrustResult.exitCode !== 0) {\n terminal.writeErrorLine(`Error: ${winTrustResult.stdout.toString()}`);\n\n const errorLines: string[] = winTrustResult.stdout\n .toString()\n .split(EOL)\n .map((line: string) => line.trim());\n\n // Not sure if this is always the status code for \"cancelled\" - should confirm.\n if (\n winTrustResult.exitCode === 2147943623 ||\n errorLines[errorLines.length - 1].indexOf('The operation was canceled by the user.') > 0\n ) {\n terminal.writeLine('Certificate trust cancelled.');\n } else {\n terminal.writeErrorLine('Certificate trust failed with an unknown error.');\n }\n\n return false;\n } else {\n terminal.writeVerboseLine('Successfully trusted development certificate.');\n\n return true;\n }\n\n case 'darwin':\n terminal.writeLine(\n 'Attempting to trust a development certificate. This self-signed certificate only points to localhost ' +\n 'and will be stored in your local user profile to be used by other instances of ' +\n 'debug-certificate-manager. If you do not consent to trust this certificate, do not enter your ' +\n 'root password in the prompt.'\n );\n\n const result: IRunResult = await runSudoAsync('security', [\n 'add-trusted-cert',\n '-d',\n '-r',\n 'trustRoot',\n '-k',\n MAC_KEYCHAIN,\n certificatePath\n ]);\n\n if (result.exitCode === 0) {\n terminal.writeVerboseLine('Successfully trusted development certificate.');\n return true;\n } else {\n if (\n result.stderr.some(\n (value: string) => !!value.match(/The authorization was cancelled by the user\\./)\n )\n ) {\n terminal.writeLine('Certificate trust cancelled.');\n return false;\n } else {\n terminal.writeErrorLine(\n `Certificate trust failed with an unknown error. Exit code: ${result.exitCode}. ` +\n `Error: ${result.stderr.join(' ')}`\n );\n return false;\n }\n }\n\n default:\n // Linux + others: Have the user manually trust the cert if they want to\n terminal.writeLine(\n 'Automatic certificate trust is only implemented for debug-certificate-manager on Windows ' +\n 'and macOS. To trust the development certificate, add this certificate to your trusted root ' +\n `certification authorities: \"${certificatePath}\".`\n );\n return true;\n }\n }\n\n private async _detectIfCertificateIsTrustedAsync(terminal: ITerminal): Promise<boolean> {\n switch (process.platform) {\n case 'win32':\n const winVerifyStoreResult: IRunResult = await runAsync(CERTUTIL_EXE_NAME, [\n '-user',\n '-verifystore',\n 'root',\n CA_SERIAL_NUMBER\n ]);\n\n if (winVerifyStoreResult.exitCode !== 0) {\n terminal.writeVerboseLine(\n 'The development certificate was not found in the store. CertUtil error: ',\n winVerifyStoreResult.stderr.join(' ')\n );\n return false;\n } else {\n terminal.writeVerboseLine(\n 'The development certificate was found in the store. CertUtil output: ',\n winVerifyStoreResult.stdout.join(' ')\n );\n return true;\n }\n\n case 'darwin':\n terminal.writeVerboseLine('Trying to find the signature of the development certificate.');\n\n const macFindCertificateResult: IRunResult = await runAsync('security', [\n 'find-certificate',\n '-c',\n 'localhost',\n '-a',\n '-Z',\n MAC_KEYCHAIN\n ]);\n\n if (macFindCertificateResult.exitCode !== 0) {\n terminal.writeVerboseLine(\n 'The development certificate was not found in keychain. Find certificate error: ',\n macFindCertificateResult.stderr.join(' ')\n );\n return false;\n }\n\n const shaHash: string | undefined = this._parseMacOsMatchingCertificateHash(\n macFindCertificateResult.stdout.join(EOL)\n );\n\n if (!shaHash) {\n terminal.writeVerboseLine(\n 'The development certificate was not found in keychain. Find certificate output:\\n',\n macFindCertificateResult.stdout.join(' ')\n );\n return false;\n }\n\n terminal.writeVerboseLine(`The development certificate was found in keychain.`);\n return true;\n\n default:\n // Linux + others: Have the user manually verify the cert is trusted\n terminal.writeVerboseLine(\n 'Automatic certificate trust validation is only implemented for debug-certificate-manager on Windows ' +\n 'and macOS. Manually verify this development certificate is present in your trusted ' +\n `root certification authorities: \"${this._certificateStore.certificatePath}\". ` +\n `The certificate has serial number \"${CA_SERIAL_NUMBER}\".`\n );\n // Always return true on Linux to prevent breaking flow.\n return true;\n }\n }\n\n private async _trySetFriendlyNameAsync(certificatePath: string, terminal: ITerminal): Promise<boolean> {\n if (process.platform === 'win32') {\n const basePath: string = path.dirname(certificatePath);\n const fileName: string = path.basename(certificatePath, path.extname(certificatePath));\n const friendlyNamePath: string = path.join(basePath, `${fileName}.inf`);\n\n const friendlyNameFile: string = [\n '[Version]',\n 'Signature = \"$Windows NT$\"',\n '[Properties]',\n `11 = \"{text}${FRIENDLY_NAME}\"`,\n ''\n ].join(EOL);\n\n await FileSystem.writeFileAsync(friendlyNamePath, friendlyNameFile);\n\n const repairStoreResult: IRunResult = await runAsync(CERTUTIL_EXE_NAME, [\n '-repairstore',\n '-user',\n 'root',\n CA_SERIAL_NUMBER,\n friendlyNamePath\n ]);\n\n if (repairStoreResult.exitCode !== 0) {\n terminal.writeVerboseLine(`CertUtil Error: ${repairStoreResult.stderr.join('')}`);\n terminal.writeVerboseLine(`CertUtil: ${repairStoreResult.stdout.join('')}`);\n return false;\n } else {\n terminal.writeVerboseLine('Successfully set certificate name.');\n return true;\n }\n } else {\n // No equivalent concept outside of Windows\n return true;\n }\n }\n\n private async _ensureCertificateInternalAsync(\n options: Required<ICertificateGenerationOptions>,\n terminal: ITerminal\n ): Promise<ICertificate> {\n const certificateStore: CertificateStore = this._certificateStore;\n const generatedCertificate: ICertificate = await this._createDevelopmentCertificateAsync(options);\n\n const certificateName: string = Date.now().toString();\n const tempDirName: string = path.join(__dirname, '..', 'temp');\n\n const tempCertificatePath: string = path.join(tempDirName, `${certificateName}.pem`);\n const pemFileContents: string | undefined = generatedCertificate.pemCaCertificate;\n if (pemFileContents) {\n await FileSystem.writeFileAsync(tempCertificatePath, pemFileContents, {\n ensureFolderExists: true\n });\n }\n\n const trustCertificateResult: boolean = await this._tryTrustCertificateAsync(\n tempCertificatePath,\n terminal\n );\n\n let subjectAltNames: readonly string[] | undefined;\n if (trustCertificateResult) {\n certificateStore.caCertificateData = generatedCertificate.pemCaCertificate;\n certificateStore.certificateData = generatedCertificate.pemCertificate;\n certificateStore.keyData = generatedCertificate.pemKey;\n subjectAltNames = generatedCertificate.subjectAltNames;\n\n // Try to set the friendly name, and warn if we can't\n if (!(await this._trySetFriendlyNameAsync(tempCertificatePath, terminal))) {\n terminal.writeWarningLine(\"Unable to set the certificate's friendly name.\");\n }\n } else {\n // Clear out the existing store data, if any exists\n certificateStore.caCertificateData = undefined;\n certificateStore.certificateData = undefined;\n certificateStore.keyData = undefined;\n }\n\n await FileSystem.deleteFileAsync(tempCertificatePath);\n\n return {\n pemCaCertificate: certificateStore.caCertificateData,\n pemCertificate: certificateStore.certificateData,\n pemKey: certificateStore.keyData,\n subjectAltNames\n };\n }\n\n private _parseMacOsMatchingCertificateHash(findCertificateOuput: string): string | undefined {\n let shaHash: string | undefined = undefined;\n for (const line of findCertificateOuput.split(EOL)) {\n // Sets `shaHash` to the current certificate SHA-1 as we progress through the lines of certificate text.\n const shaHashMatch: string[] | null = line.match(/^SHA-1 hash: (.+)$/);\n if (shaHashMatch) {\n shaHash = shaHashMatch[1];\n }\n\n const snbrMatch: string[] | null = line.match(/^\\s*\"snbr\"<blob>=0x([^\\s]+).+$/);\n if (snbrMatch && (snbrMatch[1] || '').toLowerCase() === CA_SERIAL_NUMBER) {\n return shaHash;\n }\n }\n }\n}\n\nfunction applyDefaultOptions(\n options: ICertificateGenerationOptions | undefined\n): Required<ICertificateGenerationOptions> {\n const subjectNames: ReadonlyArray<string> | undefined = options?.subjectAltNames;\n const subjectIpAddresses: ReadonlyArray<string> | undefined = options?.subjectIPAddresses;\n return {\n subjectAltNames: subjectNames?.length ? subjectNames : DEFAULT_CERTIFICATE_SUBJECT_NAMES,\n subjectIPAddresses: subjectIpAddresses?.length\n ? subjectIpAddresses\n : DEFAULT_CERTIFICATE_SUBJECT_IP_ADDRESSES,\n validityInDays: Math.min(\n MAX_CERTIFICATE_VALIDITY_DAYS,\n options?.validityInDays ?? MAX_CERTIFICATE_VALIDITY_DAYS\n )\n };\n}\n\nfunction isIPAddress(altName: IAltName): altName is IIPAddressAltName {\n return altName.type === 7;\n}\n"]}
1
+ {"version":3,"file":"CertificateManager.js","sourceRoot":"","sources":["../src/CertificateManager.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { pki } from 'node-forge';\nimport * as path from 'path';\nimport { EOL } from 'os';\nimport { FileSystem } from '@rushstack/node-core-library';\nimport type { ITerminal } from '@rushstack/terminal';\n\nimport { runSudoAsync, type IRunResult, runAsync } from './runCommand';\nimport { CertificateStore } from './CertificateStore';\n\nconst CA_SERIAL_NUMBER: string = '731c321744e34650a202e3ef91c3c1b0';\nconst TLS_SERIAL_NUMBER: string = '731c321744e34650a202e3ef00000001';\nconst FRIENDLY_NAME: string = 'debug-certificate-manager Development Certificate';\nconst MAC_KEYCHAIN: string = '/Library/Keychains/System.keychain';\nconst CERTUTIL_EXE_NAME: string = 'certutil';\nconst CA_ALT_NAME: string = 'rushstack-certificate-manager.localhost';\nconst ONE_DAY_IN_MILLISECONDS: number = 24 * 60 * 60 * 1000;\n\n/**\n * The set of names the certificate should be generated for, by default.\n * @public\n */\nexport const DEFAULT_CERTIFICATE_SUBJECT_NAMES: ReadonlyArray<string> = ['localhost'];\n\n/**\n * The set of ip addresses the certificate should be generated for, by default.\n * @public\n */\nexport const DEFAULT_CERTIFICATE_SUBJECT_IP_ADDRESSES: ReadonlyArray<string> = ['127.0.0.1'];\n\nconst DISABLE_CERT_GENERATION_VARIABLE_NAME: 'RUSHSTACK_DISABLE_DEV_CERT_GENERATION' =\n 'RUSHSTACK_DISABLE_DEV_CERT_GENERATION';\n\n/**\n * The interface for a debug certificate instance\n *\n * @public\n */\nexport interface ICertificate {\n /**\n * Generated pem Certificate Authority certificate contents\n */\n pemCaCertificate: string | undefined;\n\n /**\n * Generated pem TLS Server certificate contents\n */\n pemCertificate: string | undefined;\n\n /**\n * Private key for the TLS server certificate, used to sign TLS communications\n */\n pemKey: string | undefined;\n\n /**\n * The subject names the TLS server certificate is valid for\n */\n subjectAltNames: readonly string[] | undefined;\n}\n\ninterface ICaCertificate {\n /**\n * Certificate\n */\n certificate: pki.Certificate;\n\n /**\n * Private key for the CA cert. Delete after signing the TLS cert.\n */\n privateKey: pki.PrivateKey;\n}\n\ninterface ISubjectAltNameExtension {\n altNames: readonly IAltName[];\n}\n\n/**\n * Fields for a Subject Alternative Name of type DNS Name\n */\ninterface IDnsAltName {\n type: 2;\n value: string;\n}\n/**\n * Fields for a Subject Alternative Name of type IP Address\n * `node-forge` requires the field name to be \"ip\" instead of \"value\", likely due to subtle encoding differences.\n */\ninterface IIPAddressAltName {\n type: 7;\n ip: string;\n}\ntype IAltName = IDnsAltName | IIPAddressAltName;\n\n/**\n * Options to use if needing to generate a new certificate\n * @public\n */\nexport interface ICertificateGenerationOptions {\n /**\n * The DNS Subject names to issue the certificate for. Defaults to ['localhost'].\n */\n subjectAltNames?: ReadonlyArray<string>;\n /**\n * The IP Address Subject names to issue the certificate for. Defaults to ['127.0.0.1'].\n */\n subjectIPAddresses?: ReadonlyArray<string>;\n /**\n * How many days the certificate should be valid for.\n */\n validityInDays?: number;\n /**\n * Skip trusting a certificate. Defaults to false.\n */\n skipCertificateTrust?: boolean;\n}\n\nconst MAX_CERTIFICATE_VALIDITY_DAYS: 365 = 365;\n\n/**\n * A utility class to handle generating, trusting, and untrustring a debug certificate.\n * Contains two public methods to `ensureCertificate` and `untrustCertificate`.\n * @public\n */\nexport class CertificateManager {\n private _certificateStore: CertificateStore;\n\n public constructor() {\n this._certificateStore = new CertificateStore();\n }\n\n /**\n * Get a development certificate from the store, or optionally, generate a new one\n * and trust it if one doesn't exist in the store.\n *\n * @public\n */\n public async ensureCertificateAsync(\n canGenerateNewCertificate: boolean,\n terminal: ITerminal,\n options?: ICertificateGenerationOptions\n ): Promise<ICertificate> {\n const optionsWithDefaults: Required<ICertificateGenerationOptions> = applyDefaultOptions(options);\n\n const { certificateData: existingCert, keyData: existingKey } = this._certificateStore;\n\n if (process.env[DISABLE_CERT_GENERATION_VARIABLE_NAME] === '1') {\n // Allow the environment (e.g. GitHub codespaces) to forcibly disable dev cert generation\n terminal.writeLine(\n `Found environment variable ${DISABLE_CERT_GENERATION_VARIABLE_NAME}=1, disabling certificate generation.`\n );\n canGenerateNewCertificate = false;\n }\n\n if (existingCert && existingKey) {\n const messages: string[] = [];\n\n const forge: typeof import('node-forge') = await import('node-forge');\n const certificate: pki.Certificate = forge.pki.certificateFromPem(existingCert);\n const altNamesExtension: ISubjectAltNameExtension | undefined = certificate.getExtension(\n 'subjectAltName'\n ) as ISubjectAltNameExtension;\n if (!altNamesExtension) {\n messages.push(\n 'The existing development certificate is missing the subjectAltName ' +\n 'property and will not work with the latest versions of some browsers.'\n );\n } else {\n const missingSubjectNames: Set<string> = new Set(optionsWithDefaults.subjectAltNames);\n for (const altName of altNamesExtension.altNames) {\n missingSubjectNames.delete(isIPAddress(altName) ? altName.ip : altName.value);\n }\n if (missingSubjectNames.size) {\n messages.push(\n `The existing development certificate does not include the following expected subjectAltName values: ` +\n Array.from(missingSubjectNames, (name: string) => `\"${name}\"`).join(', ')\n );\n }\n }\n\n const { notBefore, notAfter } = certificate.validity;\n const now: Date = new Date();\n if (now < notBefore) {\n messages.push(\n `The existing development certificate's validity period does not start until ${notBefore}. It is currently ${now}.`\n );\n }\n\n if (now > notAfter) {\n messages.push(\n `The existing development certificate's validity period ended ${notAfter}. It is currently ${now}.`\n );\n }\n\n now.setUTCDate(now.getUTCDate() + optionsWithDefaults.validityInDays);\n if (notAfter > now) {\n messages.push(\n `The existing development certificate's expiration date ${notAfter} exceeds the allowed limit ${now}. ` +\n `This will be rejected by many browsers.`\n );\n }\n\n if (\n notBefore.getTime() - notAfter.getTime() >\n optionsWithDefaults.validityInDays * ONE_DAY_IN_MILLISECONDS\n ) {\n messages.push(\n \"The existing development certificate's validity period is longer \" +\n `than ${optionsWithDefaults.validityInDays} days.`\n );\n }\n\n const { caCertificateData } = this._certificateStore;\n\n if (!caCertificateData) {\n messages.push(\n 'The existing development certificate is missing a separate CA cert as the root ' +\n 'of trust and will not work with the latest versions of some browsers.'\n );\n }\n\n const isTrusted: boolean = await this._detectIfCertificateIsTrustedAsync(terminal);\n if (!isTrusted) {\n messages.push('The existing development certificate is not currently trusted by your system.');\n }\n\n if (messages.length > 0) {\n if (canGenerateNewCertificate) {\n messages.push('Attempting to untrust the certificate and generate a new one.');\n terminal.writeWarningLine(messages.join(' '));\n if (!options?.skipCertificateTrust) {\n await this.untrustCertificateAsync(terminal);\n }\n return await this._ensureCertificateInternalAsync(optionsWithDefaults, terminal);\n } else {\n messages.push(\n 'Untrust the certificate and generate a new one, or set the ' +\n '`canGenerateNewCertificate` parameter to `true` when calling `ensureCertificateAsync`.'\n );\n throw new Error(messages.join(' '));\n }\n } else {\n return {\n pemCaCertificate: caCertificateData,\n pemCertificate: existingCert,\n pemKey: existingKey,\n subjectAltNames: altNamesExtension.altNames.map((entry) =>\n isIPAddress(entry) ? entry.ip : entry.value\n )\n };\n }\n } else if (canGenerateNewCertificate) {\n return await this._ensureCertificateInternalAsync(optionsWithDefaults, terminal);\n } else {\n throw new Error(\n 'No development certificate found. Generate a new certificate manually, or set the ' +\n '`canGenerateNewCertificate` parameter to `true` when calling `ensureCertificateAsync`.'\n );\n }\n }\n\n /**\n * Attempt to locate a previously generated debug certificate and untrust it.\n *\n * @public\n */\n public async untrustCertificateAsync(terminal: ITerminal): Promise<boolean> {\n this._certificateStore.certificateData = undefined;\n this._certificateStore.keyData = undefined;\n\n switch (process.platform) {\n case 'win32':\n const winUntrustResult: IRunResult = await runAsync(CERTUTIL_EXE_NAME, [\n '-user',\n '-delstore',\n 'root',\n CA_SERIAL_NUMBER\n ]);\n\n if (winUntrustResult.exitCode !== 0) {\n terminal.writeErrorLine(`Error: ${winUntrustResult.stderr.join(' ')}`);\n return false;\n } else {\n terminal.writeVerboseLine('Successfully untrusted development certificate.');\n return true;\n }\n\n case 'darwin':\n terminal.writeVerboseLine('Trying to find the signature of the development certificate.');\n\n const macFindCertificateResult: IRunResult = await runAsync('security', [\n 'find-certificate',\n '-c',\n 'localhost',\n '-a',\n '-Z',\n MAC_KEYCHAIN\n ]);\n if (macFindCertificateResult.exitCode !== 0) {\n terminal.writeErrorLine(\n `Error finding the development certificate: ${macFindCertificateResult.stderr.join(' ')}`\n );\n return false;\n }\n\n const shaHash: string | undefined = this._parseMacOsMatchingCertificateHash(\n macFindCertificateResult.stdout.join(EOL)\n );\n\n if (!shaHash) {\n terminal.writeErrorLine('Unable to find the development certificate.');\n return false;\n } else {\n terminal.writeVerboseLine(`Found the development certificate. SHA is ${shaHash}`);\n }\n\n const macUntrustResult: IRunResult = await runSudoAsync('security', [\n 'delete-certificate',\n '-Z',\n shaHash,\n MAC_KEYCHAIN\n ]);\n\n if (macUntrustResult.exitCode === 0) {\n terminal.writeVerboseLine('Successfully untrusted development certificate.');\n return true;\n } else {\n terminal.writeErrorLine(macUntrustResult.stderr.join(' '));\n return false;\n }\n\n default:\n // Linux + others: Have the user manually untrust the cert\n terminal.writeLine(\n 'Automatic certificate untrust is only implemented for debug-certificate-manager on Windows ' +\n 'and macOS. To untrust the development certificate, remove this certificate from your trusted ' +\n `root certification authorities: \"${this._certificateStore.certificatePath}\". The ` +\n `certificate has serial number \"${CA_SERIAL_NUMBER}\".`\n );\n return false;\n }\n }\n\n private async _createCACertificateAsync(\n validityInDays: number,\n forge: typeof import('node-forge')\n ): Promise<ICaCertificate> {\n const keys: pki.KeyPair = forge.pki.rsa.generateKeyPair(2048);\n const certificate: pki.Certificate = forge.pki.createCertificate();\n certificate.publicKey = keys.publicKey;\n\n certificate.serialNumber = CA_SERIAL_NUMBER;\n\n const notBefore: Date = new Date();\n const notAfter: Date = new Date(notBefore);\n notAfter.setUTCDate(notBefore.getUTCDate() + validityInDays);\n certificate.validity.notBefore = notBefore;\n certificate.validity.notAfter = notAfter;\n\n const attrs: pki.CertificateField[] = [\n {\n name: 'commonName',\n value: CA_ALT_NAME\n }\n ];\n\n certificate.setSubject(attrs);\n certificate.setIssuer(attrs);\n\n const altNames: readonly IAltName[] = [\n {\n type: 2, // DNS\n value: CA_ALT_NAME\n }\n ];\n\n certificate.setExtensions([\n {\n name: 'basicConstraints',\n cA: true,\n pathLenConstraint: 0,\n critical: true\n },\n {\n name: 'subjectAltName',\n altNames,\n critical: true\n },\n {\n name: 'issuerAltName',\n altNames,\n critical: false\n },\n {\n name: 'keyUsage',\n keyCertSign: true,\n critical: true\n },\n {\n name: 'extKeyUsage',\n serverAuth: true,\n critical: true\n },\n {\n name: 'friendlyName',\n value: FRIENDLY_NAME\n }\n ]);\n\n // self-sign certificate\n certificate.sign(keys.privateKey, forge.md.sha256.create());\n\n return {\n certificate,\n privateKey: keys.privateKey\n };\n }\n\n private async _createDevelopmentCertificateAsync(\n options: Required<ICertificateGenerationOptions>\n ): Promise<ICertificate> {\n const forge: typeof import('node-forge') = await import('node-forge');\n const keys: pki.KeyPair = forge.pki.rsa.generateKeyPair(2048);\n const certificate: pki.Certificate = forge.pki.createCertificate();\n\n certificate.publicKey = keys.publicKey;\n certificate.serialNumber = TLS_SERIAL_NUMBER;\n\n const { subjectAltNames: subjectNames, subjectIPAddresses: subjectIpAddresses, validityInDays } = options;\n\n const { certificate: caCertificate, privateKey: caPrivateKey } = await this._createCACertificateAsync(\n validityInDays,\n forge\n );\n\n const notBefore: Date = new Date();\n const notAfter: Date = new Date(notBefore);\n notAfter.setUTCDate(notBefore.getUTCDate() + validityInDays);\n certificate.validity.notBefore = notBefore;\n certificate.validity.notAfter = notAfter;\n\n const subjectAttrs: pki.CertificateField[] = [\n {\n name: 'commonName',\n value: subjectNames[0]\n }\n ];\n const issuerAttrs: pki.CertificateField[] = caCertificate.subject.attributes;\n\n certificate.setSubject(subjectAttrs);\n certificate.setIssuer(issuerAttrs);\n\n const subjectAltNames: IAltName[] = [\n ...subjectNames.map<IDnsAltName>((subjectName) => ({\n type: 2, // DNS\n value: subjectName\n })),\n ...subjectIpAddresses.map<IIPAddressAltName>((ip) => ({\n type: 7, // IP\n ip\n }))\n ];\n\n const issuerAltNames: readonly IAltName[] = [\n {\n type: 2, // DNS\n value: CA_ALT_NAME\n }\n ];\n\n certificate.setExtensions([\n {\n name: 'basicConstraints',\n cA: false,\n critical: true\n },\n {\n name: 'subjectAltName',\n altNames: subjectAltNames,\n critical: true\n },\n {\n name: 'issuerAltName',\n altNames: issuerAltNames,\n critical: false\n },\n {\n name: 'keyUsage',\n digitalSignature: true,\n keyEncipherment: true,\n dataEncipherment: true,\n critical: true\n },\n {\n name: 'extKeyUsage',\n serverAuth: true,\n critical: true\n },\n {\n name: 'friendlyName',\n value: FRIENDLY_NAME\n }\n ]);\n\n // Sign certificate with CA\n certificate.sign(caPrivateKey, forge.md.sha256.create());\n\n // convert a Forge certificate to PEM\n const caPem: string = forge.pki.certificateToPem(caCertificate);\n const pem: string = forge.pki.certificateToPem(certificate);\n const pemKey: string = forge.pki.privateKeyToPem(keys.privateKey);\n\n return {\n pemCaCertificate: caPem,\n pemCertificate: pem,\n pemKey: pemKey,\n subjectAltNames: options.subjectAltNames\n };\n }\n\n private async _tryTrustCertificateAsync(certificatePath: string, terminal: ITerminal): Promise<boolean> {\n switch (process.platform) {\n case 'win32':\n terminal.writeLine(\n 'Attempting to trust a development certificate. This self-signed certificate only points to localhost ' +\n 'and will be stored in your local user profile to be used by other instances of ' +\n 'debug-certificate-manager. If you do not consent to trust this certificate, click \"NO\" in the dialog.'\n );\n\n const winTrustResult: IRunResult = await runAsync(CERTUTIL_EXE_NAME, [\n '-user',\n '-addstore',\n 'root',\n certificatePath\n ]);\n\n if (winTrustResult.exitCode !== 0) {\n terminal.writeErrorLine(`Error: ${winTrustResult.stdout.toString()}`);\n\n const errorLines: string[] = winTrustResult.stdout\n .toString()\n .split(EOL)\n .map((line: string) => line.trim());\n\n // Not sure if this is always the status code for \"cancelled\" - should confirm.\n if (\n winTrustResult.exitCode === 2147943623 ||\n errorLines[errorLines.length - 1].indexOf('The operation was canceled by the user.') > 0\n ) {\n terminal.writeLine('Certificate trust cancelled.');\n } else {\n terminal.writeErrorLine('Certificate trust failed with an unknown error.');\n }\n\n return false;\n } else {\n terminal.writeVerboseLine('Successfully trusted development certificate.');\n\n return true;\n }\n\n case 'darwin':\n terminal.writeLine(\n 'Attempting to trust a development certificate. This self-signed certificate only points to localhost ' +\n 'and will be stored in your local user profile to be used by other instances of ' +\n 'debug-certificate-manager. If you do not consent to trust this certificate, do not enter your ' +\n 'root password in the prompt.'\n );\n\n const result: IRunResult = await runSudoAsync('security', [\n 'add-trusted-cert',\n '-d',\n '-r',\n 'trustRoot',\n '-k',\n MAC_KEYCHAIN,\n certificatePath\n ]);\n\n if (result.exitCode === 0) {\n terminal.writeVerboseLine('Successfully trusted development certificate.');\n return true;\n } else {\n if (\n result.stderr.some(\n (value: string) => !!value.match(/The authorization was cancelled by the user\\./)\n )\n ) {\n terminal.writeLine('Certificate trust cancelled.');\n return false;\n } else {\n terminal.writeErrorLine(\n `Certificate trust failed with an unknown error. Exit code: ${result.exitCode}. ` +\n `Error: ${result.stderr.join(' ')}`\n );\n return false;\n }\n }\n\n default:\n // Linux + others: Have the user manually trust the cert if they want to\n terminal.writeLine(\n 'Automatic certificate trust is only implemented for debug-certificate-manager on Windows ' +\n 'and macOS. To trust the development certificate, add this certificate to your trusted root ' +\n `certification authorities: \"${certificatePath}\".`\n );\n return true;\n }\n }\n\n private async _detectIfCertificateIsTrustedAsync(terminal: ITerminal): Promise<boolean> {\n switch (process.platform) {\n case 'win32':\n const winVerifyStoreResult: IRunResult = await runAsync(CERTUTIL_EXE_NAME, [\n '-user',\n '-verifystore',\n 'root',\n CA_SERIAL_NUMBER\n ]);\n\n if (winVerifyStoreResult.exitCode !== 0) {\n terminal.writeVerboseLine(\n 'The development certificate was not found in the store. CertUtil error: ',\n winVerifyStoreResult.stderr.join(' ')\n );\n return false;\n } else {\n terminal.writeVerboseLine(\n 'The development certificate was found in the store. CertUtil output: ',\n winVerifyStoreResult.stdout.join(' ')\n );\n return true;\n }\n\n case 'darwin':\n terminal.writeVerboseLine('Trying to find the signature of the development certificate.');\n\n const macFindCertificateResult: IRunResult = await runAsync('security', [\n 'find-certificate',\n '-c',\n 'localhost',\n '-a',\n '-Z',\n MAC_KEYCHAIN\n ]);\n\n if (macFindCertificateResult.exitCode !== 0) {\n terminal.writeVerboseLine(\n 'The development certificate was not found in keychain. Find certificate error: ',\n macFindCertificateResult.stderr.join(' ')\n );\n return false;\n }\n\n const shaHash: string | undefined = this._parseMacOsMatchingCertificateHash(\n macFindCertificateResult.stdout.join(EOL)\n );\n\n if (!shaHash) {\n terminal.writeVerboseLine(\n 'The development certificate was not found in keychain. Find certificate output:\\n',\n macFindCertificateResult.stdout.join(' ')\n );\n return false;\n }\n\n terminal.writeVerboseLine(`The development certificate was found in keychain.`);\n return true;\n\n default:\n // Linux + others: Have the user manually verify the cert is trusted\n terminal.writeVerboseLine(\n 'Automatic certificate trust validation is only implemented for debug-certificate-manager on Windows ' +\n 'and macOS. Manually verify this development certificate is present in your trusted ' +\n `root certification authorities: \"${this._certificateStore.certificatePath}\". ` +\n `The certificate has serial number \"${CA_SERIAL_NUMBER}\".`\n );\n // Always return true on Linux to prevent breaking flow.\n return true;\n }\n }\n\n private async _trySetFriendlyNameAsync(certificatePath: string, terminal: ITerminal): Promise<boolean> {\n if (process.platform === 'win32') {\n const basePath: string = path.dirname(certificatePath);\n const fileName: string = path.basename(certificatePath, path.extname(certificatePath));\n const friendlyNamePath: string = path.join(basePath, `${fileName}.inf`);\n\n const friendlyNameFile: string = [\n '[Version]',\n 'Signature = \"$Windows NT$\"',\n '[Properties]',\n `11 = \"{text}${FRIENDLY_NAME}\"`,\n ''\n ].join(EOL);\n\n await FileSystem.writeFileAsync(friendlyNamePath, friendlyNameFile);\n\n const repairStoreResult: IRunResult = await runAsync(CERTUTIL_EXE_NAME, [\n '-repairstore',\n '-user',\n 'root',\n CA_SERIAL_NUMBER,\n friendlyNamePath\n ]);\n\n if (repairStoreResult.exitCode !== 0) {\n terminal.writeVerboseLine(`CertUtil Error: ${repairStoreResult.stderr.join('')}`);\n terminal.writeVerboseLine(`CertUtil: ${repairStoreResult.stdout.join('')}`);\n return false;\n } else {\n terminal.writeVerboseLine('Successfully set certificate name.');\n return true;\n }\n } else {\n // No equivalent concept outside of Windows\n return true;\n }\n }\n\n private async _ensureCertificateInternalAsync(\n options: Required<ICertificateGenerationOptions>,\n terminal: ITerminal\n ): Promise<ICertificate> {\n const certificateStore: CertificateStore = this._certificateStore;\n const generatedCertificate: ICertificate = await this._createDevelopmentCertificateAsync(options);\n\n const certificateName: string = Date.now().toString();\n const tempDirName: string = path.join(__dirname, '..', 'temp');\n\n const tempCertificatePath: string = path.join(tempDirName, `${certificateName}.pem`);\n const pemFileContents: string | undefined = generatedCertificate.pemCaCertificate;\n if (pemFileContents) {\n await FileSystem.writeFileAsync(tempCertificatePath, pemFileContents, {\n ensureFolderExists: true\n });\n }\n\n const trustCertificateResult: boolean = options.skipCertificateTrust\n ? true\n : await this._tryTrustCertificateAsync(tempCertificatePath, terminal);\n\n let subjectAltNames: readonly string[] | undefined;\n if (trustCertificateResult) {\n certificateStore.caCertificateData = generatedCertificate.pemCaCertificate;\n certificateStore.certificateData = generatedCertificate.pemCertificate;\n certificateStore.keyData = generatedCertificate.pemKey;\n subjectAltNames = generatedCertificate.subjectAltNames;\n\n // Try to set the friendly name, and warn if we can't\n if (!(await this._trySetFriendlyNameAsync(tempCertificatePath, terminal))) {\n terminal.writeWarningLine(\"Unable to set the certificate's friendly name.\");\n }\n } else {\n // Clear out the existing store data, if any exists\n certificateStore.caCertificateData = undefined;\n certificateStore.certificateData = undefined;\n certificateStore.keyData = undefined;\n }\n\n await FileSystem.deleteFileAsync(tempCertificatePath);\n\n return {\n pemCaCertificate: certificateStore.caCertificateData,\n pemCertificate: certificateStore.certificateData,\n pemKey: certificateStore.keyData,\n subjectAltNames\n };\n }\n\n private _parseMacOsMatchingCertificateHash(findCertificateOuput: string): string | undefined {\n let shaHash: string | undefined = undefined;\n for (const line of findCertificateOuput.split(EOL)) {\n // Sets `shaHash` to the current certificate SHA-1 as we progress through the lines of certificate text.\n const shaHashMatch: string[] | null = line.match(/^SHA-1 hash: (.+)$/);\n if (shaHashMatch) {\n shaHash = shaHashMatch[1];\n }\n\n const snbrMatch: string[] | null = line.match(/^\\s*\"snbr\"<blob>=0x([^\\s]+).+$/);\n if (snbrMatch && (snbrMatch[1] || '').toLowerCase() === CA_SERIAL_NUMBER) {\n return shaHash;\n }\n }\n }\n}\n\nfunction applyDefaultOptions(\n options: ICertificateGenerationOptions | undefined\n): Required<ICertificateGenerationOptions> {\n const subjectNames: ReadonlyArray<string> | undefined = options?.subjectAltNames;\n const subjectIpAddresses: ReadonlyArray<string> | undefined = options?.subjectIPAddresses;\n const skipCertificateTrust: boolean | undefined = options?.skipCertificateTrust || false;\n return {\n subjectAltNames: subjectNames?.length ? subjectNames : DEFAULT_CERTIFICATE_SUBJECT_NAMES,\n subjectIPAddresses: subjectIpAddresses?.length\n ? subjectIpAddresses\n : DEFAULT_CERTIFICATE_SUBJECT_IP_ADDRESSES,\n validityInDays: Math.min(\n MAX_CERTIFICATE_VALIDITY_DAYS,\n options?.validityInDays ?? MAX_CERTIFICATE_VALIDITY_DAYS\n ),\n skipCertificateTrust: skipCertificateTrust\n };\n}\n\nfunction isIPAddress(altName: IAltName): altName is IIPAddressAltName {\n return altName.type === 7;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rushstack/debug-certificate-manager",
3
- "version": "1.3.65",
3
+ "version": "1.4.0",
4
4
  "description": "Cross-platform functionality to create debug ssl certificates.",
5
5
  "main": "lib/index.js",
6
6
  "typings": "dist/debug-certificate-manager.d.ts",
@@ -13,13 +13,13 @@
13
13
  "dependencies": {
14
14
  "node-forge": "~1.3.1",
15
15
  "sudo": "~1.0.3",
16
- "@rushstack/node-core-library": "5.8.0",
17
- "@rushstack/terminal": "0.14.1"
16
+ "@rushstack/node-core-library": "5.9.0",
17
+ "@rushstack/terminal": "0.14.2"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@types/node-forge": "1.0.4",
21
- "local-node-rig": "1.0.0",
22
- "@rushstack/heft": "0.67.1"
21
+ "@rushstack/heft": "0.67.2",
22
+ "local-node-rig": "1.0.0"
23
23
  },
24
24
  "scripts": {
25
25
  "build": "heft build --clean",