@rushstack/debug-certificate-manager 1.1.84 → 1.2.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/dist/debug-certificate-manager.d.ts +49 -10
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/CertificateManager.d.ts +32 -4
- package/lib/CertificateManager.d.ts.map +1 -1
- package/lib/CertificateManager.js +163 -46
- package/lib/CertificateManager.js.map +1 -1
- package/lib/CertificateStore.d.ts +15 -6
- package/lib/CertificateStore.d.ts.map +1 -1
- package/lib/CertificateStore.js +50 -14
- package/lib/CertificateStore.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -29,19 +29,20 @@ export declare class CertificateManager {
|
|
|
29
29
|
*
|
|
30
30
|
* @public
|
|
31
31
|
*/
|
|
32
|
-
ensureCertificateAsync(canGenerateNewCertificate: boolean, terminal: ITerminal): Promise<ICertificate>;
|
|
32
|
+
ensureCertificateAsync(canGenerateNewCertificate: boolean, terminal: ITerminal, generationOptions?: ICertificateGenerationOptions): Promise<ICertificate>;
|
|
33
33
|
/**
|
|
34
34
|
* Attempt to locate a previously generated debug certificate and untrust it.
|
|
35
35
|
*
|
|
36
36
|
* @public
|
|
37
37
|
*/
|
|
38
38
|
untrustCertificateAsync(terminal: ITerminal): Promise<boolean>;
|
|
39
|
+
private _createCACertificate;
|
|
39
40
|
private _createDevelopmentCertificate;
|
|
40
41
|
private _tryTrustCertificateAsync;
|
|
41
42
|
private _detectIfCertificateIsTrustedAsync;
|
|
42
43
|
private _trySetFriendlyNameAsync;
|
|
43
44
|
private _ensureCertificateInternalAsync;
|
|
44
|
-
private
|
|
45
|
+
private _getCertificateSubjectAltName;
|
|
45
46
|
private _parseMacOsMatchingCertificateHash;
|
|
46
47
|
}
|
|
47
48
|
|
|
@@ -50,19 +51,28 @@ export declare class CertificateManager {
|
|
|
50
51
|
* @public
|
|
51
52
|
*/
|
|
52
53
|
export declare class CertificateStore {
|
|
53
|
-
private
|
|
54
|
-
private
|
|
55
|
-
private
|
|
56
|
-
private
|
|
54
|
+
private readonly _caCertificatePath;
|
|
55
|
+
private readonly _certificatePath;
|
|
56
|
+
private readonly _keyPath;
|
|
57
|
+
private _caCertificateData;
|
|
57
58
|
private _certificateData;
|
|
58
59
|
private _keyData;
|
|
59
60
|
constructor();
|
|
60
61
|
/**
|
|
61
|
-
* Path to the saved debug certificate
|
|
62
|
+
* Path to the saved debug CA certificate
|
|
63
|
+
*/
|
|
64
|
+
get caCertificatePath(): string;
|
|
65
|
+
/**
|
|
66
|
+
* Path to the saved debug TLS certificate
|
|
62
67
|
*/
|
|
63
68
|
get certificatePath(): string;
|
|
64
69
|
/**
|
|
65
|
-
* Debug certificate pem file contents.
|
|
70
|
+
* Debug Certificate Authority certificate pem file contents.
|
|
71
|
+
*/
|
|
72
|
+
get caCertificateData(): string | undefined;
|
|
73
|
+
set caCertificateData(certificate: string | undefined);
|
|
74
|
+
/**
|
|
75
|
+
* Debug TLS Server certificate pem file contents.
|
|
66
76
|
*/
|
|
67
77
|
get certificateData(): string | undefined;
|
|
68
78
|
set certificateData(certificate: string | undefined);
|
|
@@ -73,6 +83,12 @@ export declare class CertificateStore {
|
|
|
73
83
|
set keyData(key: string | undefined);
|
|
74
84
|
}
|
|
75
85
|
|
|
86
|
+
/**
|
|
87
|
+
* The set of names the certificate should be generated for, by default.
|
|
88
|
+
* @public
|
|
89
|
+
*/
|
|
90
|
+
export declare const DEFAULT_CERTIFICATE_SUBJECT_NAMES: ReadonlyArray<string>;
|
|
91
|
+
|
|
76
92
|
/**
|
|
77
93
|
* The interface for a debug certificate instance
|
|
78
94
|
*
|
|
@@ -80,13 +96,36 @@ export declare class CertificateStore {
|
|
|
80
96
|
*/
|
|
81
97
|
export declare interface ICertificate {
|
|
82
98
|
/**
|
|
83
|
-
* Generated pem certificate contents
|
|
99
|
+
* Generated pem Certificate Authority certificate contents
|
|
100
|
+
*/
|
|
101
|
+
pemCaCertificate: string | undefined;
|
|
102
|
+
/**
|
|
103
|
+
* Generated pem TLS Server certificate contents
|
|
84
104
|
*/
|
|
85
105
|
pemCertificate: string | undefined;
|
|
86
106
|
/**
|
|
87
|
-
* Private key used to sign
|
|
107
|
+
* Private key for the TLS server certificate, used to sign TLS communications
|
|
88
108
|
*/
|
|
89
109
|
pemKey: string | undefined;
|
|
110
|
+
/**
|
|
111
|
+
* The subject names the TLS server certificate is valid for
|
|
112
|
+
*/
|
|
113
|
+
subjectAltNames: readonly string[] | undefined;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Options to use if needing to generate a new certificate
|
|
118
|
+
* @public
|
|
119
|
+
*/
|
|
120
|
+
export declare interface ICertificateGenerationOptions {
|
|
121
|
+
/**
|
|
122
|
+
* The DNS Subject names to issue the certificate for.
|
|
123
|
+
*/
|
|
124
|
+
subjectAltNames?: ReadonlyArray<string>;
|
|
125
|
+
/**
|
|
126
|
+
* How many days the certificate should be valid for.
|
|
127
|
+
*/
|
|
128
|
+
validityInDays?: number;
|
|
90
129
|
}
|
|
91
130
|
|
|
92
131
|
export { }
|
package/dist/tsdoc-metadata.json
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { ITerminal } from '@rushstack/node-core-library';
|
|
2
|
+
/**
|
|
3
|
+
* The set of names the certificate should be generated for, by default.
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export declare const DEFAULT_CERTIFICATE_SUBJECT_NAMES: ReadonlyArray<string>;
|
|
2
7
|
/**
|
|
3
8
|
* The interface for a debug certificate instance
|
|
4
9
|
*
|
|
@@ -6,13 +11,35 @@ import { ITerminal } from '@rushstack/node-core-library';
|
|
|
6
11
|
*/
|
|
7
12
|
export interface ICertificate {
|
|
8
13
|
/**
|
|
9
|
-
* Generated pem certificate contents
|
|
14
|
+
* Generated pem Certificate Authority certificate contents
|
|
15
|
+
*/
|
|
16
|
+
pemCaCertificate: string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Generated pem TLS Server certificate contents
|
|
10
19
|
*/
|
|
11
20
|
pemCertificate: string | undefined;
|
|
12
21
|
/**
|
|
13
|
-
* Private key used to sign
|
|
22
|
+
* Private key for the TLS server certificate, used to sign TLS communications
|
|
14
23
|
*/
|
|
15
24
|
pemKey: string | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* The subject names the TLS server certificate is valid for
|
|
27
|
+
*/
|
|
28
|
+
subjectAltNames: readonly string[] | undefined;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Options to use if needing to generate a new certificate
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
export interface ICertificateGenerationOptions {
|
|
35
|
+
/**
|
|
36
|
+
* The DNS Subject names to issue the certificate for.
|
|
37
|
+
*/
|
|
38
|
+
subjectAltNames?: ReadonlyArray<string>;
|
|
39
|
+
/**
|
|
40
|
+
* How many days the certificate should be valid for.
|
|
41
|
+
*/
|
|
42
|
+
validityInDays?: number;
|
|
16
43
|
}
|
|
17
44
|
/**
|
|
18
45
|
* A utility class to handle generating, trusting, and untrustring a debug certificate.
|
|
@@ -28,19 +55,20 @@ export declare class CertificateManager {
|
|
|
28
55
|
*
|
|
29
56
|
* @public
|
|
30
57
|
*/
|
|
31
|
-
ensureCertificateAsync(canGenerateNewCertificate: boolean, terminal: ITerminal): Promise<ICertificate>;
|
|
58
|
+
ensureCertificateAsync(canGenerateNewCertificate: boolean, terminal: ITerminal, generationOptions?: ICertificateGenerationOptions): Promise<ICertificate>;
|
|
32
59
|
/**
|
|
33
60
|
* Attempt to locate a previously generated debug certificate and untrust it.
|
|
34
61
|
*
|
|
35
62
|
* @public
|
|
36
63
|
*/
|
|
37
64
|
untrustCertificateAsync(terminal: ITerminal): Promise<boolean>;
|
|
65
|
+
private _createCACertificate;
|
|
38
66
|
private _createDevelopmentCertificate;
|
|
39
67
|
private _tryTrustCertificateAsync;
|
|
40
68
|
private _detectIfCertificateIsTrustedAsync;
|
|
41
69
|
private _trySetFriendlyNameAsync;
|
|
42
70
|
private _ensureCertificateInternalAsync;
|
|
43
|
-
private
|
|
71
|
+
private _getCertificateSubjectAltName;
|
|
44
72
|
private _parseMacOsMatchingCertificateHash;
|
|
45
73
|
}
|
|
46
74
|
//# sourceMappingURL=CertificateManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CertificateManager.d.ts","sourceRoot":"","sources":["../src/CertificateManager.ts"],"names":[],"mappings":"AAMA,OAAO,EAAc,SAAS,EAAU,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"CertificateManager.d.ts","sourceRoot":"","sources":["../src/CertificateManager.ts"],"names":[],"mappings":"AAMA,OAAO,EAAc,SAAS,EAAU,MAAM,8BAA8B,CAAC;AAc7E;;;GAGG;AACH,eAAO,MAAM,iCAAiC,EAAE,aAAa,CAAC,MAAM,CAAiB,CAAC;AAEtF;;;;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;AAuBD;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;OAEG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;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;IA2DxB;;;;OAIG;IACU,uBAAuB,CAAC,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IA6E3E,OAAO,CAAC,oBAAoB;IAsE5B,OAAO,CAAC,6BAA6B;YAyFvB,yBAAyB;YA0FzB,kCAAkC;YAwElC,wBAAwB;YAqCxB,+BAA+B;IAmD7C,OAAO,CAAC,6BAA6B;IASrC,OAAO,CAAC,kCAAkC;CAe3C"}
|
|
@@ -25,17 +25,24 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
return result;
|
|
26
26
|
};
|
|
27
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
-
exports.CertificateManager = void 0;
|
|
28
|
+
exports.CertificateManager = exports.DEFAULT_CERTIFICATE_SUBJECT_NAMES = void 0;
|
|
29
29
|
const path = __importStar(require("path"));
|
|
30
30
|
const os_1 = require("os");
|
|
31
31
|
const node_core_library_1 = require("@rushstack/node-core-library");
|
|
32
32
|
const runCommand_1 = require("./runCommand");
|
|
33
33
|
const CertificateStore_1 = require("./CertificateStore");
|
|
34
34
|
const forge = node_core_library_1.Import.lazy('node-forge', require);
|
|
35
|
-
const
|
|
35
|
+
const CA_SERIAL_NUMBER = '731c321744e34650a202e3ef91c3c1b0';
|
|
36
|
+
const TLS_SERIAL_NUMBER = '731c321744e34650a202e3ef00000001';
|
|
36
37
|
const FRIENDLY_NAME = 'debug-certificate-manager Development Certificate';
|
|
37
38
|
const MAC_KEYCHAIN = '/Library/Keychains/System.keychain';
|
|
38
39
|
const CERTUTIL_EXE_NAME = 'certutil';
|
|
40
|
+
const CA_ALT_NAME = 'rushstack-certificate-manager.localhost';
|
|
41
|
+
/**
|
|
42
|
+
* The set of names the certificate should be generated for, by default.
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
exports.DEFAULT_CERTIFICATE_SUBJECT_NAMES = ['localhost'];
|
|
39
46
|
/**
|
|
40
47
|
* A utility class to handle generating, trusting, and untrustring a debug certificate.
|
|
41
48
|
* Contains two public methods to `ensureCertificate` and `untrustCertificate`.
|
|
@@ -51,25 +58,30 @@ class CertificateManager {
|
|
|
51
58
|
*
|
|
52
59
|
* @public
|
|
53
60
|
*/
|
|
54
|
-
async ensureCertificateAsync(canGenerateNewCertificate, terminal) {
|
|
61
|
+
async ensureCertificateAsync(canGenerateNewCertificate, terminal, generationOptions) {
|
|
62
|
+
const optionsWithDefaults = applyDefaultOptions(generationOptions);
|
|
55
63
|
if (this._certificateStore.certificateData && this._certificateStore.keyData) {
|
|
56
|
-
let invalidCertificate = false;
|
|
57
64
|
const messages = [];
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
const altNamesExtension = this._getCertificateSubjectAltName();
|
|
66
|
+
if (!altNamesExtension) {
|
|
60
67
|
messages.push('The existing development certificate is missing the subjectAltName ' +
|
|
61
68
|
'property and will not work with the latest versions of some browsers.');
|
|
62
69
|
}
|
|
63
|
-
|
|
64
|
-
|
|
70
|
+
const hasCA = !!this._certificateStore.caCertificateData;
|
|
71
|
+
if (!hasCA) {
|
|
72
|
+
messages.push('The existing development certificate is missing a separate CA cert as the root ' +
|
|
73
|
+
'of trust and will not work with the latest versions of some browsers.');
|
|
74
|
+
}
|
|
75
|
+
const isTrusted = await this._detectIfCertificateIsTrustedAsync(terminal);
|
|
76
|
+
if (!isTrusted) {
|
|
65
77
|
messages.push('The existing development certificate is not currently trusted by your system.');
|
|
66
78
|
}
|
|
67
|
-
if (
|
|
79
|
+
if (!altNamesExtension || !isTrusted || !hasCA) {
|
|
68
80
|
if (canGenerateNewCertificate) {
|
|
69
81
|
messages.push('Attempting to untrust the certificate and generate a new one.');
|
|
70
82
|
terminal.writeWarningLine(messages.join(' '));
|
|
71
83
|
await this.untrustCertificateAsync(terminal);
|
|
72
|
-
await this._ensureCertificateInternalAsync(terminal);
|
|
84
|
+
return await this._ensureCertificateInternalAsync(optionsWithDefaults, terminal);
|
|
73
85
|
}
|
|
74
86
|
else {
|
|
75
87
|
messages.push('Untrust the certificate and generate a new one, or set the ' +
|
|
@@ -77,18 +89,22 @@ class CertificateManager {
|
|
|
77
89
|
throw new Error(messages.join(' '));
|
|
78
90
|
}
|
|
79
91
|
}
|
|
92
|
+
else {
|
|
93
|
+
return {
|
|
94
|
+
pemCaCertificate: this._certificateStore.caCertificateData,
|
|
95
|
+
pemCertificate: this._certificateStore.certificateData,
|
|
96
|
+
pemKey: this._certificateStore.keyData,
|
|
97
|
+
subjectAltNames: altNamesExtension.altNames.map((entry) => entry.value)
|
|
98
|
+
};
|
|
99
|
+
}
|
|
80
100
|
}
|
|
81
101
|
else if (canGenerateNewCertificate) {
|
|
82
|
-
await this._ensureCertificateInternalAsync(terminal);
|
|
102
|
+
return await this._ensureCertificateInternalAsync(optionsWithDefaults, terminal);
|
|
83
103
|
}
|
|
84
104
|
else {
|
|
85
105
|
throw new Error('No development certificate found. Generate a new certificate manually, or set the ' +
|
|
86
106
|
'`canGenerateNewCertificate` parameter to `true` when calling `ensureCertificateAsync`.');
|
|
87
107
|
}
|
|
88
|
-
return {
|
|
89
|
-
pemCertificate: this._certificateStore.certificateData,
|
|
90
|
-
pemKey: this._certificateStore.keyData
|
|
91
|
-
};
|
|
92
108
|
}
|
|
93
109
|
/**
|
|
94
110
|
* Attempt to locate a previously generated debug certificate and untrust it.
|
|
@@ -104,7 +120,7 @@ class CertificateManager {
|
|
|
104
120
|
'-user',
|
|
105
121
|
'-delstore',
|
|
106
122
|
'root',
|
|
107
|
-
|
|
123
|
+
CA_SERIAL_NUMBER
|
|
108
124
|
]);
|
|
109
125
|
if (winUntrustResult.code !== 0) {
|
|
110
126
|
terminal.writeErrorLine(`Error: ${winUntrustResult.stderr.join(' ')}`);
|
|
@@ -155,46 +171,58 @@ class CertificateManager {
|
|
|
155
171
|
terminal.writeLine('Automatic certificate untrust is only implemented for debug-certificate-manager on Windows ' +
|
|
156
172
|
'and macOS. To untrust the development certificate, remove this certificate from your trusted ' +
|
|
157
173
|
`root certification authorities: "${this._certificateStore.certificatePath}". The ` +
|
|
158
|
-
`certificate has serial number "${
|
|
174
|
+
`certificate has serial number "${CA_SERIAL_NUMBER}".`);
|
|
159
175
|
return false;
|
|
160
176
|
}
|
|
161
177
|
}
|
|
162
|
-
|
|
178
|
+
_createCACertificate(validityInDays) {
|
|
163
179
|
const keys = forge.pki.rsa.generateKeyPair(2048);
|
|
164
180
|
const certificate = forge.pki.createCertificate();
|
|
165
181
|
certificate.publicKey = keys.publicKey;
|
|
166
|
-
certificate.serialNumber =
|
|
182
|
+
certificate.serialNumber = CA_SERIAL_NUMBER;
|
|
167
183
|
const now = new Date();
|
|
168
184
|
certificate.validity.notBefore = now;
|
|
169
|
-
|
|
170
|
-
certificate.validity.notAfter.setFullYear(certificate.validity.notBefore.getFullYear() + 3);
|
|
185
|
+
certificate.validity.notAfter.setUTCDate(certificate.validity.notBefore.getUTCDate() + validityInDays);
|
|
171
186
|
const attrs = [
|
|
172
187
|
{
|
|
173
188
|
name: 'commonName',
|
|
174
|
-
value:
|
|
189
|
+
value: CA_ALT_NAME
|
|
175
190
|
}
|
|
176
191
|
];
|
|
177
192
|
certificate.setSubject(attrs);
|
|
178
193
|
certificate.setIssuer(attrs);
|
|
194
|
+
const altNames = [
|
|
195
|
+
{
|
|
196
|
+
type: 2,
|
|
197
|
+
value: CA_ALT_NAME
|
|
198
|
+
}
|
|
199
|
+
];
|
|
179
200
|
certificate.setExtensions([
|
|
201
|
+
{
|
|
202
|
+
name: 'basicConstraints',
|
|
203
|
+
cA: true,
|
|
204
|
+
pathLenConstraint: 0,
|
|
205
|
+
critical: true
|
|
206
|
+
},
|
|
180
207
|
{
|
|
181
208
|
name: 'subjectAltName',
|
|
182
|
-
altNames
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
209
|
+
altNames,
|
|
210
|
+
critical: true
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: 'issuerAltName',
|
|
214
|
+
altNames,
|
|
215
|
+
critical: true
|
|
188
216
|
},
|
|
189
217
|
{
|
|
190
218
|
name: 'keyUsage',
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
dataEncipherment: true
|
|
219
|
+
keyCertSign: true,
|
|
220
|
+
critical: true
|
|
194
221
|
},
|
|
195
222
|
{
|
|
196
223
|
name: 'extKeyUsage',
|
|
197
|
-
serverAuth: true
|
|
224
|
+
serverAuth: true,
|
|
225
|
+
critical: true
|
|
198
226
|
},
|
|
199
227
|
{
|
|
200
228
|
name: 'friendlyName',
|
|
@@ -203,18 +231,90 @@ class CertificateManager {
|
|
|
203
231
|
]);
|
|
204
232
|
// self-sign certificate
|
|
205
233
|
certificate.sign(keys.privateKey, forge.md.sha256.create());
|
|
234
|
+
return {
|
|
235
|
+
certificate,
|
|
236
|
+
privateKey: keys.privateKey
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
_createDevelopmentCertificate(options) {
|
|
240
|
+
const keys = forge.pki.rsa.generateKeyPair(2048);
|
|
241
|
+
const certificate = forge.pki.createCertificate();
|
|
242
|
+
certificate.publicKey = keys.publicKey;
|
|
243
|
+
certificate.serialNumber = TLS_SERIAL_NUMBER;
|
|
244
|
+
const { subjectAltNames: subjectNames, validityInDays } = options;
|
|
245
|
+
const { certificate: caCertificate, privateKey: caPrivateKey } = this._createCACertificate(validityInDays);
|
|
246
|
+
const now = new Date();
|
|
247
|
+
certificate.validity.notBefore = now;
|
|
248
|
+
certificate.validity.notAfter.setUTCDate(certificate.validity.notBefore.getUTCDate() + validityInDays);
|
|
249
|
+
const subjectAttrs = [
|
|
250
|
+
{
|
|
251
|
+
name: 'commonName',
|
|
252
|
+
value: subjectNames[0]
|
|
253
|
+
}
|
|
254
|
+
];
|
|
255
|
+
const issuerAttrs = caCertificate.subject.attributes;
|
|
256
|
+
certificate.setSubject(subjectAttrs);
|
|
257
|
+
certificate.setIssuer(issuerAttrs);
|
|
258
|
+
const subjectAltNames = subjectNames.map((subjectName) => ({
|
|
259
|
+
type: 2,
|
|
260
|
+
value: subjectName
|
|
261
|
+
}));
|
|
262
|
+
const issuerAltNames = [
|
|
263
|
+
{
|
|
264
|
+
type: 2,
|
|
265
|
+
value: CA_ALT_NAME
|
|
266
|
+
}
|
|
267
|
+
];
|
|
268
|
+
certificate.setExtensions([
|
|
269
|
+
{
|
|
270
|
+
name: 'basicConstraints',
|
|
271
|
+
cA: false,
|
|
272
|
+
critical: true
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
name: 'subjectAltName',
|
|
276
|
+
altNames: subjectAltNames,
|
|
277
|
+
critical: true
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
name: 'issuerAltName',
|
|
281
|
+
altNames: issuerAltNames,
|
|
282
|
+
critical: true
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
name: 'keyUsage',
|
|
286
|
+
digitalSignature: true,
|
|
287
|
+
keyEncipherment: true,
|
|
288
|
+
dataEncipherment: true,
|
|
289
|
+
critical: true
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
name: 'extKeyUsage',
|
|
293
|
+
serverAuth: true,
|
|
294
|
+
critical: true
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
name: 'friendlyName',
|
|
298
|
+
value: FRIENDLY_NAME
|
|
299
|
+
}
|
|
300
|
+
]);
|
|
301
|
+
// Sign certificate with CA
|
|
302
|
+
certificate.sign(caPrivateKey, forge.md.sha256.create());
|
|
206
303
|
// convert a Forge certificate to PEM
|
|
304
|
+
const caPem = forge.pki.certificateToPem(caCertificate);
|
|
207
305
|
const pem = forge.pki.certificateToPem(certificate);
|
|
208
306
|
const pemKey = forge.pki.privateKeyToPem(keys.privateKey);
|
|
209
307
|
return {
|
|
308
|
+
pemCaCertificate: caPem,
|
|
210
309
|
pemCertificate: pem,
|
|
211
|
-
pemKey: pemKey
|
|
310
|
+
pemKey: pemKey,
|
|
311
|
+
subjectAltNames: options.subjectAltNames
|
|
212
312
|
};
|
|
213
313
|
}
|
|
214
314
|
async _tryTrustCertificateAsync(certificatePath, terminal) {
|
|
215
315
|
switch (process.platform) {
|
|
216
316
|
case 'win32':
|
|
217
|
-
terminal.writeLine('Attempting to trust a development certificate. This self-signed certificate only points to localhost ' +
|
|
317
|
+
terminal.writeLine('Attempting to trust a development certificate. This self-signed certificate only points to rushstack.localhost ' +
|
|
218
318
|
'and will be stored in your local user profile to be used by other instances of ' +
|
|
219
319
|
'debug-certificate-manager. If you do not consent to trust this certificate, click "NO" in the dialog.');
|
|
220
320
|
const winTrustResult = await (0, runCommand_1.runAsync)(CERTUTIL_EXE_NAME, [
|
|
@@ -287,7 +387,7 @@ class CertificateManager {
|
|
|
287
387
|
'-user',
|
|
288
388
|
'-verifystore',
|
|
289
389
|
'root',
|
|
290
|
-
|
|
390
|
+
CA_SERIAL_NUMBER
|
|
291
391
|
]);
|
|
292
392
|
if (winVerifyStoreResult.code !== 0) {
|
|
293
393
|
terminal.writeVerboseLine('The development certificate was not found in the store. CertUtil error: ', winVerifyStoreResult.stderr.join(' '));
|
|
@@ -323,7 +423,7 @@ class CertificateManager {
|
|
|
323
423
|
terminal.writeVerboseLine('Automatic certificate trust validation is only implemented for debug-certificate-manager on Windows ' +
|
|
324
424
|
'and macOS. Manually verify this development certificate is present in your trusted ' +
|
|
325
425
|
`root certification authorities: "${this._certificateStore.certificatePath}". ` +
|
|
326
|
-
`The certificate has serial number "${
|
|
426
|
+
`The certificate has serial number "${CA_SERIAL_NUMBER}".`);
|
|
327
427
|
// Always return true on Linux to prevent breaking flow.
|
|
328
428
|
return true;
|
|
329
429
|
}
|
|
@@ -345,7 +445,7 @@ class CertificateManager {
|
|
|
345
445
|
'-repairstore',
|
|
346
446
|
'-user',
|
|
347
447
|
'root',
|
|
348
|
-
|
|
448
|
+
CA_SERIAL_NUMBER,
|
|
349
449
|
friendlyNamePath
|
|
350
450
|
]);
|
|
351
451
|
if (repairStoreResult.code !== 0) {
|
|
@@ -362,23 +462,25 @@ class CertificateManager {
|
|
|
362
462
|
return true;
|
|
363
463
|
}
|
|
364
464
|
}
|
|
365
|
-
async _ensureCertificateInternalAsync(terminal) {
|
|
465
|
+
async _ensureCertificateInternalAsync(options, terminal) {
|
|
366
466
|
const certificateStore = this._certificateStore;
|
|
367
|
-
const generatedCertificate = this._createDevelopmentCertificate();
|
|
368
|
-
const
|
|
369
|
-
const certificateName = now.getTime().toString();
|
|
467
|
+
const generatedCertificate = this._createDevelopmentCertificate(options);
|
|
468
|
+
const certificateName = Date.now().toString();
|
|
370
469
|
const tempDirName = path.join(__dirname, '..', 'temp');
|
|
371
470
|
const tempCertificatePath = path.join(tempDirName, `${certificateName}.pem`);
|
|
372
|
-
const pemFileContents = generatedCertificate.
|
|
471
|
+
const pemFileContents = generatedCertificate.pemCaCertificate;
|
|
373
472
|
if (pemFileContents) {
|
|
374
473
|
await node_core_library_1.FileSystem.writeFileAsync(tempCertificatePath, pemFileContents, {
|
|
375
474
|
ensureFolderExists: true
|
|
376
475
|
});
|
|
377
476
|
}
|
|
378
477
|
const trustCertificateResult = await this._tryTrustCertificateAsync(tempCertificatePath, terminal);
|
|
478
|
+
let subjectAltNames;
|
|
379
479
|
if (trustCertificateResult) {
|
|
480
|
+
certificateStore.caCertificateData = generatedCertificate.pemCaCertificate;
|
|
380
481
|
certificateStore.certificateData = generatedCertificate.pemCertificate;
|
|
381
482
|
certificateStore.keyData = generatedCertificate.pemKey;
|
|
483
|
+
subjectAltNames = generatedCertificate.subjectAltNames;
|
|
382
484
|
// Try to set the friendly name, and warn if we can't
|
|
383
485
|
if (!this._trySetFriendlyNameAsync(tempCertificatePath, terminal)) {
|
|
384
486
|
terminal.writeWarningLine("Unable to set the certificate's friendly name.");
|
|
@@ -386,18 +488,25 @@ class CertificateManager {
|
|
|
386
488
|
}
|
|
387
489
|
else {
|
|
388
490
|
// Clear out the existing store data, if any exists
|
|
491
|
+
certificateStore.caCertificateData = undefined;
|
|
389
492
|
certificateStore.certificateData = undefined;
|
|
390
493
|
certificateStore.keyData = undefined;
|
|
391
494
|
}
|
|
392
495
|
await node_core_library_1.FileSystem.deleteFileAsync(tempCertificatePath);
|
|
496
|
+
return {
|
|
497
|
+
pemCaCertificate: certificateStore.caCertificateData,
|
|
498
|
+
pemCertificate: certificateStore.certificateData,
|
|
499
|
+
pemKey: certificateStore.keyData,
|
|
500
|
+
subjectAltNames
|
|
501
|
+
};
|
|
393
502
|
}
|
|
394
|
-
|
|
503
|
+
_getCertificateSubjectAltName() {
|
|
395
504
|
const certificateData = this._certificateStore.certificateData;
|
|
396
505
|
if (!certificateData) {
|
|
397
|
-
return
|
|
506
|
+
return;
|
|
398
507
|
}
|
|
399
508
|
const certificate = forge.pki.certificateFromPem(certificateData);
|
|
400
|
-
return
|
|
509
|
+
return certificate.getExtension('subjectAltName');
|
|
401
510
|
}
|
|
402
511
|
_parseMacOsMatchingCertificateHash(findCertificateOuput) {
|
|
403
512
|
let shaHash = undefined;
|
|
@@ -408,11 +517,19 @@ class CertificateManager {
|
|
|
408
517
|
shaHash = shaHashMatch[1];
|
|
409
518
|
}
|
|
410
519
|
const snbrMatch = line.match(/^\s*"snbr"<blob>=0x([^\s]+).+$/);
|
|
411
|
-
if (snbrMatch && (snbrMatch[1] || '').toLowerCase() ===
|
|
520
|
+
if (snbrMatch && (snbrMatch[1] || '').toLowerCase() === CA_SERIAL_NUMBER) {
|
|
412
521
|
return shaHash;
|
|
413
522
|
}
|
|
414
523
|
}
|
|
415
524
|
}
|
|
416
525
|
}
|
|
417
526
|
exports.CertificateManager = CertificateManager;
|
|
527
|
+
function applyDefaultOptions(options) {
|
|
528
|
+
var _a;
|
|
529
|
+
const subjectNames = options === null || options === void 0 ? void 0 : options.subjectAltNames;
|
|
530
|
+
return {
|
|
531
|
+
subjectAltNames: (subjectNames === null || subjectNames === void 0 ? void 0 : subjectNames.length) ? subjectNames : exports.DEFAULT_CERTIFICATE_SUBJECT_NAMES,
|
|
532
|
+
validityInDays: (_a = options === null || options === void 0 ? void 0 : options.validityInDays) !== null && _a !== void 0 ? _a : 365 * 3
|
|
533
|
+
};
|
|
534
|
+
}
|
|
418
535
|
//# sourceMappingURL=CertificateManager.js.map
|
|
@@ -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, ITerminal, Import } from '@rushstack/node-core-library';\n\nimport { runSudoAsync, IRunResult, runAsync } from './runCommand';\nimport { CertificateStore } from './CertificateStore';\n\nconst forge: typeof import('node-forge') = Import.lazy('node-forge', require);\n\nconst SERIAL_NUMBER: string = '731c321744e34650a202e3ef91c3c1b0';\nconst FRIENDLY_NAME: string = 'debug-certificate-manager Development Certificate';\nconst MAC_KEYCHAIN: string = '/Library/Keychains/System.keychain';\nconst CERTUTIL_EXE_NAME: string = 'certutil';\n\n/**\n * The interface for a debug certificate instance\n *\n * @public\n */\nexport interface ICertificate {\n /**\n * Generated pem certificate contents\n */\n pemCertificate: string | undefined;\n\n /**\n * Private key used to sign the pem certificate\n */\n pemKey: string | undefined;\n}\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 ): Promise<ICertificate> {\n if (this._certificateStore.certificateData && this._certificateStore.keyData) {\n let invalidCertificate: boolean = false;\n const messages: string[] = [];\n\n if (!this._certificateHasSubjectAltName()) {\n invalidCertificate = true;\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 }\n\n if (!(await this._detectIfCertificateIsTrustedAsync(terminal))) {\n invalidCertificate = true;\n messages.push('The existing development certificate is not currently trusted by your system.');\n }\n\n if (invalidCertificate) {\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 await this._ensureCertificateInternalAsync(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 }\n } else if (canGenerateNewCertificate) {\n await this._ensureCertificateInternalAsync(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 return {\n pemCertificate: this._certificateStore.certificateData,\n pemKey: this._certificateStore.keyData\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 SERIAL_NUMBER\n ]);\n\n if (winUntrustResult.code !== 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.code !== 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.code === 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 \"${SERIAL_NUMBER}\".`\n );\n return false;\n }\n }\n\n private _createDevelopmentCertificate(): ICertificate {\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 = SERIAL_NUMBER;\n\n const now: Date = new Date();\n certificate.validity.notBefore = now;\n // Valid for 3 years\n certificate.validity.notAfter.setFullYear(certificate.validity.notBefore.getFullYear() + 3);\n\n const attrs: pki.CertificateField[] = [\n {\n name: 'commonName',\n value: 'localhost'\n }\n ];\n\n certificate.setSubject(attrs);\n certificate.setIssuer(attrs);\n\n certificate.setExtensions([\n {\n name: 'subjectAltName',\n altNames: [\n {\n type: 2, // DNS\n value: 'localhost'\n }\n ]\n },\n {\n name: 'keyUsage',\n digitalSignature: true,\n keyEncipherment: true,\n dataEncipherment: true\n },\n {\n name: 'extKeyUsage',\n serverAuth: 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 // convert a Forge certificate to PEM\n const pem: string = forge.pki.certificateToPem(certificate);\n const pemKey: string = forge.pki.privateKeyToPem(keys.privateKey);\n\n return {\n pemCertificate: pem,\n pemKey: pemKey\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.code !== 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.code === 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.code === 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.code}. ` +\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 SERIAL_NUMBER\n ]);\n\n if (winVerifyStoreResult.code !== 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.code !== 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 \"${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 SERIAL_NUMBER,\n friendlyNamePath\n ]);\n\n if (repairStoreResult.code !== 0) {\n terminal.writeErrorLine(`CertUtil Error: ${repairStoreResult.stderr.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(terminal: ITerminal): Promise<void> {\n const certificateStore: CertificateStore = this._certificateStore;\n const generatedCertificate: ICertificate = this._createDevelopmentCertificate();\n\n const now: Date = new Date();\n const certificateName: string = now.getTime().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.pemCertificate;\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 if (trustCertificateResult) {\n certificateStore.certificateData = generatedCertificate.pemCertificate;\n certificateStore.keyData = generatedCertificate.pemKey;\n\n // Try to set the friendly name, and warn if we can't\n if (!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.certificateData = undefined;\n certificateStore.keyData = undefined;\n }\n\n await FileSystem.deleteFileAsync(tempCertificatePath);\n }\n\n private _certificateHasSubjectAltName(): boolean {\n const certificateData: string | undefined = this._certificateStore.certificateData;\n if (!certificateData) {\n return false;\n }\n const certificate: pki.Certificate = forge.pki.certificateFromPem(certificateData);\n return !!certificate.getExtension('subjectAltName');\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() === SERIAL_NUMBER) {\n return shaHash;\n }\n }\n }\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, ITerminal, Import } from '@rushstack/node-core-library';\n\nimport { runSudoAsync, IRunResult, runAsync } from './runCommand';\nimport { CertificateStore } from './CertificateStore';\n\nconst forge: typeof import('node-forge') = Import.lazy('node-forge', require);\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';\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 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\ninterface IAltName {\n type: 2;\n value: string;\n}\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.\n */\n subjectAltNames?: ReadonlyArray<string>;\n /**\n * How many days the certificate should be valid for.\n */\n validityInDays?: number;\n}\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 if (this._certificateStore.certificateData && this._certificateStore.keyData) {\n const messages: string[] = [];\n\n const altNamesExtension: ISubjectAltNameExtension | undefined = this._getCertificateSubjectAltName();\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 }\n\n const hasCA: boolean = !!this._certificateStore.caCertificateData;\n if (!hasCA) {\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 (!altNamesExtension || !isTrusted || !hasCA) {\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: this._certificateStore.caCertificateData,\n pemCertificate: this._certificateStore.certificateData,\n pemKey: this._certificateStore.keyData,\n subjectAltNames: altNamesExtension.altNames.map((entry) => entry.value)\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.code !== 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.code !== 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.code === 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 _createCACertificate(validityInDays: number): 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 now: Date = new Date();\n certificate.validity.notBefore = now;\n certificate.validity.notAfter.setUTCDate(certificate.validity.notBefore.getUTCDate() + validityInDays);\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: true\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 _createDevelopmentCertificate(options: Required<ICertificateGenerationOptions>): ICertificate {\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, validityInDays } = options;\n\n const { certificate: caCertificate, privateKey: caPrivateKey } =\n this._createCACertificate(validityInDays);\n\n const now: Date = new Date();\n certificate.validity.notBefore = now;\n certificate.validity.notAfter.setUTCDate(certificate.validity.notBefore.getUTCDate() + validityInDays);\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: readonly IAltName[] = subjectNames.map((subjectName) => ({\n type: 2, // DNS\n value: subjectName\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: true\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 rushstack.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.code !== 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.code === 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.code === 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.code}. ` +\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.code !== 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.code !== 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.code !== 0) {\n terminal.writeErrorLine(`CertUtil Error: ${repairStoreResult.stderr.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 = this._createDevelopmentCertificate(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 (!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 _getCertificateSubjectAltName(): ISubjectAltNameExtension | undefined {\n const certificateData: string | undefined = this._certificateStore.certificateData;\n if (!certificateData) {\n return;\n }\n const certificate: pki.Certificate = forge.pki.certificateFromPem(certificateData);\n return certificate.getExtension('subjectAltName') as ISubjectAltNameExtension;\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 return {\n subjectAltNames: subjectNames?.length ? subjectNames : DEFAULT_CERTIFICATE_SUBJECT_NAMES,\n validityInDays: options?.validityInDays ?? 365 * 3\n };\n}\n"]}
|
|
@@ -3,19 +3,28 @@
|
|
|
3
3
|
* @public
|
|
4
4
|
*/
|
|
5
5
|
export declare class CertificateStore {
|
|
6
|
-
private
|
|
7
|
-
private
|
|
8
|
-
private
|
|
9
|
-
private
|
|
6
|
+
private readonly _caCertificatePath;
|
|
7
|
+
private readonly _certificatePath;
|
|
8
|
+
private readonly _keyPath;
|
|
9
|
+
private _caCertificateData;
|
|
10
10
|
private _certificateData;
|
|
11
11
|
private _keyData;
|
|
12
12
|
constructor();
|
|
13
13
|
/**
|
|
14
|
-
* Path to the saved debug certificate
|
|
14
|
+
* Path to the saved debug CA certificate
|
|
15
|
+
*/
|
|
16
|
+
get caCertificatePath(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Path to the saved debug TLS certificate
|
|
15
19
|
*/
|
|
16
20
|
get certificatePath(): string;
|
|
17
21
|
/**
|
|
18
|
-
* Debug certificate pem file contents.
|
|
22
|
+
* Debug Certificate Authority certificate pem file contents.
|
|
23
|
+
*/
|
|
24
|
+
get caCertificateData(): string | undefined;
|
|
25
|
+
set caCertificateData(certificate: string | undefined);
|
|
26
|
+
/**
|
|
27
|
+
* Debug TLS Server certificate pem file contents.
|
|
19
28
|
*/
|
|
20
29
|
get certificateData(): string | undefined;
|
|
21
30
|
set certificateData(certificate: string | undefined);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CertificateStore.d.ts","sourceRoot":"","sources":["../src/CertificateStore.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"CertificateStore.d.ts","sourceRoot":"","sources":["../src/CertificateStore.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAElC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAqB;;IAiBrC;;OAEG;IACH,IAAW,iBAAiB,IAAI,MAAM,CAErC;IAED;;OAEG;IACH,IAAW,eAAe,IAAI,MAAM,CAEnC;IAED;;OAEG;IACH,IAAW,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAYjD;IAED,IAAW,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAQ3D;IAED;;OAEG;IACH,IAAW,eAAe,IAAI,MAAM,GAAG,SAAS,CAY/C;IAED,IAAW,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAQzD;IAED;;OAEG;IACH,IAAW,OAAO,IAAI,MAAM,GAAG,SAAS,CAYvC;IAED,IAAW,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAQzC;CACF"}
|
package/lib/CertificateStore.js
CHANGED
|
@@ -36,31 +36,65 @@ const node_core_library_1 = require("@rushstack/node-core-library");
|
|
|
36
36
|
class CertificateStore {
|
|
37
37
|
constructor() {
|
|
38
38
|
const unresolvedUserFolder = (0, os_1.homedir)();
|
|
39
|
-
|
|
40
|
-
if (!node_core_library_1.FileSystem.exists(
|
|
39
|
+
const userProfilePath = path.resolve(unresolvedUserFolder);
|
|
40
|
+
if (!node_core_library_1.FileSystem.exists(userProfilePath)) {
|
|
41
41
|
throw new Error("Unable to determine the current user's home directory");
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
node_core_library_1.FileSystem.ensureFolder(
|
|
45
|
-
this.
|
|
46
|
-
this.
|
|
43
|
+
const serveDataPath = path.join(userProfilePath, '.rushstack');
|
|
44
|
+
node_core_library_1.FileSystem.ensureFolder(serveDataPath);
|
|
45
|
+
this._caCertificatePath = path.join(serveDataPath, 'rushstack-ca.pem');
|
|
46
|
+
this._certificatePath = path.join(serveDataPath, 'rushstack-serve.pem');
|
|
47
|
+
this._keyPath = path.join(serveDataPath, 'rushstack-serve.key');
|
|
47
48
|
}
|
|
48
49
|
/**
|
|
49
|
-
* Path to the saved debug certificate
|
|
50
|
+
* Path to the saved debug CA certificate
|
|
51
|
+
*/
|
|
52
|
+
get caCertificatePath() {
|
|
53
|
+
return this._caCertificatePath;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Path to the saved debug TLS certificate
|
|
50
57
|
*/
|
|
51
58
|
get certificatePath() {
|
|
52
59
|
return this._certificatePath;
|
|
53
60
|
}
|
|
54
61
|
/**
|
|
55
|
-
* Debug certificate pem file contents.
|
|
62
|
+
* Debug Certificate Authority certificate pem file contents.
|
|
63
|
+
*/
|
|
64
|
+
get caCertificateData() {
|
|
65
|
+
if (!this._caCertificateData) {
|
|
66
|
+
try {
|
|
67
|
+
this._caCertificateData = node_core_library_1.FileSystem.readFile(this._caCertificatePath);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
if (!node_core_library_1.FileSystem.isNotExistError(err)) {
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return this._caCertificateData;
|
|
76
|
+
}
|
|
77
|
+
set caCertificateData(certificate) {
|
|
78
|
+
if (certificate) {
|
|
79
|
+
node_core_library_1.FileSystem.writeFile(this._caCertificatePath, certificate);
|
|
80
|
+
}
|
|
81
|
+
else if (node_core_library_1.FileSystem.exists(this._caCertificatePath)) {
|
|
82
|
+
node_core_library_1.FileSystem.deleteFile(this._caCertificatePath);
|
|
83
|
+
}
|
|
84
|
+
this._caCertificateData = certificate;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Debug TLS Server certificate pem file contents.
|
|
56
88
|
*/
|
|
57
89
|
get certificateData() {
|
|
58
90
|
if (!this._certificateData) {
|
|
59
|
-
|
|
91
|
+
try {
|
|
60
92
|
this._certificateData = node_core_library_1.FileSystem.readFile(this._certificatePath);
|
|
61
93
|
}
|
|
62
|
-
|
|
63
|
-
|
|
94
|
+
catch (err) {
|
|
95
|
+
if (!node_core_library_1.FileSystem.isNotExistError(err)) {
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
64
98
|
}
|
|
65
99
|
}
|
|
66
100
|
return this._certificateData;
|
|
@@ -79,11 +113,13 @@ class CertificateStore {
|
|
|
79
113
|
*/
|
|
80
114
|
get keyData() {
|
|
81
115
|
if (!this._keyData) {
|
|
82
|
-
|
|
116
|
+
try {
|
|
83
117
|
this._keyData = node_core_library_1.FileSystem.readFile(this._keyPath);
|
|
84
118
|
}
|
|
85
|
-
|
|
86
|
-
|
|
119
|
+
catch (err) {
|
|
120
|
+
if (!node_core_library_1.FileSystem.isNotExistError(err)) {
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
87
123
|
}
|
|
88
124
|
}
|
|
89
125
|
return this._keyData;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CertificateStore.js","sourceRoot":"","sources":["../src/CertificateStore.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;AAE3D,2CAA6B;AAC7B,2BAA6B;AAE7B,oEAA0D;AAE1D;;;GAGG;AACH,MAAa,gBAAgB;IAS3B;QACE,MAAM,oBAAoB,GAAW,IAAA,YAAO,GAAE,CAAC;QAC/C,
|
|
1
|
+
{"version":3,"file":"CertificateStore.js","sourceRoot":"","sources":["../src/CertificateStore.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 * as path from 'path';\nimport { homedir } from 'os';\n\nimport { FileSystem } from '@rushstack/node-core-library';\n\n/**\n * Store to retrieve and save debug certificate data.\n * @public\n */\nexport class CertificateStore {\n private readonly _caCertificatePath: string;\n private readonly _certificatePath: string;\n private readonly _keyPath: string;\n\n private _caCertificateData: string | undefined;\n private _certificateData: string | undefined;\n private _keyData: string | undefined;\n\n public constructor() {\n const unresolvedUserFolder: string = homedir();\n const userProfilePath: string = path.resolve(unresolvedUserFolder);\n if (!FileSystem.exists(userProfilePath)) {\n throw new Error(\"Unable to determine the current user's home directory\");\n }\n\n const serveDataPath: string = path.join(userProfilePath, '.rushstack');\n FileSystem.ensureFolder(serveDataPath);\n\n this._caCertificatePath = path.join(serveDataPath, 'rushstack-ca.pem');\n this._certificatePath = path.join(serveDataPath, 'rushstack-serve.pem');\n this._keyPath = path.join(serveDataPath, 'rushstack-serve.key');\n }\n\n /**\n * Path to the saved debug CA certificate\n */\n public get caCertificatePath(): string {\n return this._caCertificatePath;\n }\n\n /**\n * Path to the saved debug TLS certificate\n */\n public get certificatePath(): string {\n return this._certificatePath;\n }\n\n /**\n * Debug Certificate Authority certificate pem file contents.\n */\n public get caCertificateData(): string | undefined {\n if (!this._caCertificateData) {\n try {\n this._caCertificateData = FileSystem.readFile(this._caCertificatePath);\n } catch (err) {\n if (!FileSystem.isNotExistError(err)) {\n throw err;\n }\n }\n }\n\n return this._caCertificateData;\n }\n\n public set caCertificateData(certificate: string | undefined) {\n if (certificate) {\n FileSystem.writeFile(this._caCertificatePath, certificate);\n } else if (FileSystem.exists(this._caCertificatePath)) {\n FileSystem.deleteFile(this._caCertificatePath);\n }\n\n this._caCertificateData = certificate;\n }\n\n /**\n * Debug TLS Server certificate pem file contents.\n */\n public get certificateData(): string | undefined {\n if (!this._certificateData) {\n try {\n this._certificateData = FileSystem.readFile(this._certificatePath);\n } catch (err) {\n if (!FileSystem.isNotExistError(err)) {\n throw err;\n }\n }\n }\n\n return this._certificateData;\n }\n\n public set certificateData(certificate: string | undefined) {\n if (certificate) {\n FileSystem.writeFile(this._certificatePath, certificate);\n } else if (FileSystem.exists(this._certificatePath)) {\n FileSystem.deleteFile(this._certificatePath);\n }\n\n this._certificateData = certificate;\n }\n\n /**\n * Key used to sign the debug pem certificate.\n */\n public get keyData(): string | undefined {\n if (!this._keyData) {\n try {\n this._keyData = FileSystem.readFile(this._keyPath);\n } catch (err) {\n if (!FileSystem.isNotExistError(err)) {\n throw err;\n }\n }\n }\n\n return this._keyData;\n }\n\n public set keyData(key: string | undefined) {\n if (key) {\n FileSystem.writeFile(this._keyPath, key);\n } else if (FileSystem.exists(this._keyPath)) {\n FileSystem.deleteFile(this._keyPath);\n }\n\n this._keyData = key;\n }\n}\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @packageDocumentation
|
|
14
14
|
*/
|
|
15
|
-
export { ICertificate, CertificateManager } from './CertificateManager';
|
|
15
|
+
export { ICertificate, CertificateManager, ICertificateGenerationOptions, DEFAULT_CERTIFICATE_SUBJECT_NAMES } from './CertificateManager';
|
|
16
16
|
export { CertificateStore } from './CertificateStore';
|
|
17
17
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,6BAA6B,EAC7B,iCAAiC,EAClC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
3
|
// See LICENSE in the project root for license information.
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.CertificateStore = exports.CertificateManager = void 0;
|
|
5
|
+
exports.CertificateStore = exports.DEFAULT_CERTIFICATE_SUBJECT_NAMES = exports.CertificateManager = void 0;
|
|
6
6
|
/**
|
|
7
7
|
* This package is used to manage debug certificates for development servers.
|
|
8
8
|
* It is used by
|
|
@@ -19,6 +19,7 @@ exports.CertificateStore = exports.CertificateManager = void 0;
|
|
|
19
19
|
*/
|
|
20
20
|
var CertificateManager_1 = require("./CertificateManager");
|
|
21
21
|
Object.defineProperty(exports, "CertificateManager", { enumerable: true, get: function () { return CertificateManager_1.CertificateManager; } });
|
|
22
|
+
Object.defineProperty(exports, "DEFAULT_CERTIFICATE_SUBJECT_NAMES", { enumerable: true, get: function () { return CertificateManager_1.DEFAULT_CERTIFICATE_SUBJECT_NAMES; } });
|
|
22
23
|
var CertificateStore_1 = require("./CertificateStore");
|
|
23
24
|
Object.defineProperty(exports, "CertificateStore", { enumerable: true, get: function () { return CertificateStore_1.CertificateStore; } });
|
|
24
25
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D;;;;;;;;;;;;;GAaG;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D;;;;;;;;;;;;;GAaG;AAEH,2DAK8B;AAH5B,wHAAA,kBAAkB,OAAA;AAElB,uIAAA,iCAAiC,OAAA;AAEnC,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * This package is used to manage debug certificates for development servers.\n * It is used by\n * [\\@microsoft/gulp-core-build-serve](https://www.npmjs.com/package/\\@microsoft/gulp-core-build-serve)\n * to generate and trust a certificate when HTTPS is turned on.\n *\n * This package provides the following utilities:\n * - `CertificateStore` to handle retrieving and saving a debug certificate.\n * - `CertificateManager` is a utility class containing the following public methods:\n * | - `ensureCertificate` will find or optionally create a debug certificate and trust it.\n * | - `untrustCertificate` will untrust a debug certificate.\n *\n * @packageDocumentation\n */\n\nexport {\n ICertificate,\n CertificateManager,\n ICertificateGenerationOptions,\n DEFAULT_CERTIFICATE_SUBJECT_NAMES\n} from './CertificateManager';\nexport { CertificateStore } from './CertificateStore';\n"]}
|
package/package.json
CHANGED