node-opcua-pki 6.21.0 → 6.22.1
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/bin/pki.mjs +159 -18
- package/dist/bin/pki.mjs.map +1 -1
- package/dist/{chunk-2HTNH73K.mjs → chunk-EQ4DGI4M.mjs} +5 -1
- package/dist/chunk-EQ4DGI4M.mjs.map +1 -0
- package/dist/{core-C6faZClF.d.mts → core-BwqSJPHc.d.mts} +19 -10
- package/dist/{core-C6faZClF.d.ts → core-BwqSJPHc.d.ts} +19 -10
- package/dist/core.d.mts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +1 -1
- package/dist/index.d.mts +51 -5
- package/dist/index.d.ts +51 -5
- package/dist/index.js +164 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +165 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-2HTNH73K.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -13,16 +13,20 @@ import {
|
|
|
13
13
|
ensurePrivateDirectory,
|
|
14
14
|
g_config,
|
|
15
15
|
isEncryptedPrivateKeyFile,
|
|
16
|
+
isOpaqueSigner,
|
|
16
17
|
makePath,
|
|
17
18
|
mkdirRecursiveSync,
|
|
18
19
|
quote,
|
|
19
20
|
resolvePrivateKeyPassphrase,
|
|
20
21
|
restrictPrivateFilePermissions,
|
|
21
22
|
warningLog
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-EQ4DGI4M.mjs";
|
|
23
24
|
|
|
24
25
|
// packages/node-opcua-pki/lib/index.ts
|
|
25
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
PrivateKeyPassphraseRequiredError,
|
|
28
|
+
PrivateKeyUnavailableError as PrivateKeyUnavailableError2
|
|
29
|
+
} from "node-opcua-crypto";
|
|
26
30
|
|
|
27
31
|
// packages/node-opcua-pki/lib/ca/backends/openssl_ca_backend.ts
|
|
28
32
|
import fs4 from "fs";
|
|
@@ -407,8 +411,32 @@ function passinArg(passphrase = "") {
|
|
|
407
411
|
function renderForDisplay(file, args) {
|
|
408
412
|
return [file, ...args].map((a) => a === "" || /[\s"'`$\\]/.test(a) ? JSON.stringify(a) : a).join(" ");
|
|
409
413
|
}
|
|
414
|
+
function hasUnsafeArgChar(value) {
|
|
415
|
+
for (const ch of value) {
|
|
416
|
+
const code = ch.codePointAt(0);
|
|
417
|
+
if (code < 32 || code === 127) {
|
|
418
|
+
return true;
|
|
419
|
+
}
|
|
420
|
+
if (code < 128) {
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
if (/[\p{L}\p{N}\p{M}]/u.test(ch)) {
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
return true;
|
|
427
|
+
}
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
function checkArgs(file, args) {
|
|
431
|
+
for (const value of [file, ...args]) {
|
|
432
|
+
if (typeof value === "string" && hasUnsafeArgChar(value)) {
|
|
433
|
+
throw new Error(`execute_openssl: refusing argument with an unexpected character: ${JSON.stringify(value)}`);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
410
437
|
async function execute2(file, args, options) {
|
|
411
438
|
const from = new Error();
|
|
439
|
+
checkArgs(file, args);
|
|
412
440
|
options.cwd = options.cwd || process.cwd();
|
|
413
441
|
if (!g_config.silent) {
|
|
414
442
|
warningLog(chalk2.cyan(" CWD "), options.cwd);
|
|
@@ -975,11 +1003,14 @@ import { drainPendingLocks, withLock } from "@ster5/global-mutex";
|
|
|
975
1003
|
import chalk3 from "chalk";
|
|
976
1004
|
import chokidar from "chokidar";
|
|
977
1005
|
import {
|
|
1006
|
+
caSignerFromKeyOperations,
|
|
978
1007
|
exploreCertificate,
|
|
979
1008
|
exploreCertificateInfo,
|
|
980
1009
|
exploreCertificateRevocationList,
|
|
981
1010
|
generatePrivateKeyFile,
|
|
1011
|
+
keyOperationsFromPrivateKey,
|
|
982
1012
|
makeSHA1Thumbprint,
|
|
1013
|
+
PrivateKeyUnavailableError,
|
|
983
1014
|
readCertificateChain,
|
|
984
1015
|
readCertificateChainAsync,
|
|
985
1016
|
readCertificateRevocationList,
|
|
@@ -1006,8 +1037,9 @@ async function createCertificateSigningRequestAsync(certificateSigningRequestFil
|
|
|
1006
1037
|
assert3(typeof certificateSigningRequestFilename === "string");
|
|
1007
1038
|
const subject = params.subject ? new Subject3(params.subject).toString() : void 0;
|
|
1008
1039
|
displaySubtitle("- Creating a Certificate Signing Request with subtile");
|
|
1009
|
-
const
|
|
1010
|
-
|
|
1040
|
+
const privateKey = isOpaqueSigner(params.privateKey) ? params.privateKey : await pemToPrivateKey(
|
|
1041
|
+
typeof params.privateKey === "string" ? await fs5.promises.readFile(params.privateKey, "utf-8") : coercePrivateKeyPem(params.privateKey)
|
|
1042
|
+
);
|
|
1011
1043
|
const { csr } = await createCertificateSigningRequest({
|
|
1012
1044
|
privateKey,
|
|
1013
1045
|
dns: params.dns,
|
|
@@ -1017,7 +1049,9 @@ async function createCertificateSigningRequestAsync(certificateSigningRequestFil
|
|
|
1017
1049
|
purpose: params.purpose
|
|
1018
1050
|
});
|
|
1019
1051
|
await fs5.promises.writeFile(certificateSigningRequestFilename, csr, "utf-8");
|
|
1020
|
-
display(
|
|
1052
|
+
display(
|
|
1053
|
+
`- privateKey ${typeof params.privateKey === "string" ? params.privateKey : isOpaqueSigner(params.privateKey) ? "<opaque-signer>" : "<in-memory>"}`
|
|
1054
|
+
);
|
|
1021
1055
|
display(`- certificateSigningRequestFilename ${certificateSigningRequestFilename}`);
|
|
1022
1056
|
}
|
|
1023
1057
|
|
|
@@ -1050,8 +1084,9 @@ async function createSelfSignedCertificateAsync(certificate, params) {
|
|
|
1050
1084
|
subject = subject.toString();
|
|
1051
1085
|
const purpose = params.purpose;
|
|
1052
1086
|
displayTitle("Generate a certificate request");
|
|
1053
|
-
const
|
|
1054
|
-
|
|
1087
|
+
const privateKey = isOpaqueSigner(params.privateKey) ? params.privateKey : await pemToPrivateKey2(
|
|
1088
|
+
typeof params.privateKey === "string" ? await fs6.promises.readFile(params.privateKey, "utf-8") : coercePrivateKeyPem2(params.privateKey)
|
|
1089
|
+
);
|
|
1055
1090
|
const { cert } = await createSelfSignedCertificate1({
|
|
1056
1091
|
privateKey,
|
|
1057
1092
|
notBefore: params.startDate,
|
|
@@ -1117,18 +1152,31 @@ function makeFingerprint(certificate) {
|
|
|
1117
1152
|
function short(stringToShorten) {
|
|
1118
1153
|
return stringToShorten.substring(0, 10);
|
|
1119
1154
|
}
|
|
1120
|
-
var
|
|
1155
|
+
var disallowedInLabel = /[^A-Za-z0-9._ -]/g;
|
|
1156
|
+
function toFilenameLabel(commonName) {
|
|
1157
|
+
const label = (commonName || "").normalize("NFKC").replace(disallowedInLabel, "_").replace(/[^\x20-\x7E]/g, "").slice(0, 64).trim();
|
|
1158
|
+
return label || "certificate";
|
|
1159
|
+
}
|
|
1121
1160
|
function buildIdealCertificateName(certificate) {
|
|
1122
1161
|
const chain = coerceCertificateChain(certificate);
|
|
1123
1162
|
const fingerprint = makeFingerprint(chain);
|
|
1124
1163
|
try {
|
|
1125
1164
|
const commonName = exploreCertificate(chain[0]).tbsCertificate.subject.commonName || "";
|
|
1126
|
-
const sanitizedCommonName = commonName
|
|
1165
|
+
const sanitizedCommonName = toFilenameLabel(commonName);
|
|
1127
1166
|
return `${sanitizedCommonName}[${fingerprint}]`;
|
|
1128
1167
|
} catch (_err) {
|
|
1129
1168
|
return `invalid_certificate_[${fingerprint}]`;
|
|
1130
1169
|
}
|
|
1131
1170
|
}
|
|
1171
|
+
function safeStoreJoin(folder, filename) {
|
|
1172
|
+
const full = path4.resolve(folder, filename);
|
|
1173
|
+
const base = path4.resolve(folder);
|
|
1174
|
+
if (full !== base && !full.startsWith(base + path4.sep)) {
|
|
1175
|
+
warningLog("refusing to write certificate outside its store folder:", filename);
|
|
1176
|
+
throw new Error(`certificate filename escapes its store folder: ${filename}`);
|
|
1177
|
+
}
|
|
1178
|
+
return full;
|
|
1179
|
+
}
|
|
1132
1180
|
function findMatchingIssuerKey(entries, wantedIssuerKey) {
|
|
1133
1181
|
return entries.filter((entry) => {
|
|
1134
1182
|
const info = getOrComputeInfo(entry);
|
|
@@ -1356,6 +1404,9 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
1356
1404
|
#disableFileWatchers;
|
|
1357
1405
|
#privateKeyPassphrase;
|
|
1358
1406
|
#privateKeyProvider;
|
|
1407
|
+
#keyOperations;
|
|
1408
|
+
/** The stable lazy wrap handed out by {@link getKeyOperations} for non-opaque configurations. */
|
|
1409
|
+
#lazyLocalKeyOperations;
|
|
1359
1410
|
/**
|
|
1360
1411
|
* The on-disk key, decrypted once and kept for the instance's lifetime,
|
|
1361
1412
|
* so the passphrase (or its resolver function) is consulted at most
|
|
@@ -1399,6 +1450,17 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
1399
1450
|
this.#disableFileWatchers = options.disableFileWatchers ?? process.env.OPCUA_PKI_DISABLE_FILE_WATCHERS === "true";
|
|
1400
1451
|
this.#privateKeyPassphrase = options.privateKeyPassphrase;
|
|
1401
1452
|
this.#privateKeyProvider = options.privateKeyProvider;
|
|
1453
|
+
this.#keyOperations = options.keyOperations;
|
|
1454
|
+
if (this.#keyOperations && this.#privateKeyProvider) {
|
|
1455
|
+
throw new Error(
|
|
1456
|
+
"CertificateManager: 'keyOperations' and 'privateKeyProvider' are mutually exclusive: one hides the key, the other sources its material"
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
if (this.#keyOperations && this.#privateKeyPassphrase) {
|
|
1460
|
+
throw new Error(
|
|
1461
|
+
"CertificateManager: 'privateKeyPassphrase' is meaningless with 'keyOperations': there is no key material for a passphrase to protect"
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1402
1464
|
mkdirRecursiveSync(options.location);
|
|
1403
1465
|
if (!fs7.existsSync(this.#location)) {
|
|
1404
1466
|
throw new Error(`CertificateManager cannot access location ${this.#location}`);
|
|
@@ -1440,6 +1502,11 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
1440
1502
|
* authority on what the current key is.
|
|
1441
1503
|
*/
|
|
1442
1504
|
async getPrivateKey() {
|
|
1505
|
+
if (this.#keyOperations) {
|
|
1506
|
+
throw new PrivateKeyUnavailableError(
|
|
1507
|
+
"CertificateManager.getPrivateKey is not available when keyOperations is configured: the private key is held by the key-operations provider (HSM/KMS) and cannot be read \u2014 use getKeyOperations() instead"
|
|
1508
|
+
);
|
|
1509
|
+
}
|
|
1443
1510
|
if (this.#privateKeyProvider) {
|
|
1444
1511
|
return await this.#privateKeyProvider.getPrivateKey();
|
|
1445
1512
|
}
|
|
@@ -1465,6 +1532,75 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
1465
1532
|
}
|
|
1466
1533
|
/** In-flight first read of the on-disk key, so concurrent callers share one passphrase resolution. */
|
|
1467
1534
|
#privateKeyPromise;
|
|
1535
|
+
/**
|
|
1536
|
+
* True when this manager's key is opaque — configured through
|
|
1537
|
+
* `keyOperations`, held by an HSM/KMS, never obtainable as material.
|
|
1538
|
+
* When true, {@link getPrivateKey} throws `PrivateKeyUnavailableError`
|
|
1539
|
+
* and {@link getKeyOperations} is the only way to use the key.
|
|
1540
|
+
*/
|
|
1541
|
+
isPrivateKeyOpaque() {
|
|
1542
|
+
return !!this.#keyOperations;
|
|
1543
|
+
}
|
|
1544
|
+
/**
|
|
1545
|
+
* The key as an opaque {@link IKeyOperations} — the recommended way to
|
|
1546
|
+
* *use* the private key regardless of where it lives.
|
|
1547
|
+
*
|
|
1548
|
+
* Returns the configured `keyOperations` object when the key is opaque.
|
|
1549
|
+
* Otherwise returns a stable lazy wrap over {@link getPrivateKey}: its
|
|
1550
|
+
* methods resolve the key on first use (disk read, passphrase,
|
|
1551
|
+
* `privateKeyProvider` — all async), so the wrap offers no synchronous
|
|
1552
|
+
* fast path; callers that need one resolve the key themselves and build
|
|
1553
|
+
* a `LocalKeyOperations` over it. The wrap follows key rotation: a
|
|
1554
|
+
* `privateKeyProvider` that starts returning a different key gets a
|
|
1555
|
+
* fresh underlying `LocalKeyOperations`.
|
|
1556
|
+
*/
|
|
1557
|
+
getKeyOperations() {
|
|
1558
|
+
if (this.#keyOperations) {
|
|
1559
|
+
return this.#keyOperations;
|
|
1560
|
+
}
|
|
1561
|
+
if (!this.#lazyLocalKeyOperations) {
|
|
1562
|
+
let cached;
|
|
1563
|
+
const resolve = async () => {
|
|
1564
|
+
const key = await this.getPrivateKey();
|
|
1565
|
+
if (!cached || cached.key !== key) {
|
|
1566
|
+
cached = { key, ops: keyOperationsFromPrivateKey(key) };
|
|
1567
|
+
}
|
|
1568
|
+
return cached.ops;
|
|
1569
|
+
};
|
|
1570
|
+
this.#lazyLocalKeyOperations = {
|
|
1571
|
+
sign: async (data, params) => (await resolve()).sign(data, params),
|
|
1572
|
+
decryptBlock: async (block, params) => (await resolve()).decryptBlock(block, params),
|
|
1573
|
+
getKeyMetadata: async () => (await resolve()).getKeyMetadata(),
|
|
1574
|
+
getPublicKey: async () => (await resolve()).getPublicKey()
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
return this.#lazyLocalKeyOperations;
|
|
1578
|
+
}
|
|
1579
|
+
/**
|
|
1580
|
+
* Fail closed at `initialize()` time, not on the first certificate
|
|
1581
|
+
* operation, if the key cannot actually be used: wrong/missing
|
|
1582
|
+
* passphrase on an encrypted key, a broken `privateKeyProvider`, or an
|
|
1583
|
+
* unreachable `keyOperations` provider (probed via `getKeyMetadata`).
|
|
1584
|
+
*/
|
|
1585
|
+
async #probePrivateKey() {
|
|
1586
|
+
if (this.#keyOperations) {
|
|
1587
|
+
await this.#keyOperations.getKeyMetadata();
|
|
1588
|
+
return;
|
|
1589
|
+
}
|
|
1590
|
+
await this.getPrivateKey();
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* The key to hand to a certificate-issuance primitive: the raw
|
|
1594
|
+
* {@link PrivateKey} for a local configuration, or a {@link CaSigner}
|
|
1595
|
+
* adapted from `keyOperations` when the key is opaque — which requires
|
|
1596
|
+
* the provider to implement `getPublicKey` (the adapter says so if not).
|
|
1597
|
+
*/
|
|
1598
|
+
async #resolveSigningKey() {
|
|
1599
|
+
if (this.#keyOperations) {
|
|
1600
|
+
return caSignerFromKeyOperations(this.#keyOperations);
|
|
1601
|
+
}
|
|
1602
|
+
return await this.getPrivateKey();
|
|
1603
|
+
}
|
|
1468
1604
|
/**
|
|
1469
1605
|
* Enable, disable, or rotate the passphrase protecting the on-disk
|
|
1470
1606
|
* private key: decrypt with `oldPassphrase` (omit if the key is
|
|
@@ -1486,6 +1622,11 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
1486
1622
|
* disk file for this method to rewrite).
|
|
1487
1623
|
*/
|
|
1488
1624
|
async reencryptPrivateKey(oldPassphrase, newPassphrase) {
|
|
1625
|
+
if (this.#keyOperations) {
|
|
1626
|
+
throw new PrivateKeyUnavailableError(
|
|
1627
|
+
"reencryptPrivateKey: not supported when keyOperations is configured \u2014 there is no key material to rewrite"
|
|
1628
|
+
);
|
|
1629
|
+
}
|
|
1489
1630
|
if (this.#privateKeyProvider) {
|
|
1490
1631
|
throw new Error("reencryptPrivateKey: not supported when a privateKeyProvider is configured");
|
|
1491
1632
|
}
|
|
@@ -1611,7 +1752,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
1611
1752
|
} catch (_err) {
|
|
1612
1753
|
return "BadCertificateInvalid";
|
|
1613
1754
|
}
|
|
1614
|
-
const filename =
|
|
1755
|
+
const filename = safeStoreJoin(this.rejectedFolder, `${buildIdealCertificateName(leafCertificate)}.pem`);
|
|
1615
1756
|
debugLog("certificate has never been seen before and is now rejected (untrusted) ", filename);
|
|
1616
1757
|
await fsWriteFile(filename, toPem(chain, "CERTIFICATE"));
|
|
1617
1758
|
this.#thumbs.rejected.set(fingerprint, { certificate: leafCertificate, filename });
|
|
@@ -1834,7 +1975,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
1834
1975
|
mkdirRecursiveSync(path4.join(pkiDir, "issuers"));
|
|
1835
1976
|
mkdirRecursiveSync(path4.join(pkiDir, "issuers/certs"));
|
|
1836
1977
|
mkdirRecursiveSync(path4.join(pkiDir, "issuers/crl"));
|
|
1837
|
-
const ownsDiskKey = !this.#privateKeyProvider;
|
|
1978
|
+
const ownsDiskKey = !this.#privateKeyProvider && !this.#keyOperations;
|
|
1838
1979
|
const needsKeyGeneration = ownsDiskKey && !fs7.existsSync(this.privateKey);
|
|
1839
1980
|
const needsKeyEncryption = ownsDiskKey && !needsKeyGeneration && this.#privateKeyPassphrase !== void 0 && !isEncryptedPrivateKeyFile(this.privateKey);
|
|
1840
1981
|
if (!fs7.existsSync(this.configFile) || needsKeyGeneration || needsKeyEncryption) {
|
|
@@ -1860,14 +2001,14 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
1860
2001
|
if (ownsDiskKey) {
|
|
1861
2002
|
restrictPrivateFilePermissions(this.privateKey, 384);
|
|
1862
2003
|
}
|
|
1863
|
-
await this
|
|
2004
|
+
await this.#probePrivateKey();
|
|
1864
2005
|
await this.#readCertificates();
|
|
1865
2006
|
});
|
|
1866
2007
|
} else {
|
|
1867
2008
|
if (ownsDiskKey) {
|
|
1868
2009
|
restrictPrivateFilePermissions(this.privateKey, 384);
|
|
1869
2010
|
}
|
|
1870
|
-
await this
|
|
2011
|
+
await this.#probePrivateKey();
|
|
1871
2012
|
await this.#readCertificates();
|
|
1872
2013
|
}
|
|
1873
2014
|
}
|
|
@@ -1952,7 +2093,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
1952
2093
|
if (typeof params.applicationUri !== "string") {
|
|
1953
2094
|
throw new Error("createSelfSignedCertificate: expecting applicationUri to be a string");
|
|
1954
2095
|
}
|
|
1955
|
-
if (!this.#privateKeyProvider && !fs7.existsSync(this.privateKey)) {
|
|
2096
|
+
if (!this.#privateKeyProvider && !this.#keyOperations && !fs7.existsSync(this.privateKey)) {
|
|
1956
2097
|
throw new Error(`Cannot find private key ${this.privateKey}`);
|
|
1957
2098
|
}
|
|
1958
2099
|
let certificateFilename = path4.join(this.rootDir, "own/certs/self_signed_certificate.pem");
|
|
@@ -1961,7 +2102,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
1961
2102
|
...params,
|
|
1962
2103
|
rootDir: this.rootDir,
|
|
1963
2104
|
configFile: this.configFile,
|
|
1964
|
-
privateKey: await this
|
|
2105
|
+
privateKey: await this.#resolveSigningKey(),
|
|
1965
2106
|
subject: params.subject || "CN=FIXME"
|
|
1966
2107
|
};
|
|
1967
2108
|
await this.withLock2(async () => {
|
|
@@ -1989,7 +2130,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
1989
2130
|
...params,
|
|
1990
2131
|
rootDir: path4.resolve(this.rootDir),
|
|
1991
2132
|
configFile: path4.resolve(this.configFile),
|
|
1992
|
-
privateKey: await this
|
|
2133
|
+
privateKey: await this.#resolveSigningKey()
|
|
1993
2134
|
};
|
|
1994
2135
|
return await this.withLock2(async () => {
|
|
1995
2136
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -2019,7 +2160,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
2019
2160
|
if (this.#thumbs.issuers.certs.has(fingerprint)) {
|
|
2020
2161
|
return "Good" /* Good */;
|
|
2021
2162
|
}
|
|
2022
|
-
const filename =
|
|
2163
|
+
const filename = safeStoreJoin(this.issuersCertFolder, `issuer_${buildIdealCertificateName(certificate)}.pem`);
|
|
2023
2164
|
await fs7.promises.writeFile(filename, pemCertificate, "ascii");
|
|
2024
2165
|
this.#thumbs.issuers.certs.set(fingerprint, { certificate, filename });
|
|
2025
2166
|
if (addInTrustList) {
|
|
@@ -2478,7 +2619,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
2478
2619
|
let status = await this.#checkRejectedOrTrusted(certificate);
|
|
2479
2620
|
if (status === "unknown") {
|
|
2480
2621
|
const pem = toPem(chain, "CERTIFICATE");
|
|
2481
|
-
const filename =
|
|
2622
|
+
const filename = safeStoreJoin(this.rejectedFolder, `${buildIdealCertificateName(certificate)}.pem`);
|
|
2482
2623
|
await fs7.promises.writeFile(filename, pem);
|
|
2483
2624
|
this.#thumbs.rejected.set(fingerprint, { certificate, filename });
|
|
2484
2625
|
status = "rejected";
|
|
@@ -2495,7 +2636,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
2495
2636
|
throw new Error(`#moveCertificate: certificate ${fingerprint.substring(0, 10)} not found in ${status} index`);
|
|
2496
2637
|
}
|
|
2497
2638
|
const destFolder = newStatus === "trusted" ? this.trustedFolder : this.rejectedFolder;
|
|
2498
|
-
const certificateDest =
|
|
2639
|
+
const certificateDest = safeStoreJoin(destFolder, path4.basename(srcEntry.filename));
|
|
2499
2640
|
debugLog("#moveCertificate", fingerprint.substring(0, 10), "old name", srcEntry.filename);
|
|
2500
2641
|
debugLog("#moveCertificate", fingerprint.substring(0, 10), "new name", certificateDest);
|
|
2501
2642
|
await fs7.promises.rename(srcEntry.filename, certificateDest);
|
|
@@ -2976,6 +3117,7 @@ export {
|
|
|
2976
3117
|
NativeCaBackend,
|
|
2977
3118
|
OpenSslCaBackend,
|
|
2978
3119
|
PrivateKeyPassphraseRequiredError,
|
|
3120
|
+
PrivateKeyUnavailableError2 as PrivateKeyUnavailableError,
|
|
2979
3121
|
Subject,
|
|
2980
3122
|
VerificationStatus,
|
|
2981
3123
|
adjustApplicationUri,
|
|
@@ -2992,9 +3134,12 @@ export {
|
|
|
2992
3134
|
install_prerequisite,
|
|
2993
3135
|
isIntermediateIssuer,
|
|
2994
3136
|
isIssuer,
|
|
3137
|
+
isOpaqueSigner,
|
|
2995
3138
|
isRootIssuer,
|
|
2996
3139
|
makeFingerprint,
|
|
2997
3140
|
quote,
|
|
2998
|
-
resolvePrivateKeyPassphrase
|
|
3141
|
+
resolvePrivateKeyPassphrase,
|
|
3142
|
+
safeStoreJoin,
|
|
3143
|
+
toFilenameLabel
|
|
2999
3144
|
};
|
|
3000
3145
|
//# sourceMappingURL=index.mjs.map
|