node-opcua-pki 6.22.1 → 7.0.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.
Files changed (138) hide show
  1. package/bin/install_prerequisite.ts +1 -1
  2. package/bin/pki.ts +1 -1
  3. package/bin/pki_config.example.js +0 -1
  4. package/dist/bin/install_prerequisite.d.ts +2 -0
  5. package/dist/bin/install_prerequisite.js +6 -0
  6. package/dist/bin/install_prerequisite.js.map +1 -0
  7. package/dist/bin/pki.d.ts +2 -0
  8. package/dist/bin/pki.js +4 -0
  9. package/dist/bin/pki.js.map +1 -0
  10. package/dist/lib/ca/backends/native_ca_backend.d.ts +49 -0
  11. package/dist/lib/ca/backends/native_ca_backend.js +365 -0
  12. package/dist/lib/ca/backends/native_ca_backend.js.map +1 -0
  13. package/dist/lib/ca/backends/openssl_ca_backend.d.ts +47 -0
  14. package/dist/lib/ca/backends/openssl_ca_backend.js +398 -0
  15. package/dist/lib/ca/backends/openssl_ca_backend.js.map +1 -0
  16. package/dist/lib/ca/certificate_authority.d.ts +62 -0
  17. package/dist/lib/ca/certificate_authority.js +91 -0
  18. package/dist/lib/ca/certificate_authority.js.map +1 -0
  19. package/dist/lib/ca/core/ca_backend.d.ts +89 -0
  20. package/dist/lib/ca/core/ca_backend.js +24 -0
  21. package/dist/lib/ca/core/ca_backend.js.map +1 -0
  22. package/dist/lib/ca/core/ca_database.d.ts +91 -0
  23. package/dist/lib/ca/core/ca_database.js +267 -0
  24. package/dist/lib/ca/core/ca_database.js.map +1 -0
  25. package/dist/{core-BwqSJPHc.d.mts → lib/ca/core/certificate_authority_core.d.ts} +45 -394
  26. package/dist/lib/ca/core/certificate_authority_core.js +1300 -0
  27. package/dist/lib/ca/core/certificate_authority_core.js.map +1 -0
  28. package/dist/lib/ca/core/index.d.ts +17 -0
  29. package/dist/lib/ca/core/index.js +25 -0
  30. package/dist/lib/ca/core/index.js.map +1 -0
  31. package/dist/lib/ca/crypto_create_CA.d.ts +1 -0
  32. package/dist/lib/ca/crypto_create_CA.js +821 -0
  33. package/dist/lib/ca/crypto_create_CA.js.map +1 -0
  34. package/dist/lib/ca/index.d.ts +1 -0
  35. package/dist/lib/ca/index.js +2 -0
  36. package/dist/lib/ca/index.js.map +1 -0
  37. package/dist/lib/ca/templates/ca_config_template.cnf.d.ts +2 -0
  38. package/dist/lib/ca/templates/ca_config_template.cnf.js +170 -0
  39. package/dist/lib/ca/templates/ca_config_template.cnf.js.map +1 -0
  40. package/dist/lib/core.d.ts +33 -0
  41. package/dist/lib/core.js +56 -0
  42. package/dist/lib/core.js.map +1 -0
  43. package/dist/lib/index.d.ts +11 -0
  44. package/dist/lib/index.js +37 -0
  45. package/dist/lib/index.js.map +1 -0
  46. package/dist/lib/misc/applicationurn.d.ts +1 -0
  47. package/dist/lib/misc/applicationurn.js +40 -0
  48. package/dist/lib/misc/applicationurn.js.map +1 -0
  49. package/dist/lib/misc/hostname.d.ts +8 -0
  50. package/dist/lib/misc/hostname.js +82 -0
  51. package/dist/lib/misc/hostname.js.map +1 -0
  52. package/dist/lib/misc/subject.d.ts +2 -0
  53. package/dist/lib/misc/subject.js +2 -0
  54. package/dist/lib/misc/subject.js.map +1 -0
  55. package/dist/{index.d.ts → lib/pki/certificate_manager.d.ts} +24 -248
  56. package/dist/lib/pki/certificate_manager.js +2302 -0
  57. package/dist/lib/pki/certificate_manager.js.map +1 -0
  58. package/dist/lib/pki/templates/simple_config_template.cnf.d.ts +2 -0
  59. package/dist/lib/pki/templates/simple_config_template.cnf.js +74 -0
  60. package/dist/lib/pki/templates/simple_config_template.cnf.js.map +1 -0
  61. package/dist/lib/pki/toolbox_pfx.d.ts +127 -0
  62. package/dist/lib/pki/toolbox_pfx.js +248 -0
  63. package/dist/lib/pki/toolbox_pfx.js.map +1 -0
  64. package/dist/lib/toolbox/common.d.ts +150 -0
  65. package/dist/lib/toolbox/common.js +82 -0
  66. package/dist/lib/toolbox/common.js.map +1 -0
  67. package/dist/lib/toolbox/common2.d.ts +25 -0
  68. package/dist/lib/toolbox/common2.js +97 -0
  69. package/dist/lib/toolbox/common2.js.map +1 -0
  70. package/dist/lib/toolbox/config.d.ts +5 -0
  71. package/dist/lib/toolbox/config.js +28 -0
  72. package/dist/lib/toolbox/config.js.map +1 -0
  73. package/dist/lib/toolbox/debug.d.ts +5 -0
  74. package/dist/lib/toolbox/debug.js +35 -0
  75. package/dist/lib/toolbox/debug.js.map +1 -0
  76. package/dist/lib/toolbox/display.d.ts +4 -0
  77. package/dist/lib/toolbox/display.js +56 -0
  78. package/dist/lib/toolbox/display.js.map +1 -0
  79. package/dist/lib/toolbox/index.d.ts +5 -0
  80. package/dist/lib/toolbox/index.js +28 -0
  81. package/dist/lib/toolbox/index.js.map +1 -0
  82. package/dist/lib/toolbox/with_openssl/_create_random_file.d.ts +4 -0
  83. package/dist/lib/toolbox/with_openssl/_create_random_file.js +50 -0
  84. package/dist/lib/toolbox/with_openssl/_create_random_file.js.map +1 -0
  85. package/dist/lib/toolbox/with_openssl/_env.d.ts +58 -0
  86. package/dist/lib/toolbox/with_openssl/_env.js +126 -0
  87. package/dist/lib/toolbox/with_openssl/_env.js.map +1 -0
  88. package/dist/lib/toolbox/with_openssl/create_certificate_signing_request.d.ts +5 -0
  89. package/dist/lib/toolbox/with_openssl/create_certificate_signing_request.js +72 -0
  90. package/dist/lib/toolbox/with_openssl/create_certificate_signing_request.js.map +1 -0
  91. package/dist/lib/toolbox/with_openssl/create_private_key.d.ts +5 -0
  92. package/dist/lib/toolbox/with_openssl/create_private_key.js +92 -0
  93. package/dist/lib/toolbox/with_openssl/create_private_key.js.map +1 -0
  94. package/dist/lib/toolbox/with_openssl/create_self_signed_certificate.d.ts +5 -0
  95. package/dist/lib/toolbox/with_openssl/create_self_signed_certificate.js +135 -0
  96. package/dist/lib/toolbox/with_openssl/create_self_signed_certificate.js.map +1 -0
  97. package/dist/lib/toolbox/with_openssl/execute_openssl.d.ts +67 -0
  98. package/dist/lib/toolbox/with_openssl/execute_openssl.js +246 -0
  99. package/dist/lib/toolbox/with_openssl/execute_openssl.js.map +1 -0
  100. package/dist/lib/toolbox/with_openssl/index.d.ts +5 -0
  101. package/dist/lib/toolbox/with_openssl/index.js +30 -0
  102. package/dist/lib/toolbox/with_openssl/index.js.map +1 -0
  103. package/dist/lib/toolbox/with_openssl/install_prerequisite.d.ts +7 -0
  104. package/dist/lib/toolbox/with_openssl/install_prerequisite.js +358 -0
  105. package/dist/lib/toolbox/with_openssl/install_prerequisite.js.map +1 -0
  106. package/dist/lib/toolbox/with_openssl/toolbox.d.ts +53 -0
  107. package/dist/lib/toolbox/with_openssl/toolbox.js +190 -0
  108. package/dist/lib/toolbox/with_openssl/toolbox.js.map +1 -0
  109. package/dist/lib/toolbox/without_openssl/create_certificate_signing_request.d.ts +5 -0
  110. package/dist/lib/toolbox/without_openssl/create_certificate_signing_request.js +69 -0
  111. package/dist/lib/toolbox/without_openssl/create_certificate_signing_request.js.map +1 -0
  112. package/dist/lib/toolbox/without_openssl/create_self_signed_certificate.d.ts +3 -0
  113. package/dist/lib/toolbox/without_openssl/create_self_signed_certificate.js +78 -0
  114. package/dist/lib/toolbox/without_openssl/create_self_signed_certificate.js.map +1 -0
  115. package/dist/lib/toolbox/without_openssl/index.d.ts +2 -0
  116. package/dist/lib/toolbox/without_openssl/index.js +25 -0
  117. package/dist/lib/toolbox/without_openssl/index.js.map +1 -0
  118. package/package.json +12 -31
  119. package/dist/bin/install_prerequisite.mjs +0 -18
  120. package/dist/bin/install_prerequisite.mjs.map +0 -1
  121. package/dist/bin/pki.mjs +0 -5932
  122. package/dist/bin/pki.mjs.map +0 -1
  123. package/dist/chunk-EQ4DGI4M.mjs +0 -1917
  124. package/dist/chunk-EQ4DGI4M.mjs.map +0 -1
  125. package/dist/chunk-GCHH54PS.mjs +0 -30
  126. package/dist/chunk-GCHH54PS.mjs.map +0 -1
  127. package/dist/core-BwqSJPHc.d.ts +0 -1041
  128. package/dist/core.d.mts +0 -2
  129. package/dist/core.d.ts +0 -2
  130. package/dist/core.js +0 -1902
  131. package/dist/core.js.map +0 -1
  132. package/dist/core.mjs +0 -21
  133. package/dist/core.mjs.map +0 -1
  134. package/dist/index.d.mts +0 -1003
  135. package/dist/index.js +0 -5009
  136. package/dist/index.js.map +0 -1
  137. package/dist/index.mjs +0 -3145
  138. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,398 @@
1
+ // ---------------------------------------------------------------------------------------------------------------------
2
+ // node-opcua-pki
3
+ // ---------------------------------------------------------------------------------------------------------------------
4
+ // Copyright (c) 2014-2026 - Etienne Rossignon - etienne.rossignon (at) gadz.org
5
+ // Copyright (c) 2022-2026 - Sterfive.com
6
+ // ---------------------------------------------------------------------------------------------------------------------
7
+ //
8
+ // This project is licensed under the terms of the MIT license.
9
+ //
10
+ // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
11
+ // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
12
+ // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
13
+ // permit persons to whom the Software is furnished to do so, subject to the following conditions:
14
+ //
15
+ // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
16
+ // Software.
17
+ //
18
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
19
+ // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20
+ // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ // ---------------------------------------------------------------------------------------------------------------------
23
+ import fs from "node:fs";
24
+ import path from "node:path";
25
+ import { Subject } from "node-opcua-crypto";
26
+ import { displaySubtitle, displayTitle, makePath } from "../../toolbox/index.js";
27
+ import { buildSubjectAltNameString, cleanupStaticConfig, ensure_openssl_installed, execute_openssl, execute_openssl_no_failure, generateStaticConfig, passinArg, setEnv, x509Date } from "../../toolbox/with_openssl/index.js";
28
+ const n = makePath;
29
+ /** The ALTNAME openssl embeds as `subjectAltName` on the CA's own certificate/CSR — see `[v3_ca]` / `[v3_ca_req]`. */
30
+ function caAltName(ca) {
31
+ // OPC UA validators (UaExpert, compliance tools) require every
32
+ // certificate — including the root/intermediate CA — to carry a
33
+ // SubjectAltName extension. RFC 5280 does not strictly mandate it
34
+ // on CA certificates but the OPC UA Profile does. Build a stable
35
+ // URI SAN derived from the CA CommonName so the resulting CA cert
36
+ // passes the spec check.
37
+ return `URI:urn:${ca.subject.commonName || "NodeOPCUA-CA"}`;
38
+ }
39
+ /**
40
+ * Every render of `conf/caconfig.cnf` needs `ALTNAME` / `CDP_URL` /
41
+ * `AIA_VALUE` resolved, **even for an `openssl` subcommand that only reads
42
+ * a different section** (`ca -gencrl` only needs `[crl_ext]`, `ca -revoke`
43
+ * only needs `[ca]`): openssl's config loader (`NCONF_load`) expands every
44
+ * `$ENV::NAME` reference in the file line by line as it parses it, not
45
+ * lazily per queried section, and every section in this template — not
46
+ * just the two gated behind `{{#CDP_URL}}` / `{{#AIA_VALUE}}` — references
47
+ * `$ENV::ALTNAME` unconditionally. Leaving any of the three unresolved
48
+ * makes openssl fall through to its own native `$ENV::` resolution (a real
49
+ * OS environment variable, which is never set) and fail with "variable has
50
+ * no value".
51
+ *
52
+ * Passed explicitly rather than relying on whatever `setEnv()` last wrote
53
+ * to the shared registry (see {@link generateStaticConfig}'s
54
+ * `envOverrides`) — empty string means "omit the extension" for the two
55
+ * gated keys (the template's `{{#KEY}}` block strips itself on an empty
56
+ * value), never "fall back to the registry".
57
+ *
58
+ * Exported as the single implementation of the CDP/AIA value format:
59
+ * `CertificateAuthority._wireRevocationEnvVars` (the legacy registry shim)
60
+ * delegates here so the format cannot drift between the two mechanisms.
61
+ */
62
+ export function caConfigEnvOverrides(ca, altName = caAltName(ca)) {
63
+ const aiaLegs = [];
64
+ if (ca.ocspResponderUrl) {
65
+ aiaLegs.push(`OCSP;URI:${ca.ocspResponderUrl}`);
66
+ }
67
+ if (ca.caIssuersUrl) {
68
+ aiaLegs.push(`caIssuers;URI:${ca.caIssuersUrl}`);
69
+ }
70
+ return {
71
+ ALTNAME: altName,
72
+ CDP_URL: ca.crlDistributionUrl ?? "",
73
+ AIA_VALUE: aiaLegs.join(",")
74
+ };
75
+ }
76
+ /**
77
+ * The default {@link CaBackend}: shells out to the `openssl` CLI, exactly as
78
+ * `CertificateAuthority` always has — this is a pure code move (plus a lock
79
+ * around every database-mutating operation, temp-config cleanup, and
80
+ * explicit `envOverrides` on every config render) with no change in the
81
+ * openssl commands issued or the files produced.
82
+ */
83
+ export class OpenSslCaBackend {
84
+ /** This backend is the `openssl` executable, so it has to be there. */
85
+ /**
86
+ * `-passin env:` argv and env for an openssl call that has to load this
87
+ * CA's key. Built here rather than on the CA: the passphrase is the
88
+ * CA's business, but expressing it as an openssl argument is this
89
+ * backend's, and the core has no reason to know the flag exists.
90
+ */
91
+ async #passin(ca) {
92
+ return passinArg(await ca._privateKeyPassphrase());
93
+ }
94
+ /** The openssl CLI loads its key from a file, so it cannot call out to an HSM. */
95
+ supportsExternalSigner = false;
96
+ async preflight() {
97
+ await ensure_openssl_installed();
98
+ }
99
+ /**
100
+ * Render `conf/caconfig.cnf` once with explicit overrides, run `fn`
101
+ * with the rendered path, and always remove the temp file. Structural
102
+ * guarantee that (a) every render carries the three required env
103
+ * values and (b) no rendered `<name>.<pid>-<n>.tmp` file is ever left
104
+ * behind — each was previously a per-method discipline.
105
+ */
106
+ async #withConfig(ca, altName, fn) {
107
+ const caRootDir = path.resolve(ca.rootDir);
108
+ const options = { cwd: caRootDir };
109
+ const configFile = generateStaticConfig("conf/caconfig.cnf", options, caConfigEnvOverrides(ca, altName));
110
+ try {
111
+ return await fn(configFile, options);
112
+ }
113
+ finally {
114
+ await cleanupStaticConfig(configFile, options);
115
+ }
116
+ }
117
+ async #generateCaCsrWith(ca, configFile, options, privateKeyFile, csrFile) {
118
+ const passin = await this.#passin(ca);
119
+ displayTitle("Generate a certificate request for the CA key");
120
+ await execute_openssl([
121
+ "req",
122
+ "-new",
123
+ "-sha256",
124
+ "-extensions",
125
+ "v3_ca_req",
126
+ "-config",
127
+ n(configFile),
128
+ "-key",
129
+ n(privateKeyFile),
130
+ "-out",
131
+ n(csrFile),
132
+ "-subj",
133
+ ca.subject.toString(),
134
+ ...passin.args
135
+ ], { ...options, env: passin.env });
136
+ }
137
+ /**
138
+ * `openssl ca -gencrl` signs the CRL with the CA key it finds through the
139
+ * config file (`private_key = $dir/private/cakey.pem`), so it needs the
140
+ * CA passphrase like every other `openssl ca` invocation.
141
+ */
142
+ async #regenerateCrlWith(ca, configFile, options) {
143
+ const passin = await this.#passin(ca);
144
+ // produce a CRL in PEM format
145
+ displaySubtitle("regenerate CRL (Certificate Revocation List)");
146
+ await execute_openssl(["ca", "-gencrl", "-config", n(configFile), "-out", "crl/revocation_list.crl", ...passin.args], {
147
+ ...options,
148
+ env: passin.env
149
+ });
150
+ await execute_openssl(["crl", "-in", "crl/revocation_list.crl", "-out", "crl/revocation_list.der", "-outform", "der"], options);
151
+ displaySubtitle("Display (Certificate Revocation List)");
152
+ await execute_openssl(["crl", "-in", n(ca.revocationList), "-text", "-noout"], options);
153
+ }
154
+ async generateCaCsr(ca, _caRootDir, privateKeyFile, csrFile) {
155
+ await this.#withConfig(ca, caAltName(ca), (configFile, options) => this.#generateCaCsrWith(ca, configFile, options, privateKeyFile, csrFile));
156
+ }
157
+ async bootstrap(ca) {
158
+ const caRootDir = path.resolve(ca.rootDir);
159
+ const privateKeyFilename = path.join(caRootDir, "private/cakey.pem");
160
+ const csrFilename = path.join(caRootDir, "private/cakey.csr");
161
+ // one render serves the CSR, the CA-certificate signature, and the
162
+ // initial CRL (the overrides are identical for all three)
163
+ await this.#withConfig(ca, caAltName(ca), async (configFile, options) => {
164
+ await this.#generateCaCsrWith(ca, configFile, options, privateKeyFilename, csrFilename);
165
+ const issuerCA = ca._issuerCA;
166
+ if (issuerCA) {
167
+ // Subordinate (intermediate) CA — signed by the parent CA
168
+ displayTitle("Generate CA Certificate (signed by issuer CA)");
169
+ const issuerCert = path.resolve(issuerCA.caCertificate);
170
+ const issuerKey = path.resolve(issuerCA.rootDir, "private/cakey.pem");
171
+ const issuerSerial = path.resolve(issuerCA.rootDir, "serial");
172
+ // the -CAkey is the *issuer's* key: its passphrase, not this CA's
173
+ const issuerPassin = await this.#passin(issuerCA);
174
+ const signWithIssuer = async () => {
175
+ await execute_openssl([
176
+ "x509",
177
+ "-sha256",
178
+ "-req",
179
+ "-days",
180
+ "3650",
181
+ "-extensions",
182
+ "v3_ca",
183
+ "-extfile",
184
+ n(configFile),
185
+ "-in",
186
+ "private/cakey.csr",
187
+ "-CA",
188
+ n(issuerCert),
189
+ "-CAkey",
190
+ n(issuerKey),
191
+ "-CAserial",
192
+ n(issuerSerial),
193
+ "-out",
194
+ "public/cacert.pem",
195
+ ...issuerPassin.args
196
+ ], { ...options, env: issuerPassin.env });
197
+ };
198
+ // `-CAserial` read-increment-writes the ISSUER's serial file,
199
+ // so this must hold the issuer's directory lock, not just the
200
+ // subordinate's (which the caller already holds). The only
201
+ // cross-CA lock ordering in the codebase is subordinate ->
202
+ // issuer, so this cannot deadlock — unless both CAs share one
203
+ // rootDir (a degenerate configuration), where the lock is
204
+ // already held and re-acquiring the non-reentrant file lock
205
+ // would self-deadlock: skip it there.
206
+ if (path.resolve(issuerCA.rootDir) === caRootDir) {
207
+ await signWithIssuer();
208
+ }
209
+ else {
210
+ await issuerCA._withCaDirectoryLock(signWithIssuer);
211
+ }
212
+ }
213
+ else {
214
+ // Root CA — self-signed
215
+ displayTitle("Generate CA Certificate (self-signed)");
216
+ const passin = await this.#passin(ca);
217
+ await execute_openssl([
218
+ "x509",
219
+ "-sha256",
220
+ "-req",
221
+ "-days",
222
+ "3650",
223
+ "-extensions",
224
+ "v3_ca",
225
+ "-extfile",
226
+ n(configFile),
227
+ "-in",
228
+ "private/cakey.csr",
229
+ "-signkey",
230
+ n(privateKeyFilename),
231
+ "-out",
232
+ "public/cacert.pem",
233
+ ...passin.args
234
+ ], { ...options, env: passin.env });
235
+ }
236
+ displaySubtitle("generate initial CRL (Certificate Revocation List)");
237
+ await this.#regenerateCrlWith(ca, configFile, options);
238
+ });
239
+ displayTitle("Create Certificate Authority (CA) ---> DONE");
240
+ }
241
+ async regenerateCrl(ca) {
242
+ await this.#withConfig(ca, caAltName(ca), (configFile, options) => this.#regenerateCrlWith(ca, configFile, options));
243
+ }
244
+ async signSubordinateCsr(ca, csrFile, certFile, validityDays) {
245
+ // `[v3_ca]`'s subjectAltName should describe the *subordinate* being
246
+ // certified, not `ca` (the issuer doing the signing) — but nothing
247
+ // here parses `csrFile`'s own subject, so this reuses the issuer's
248
+ // identity as a well-formed placeholder. This is a pre-existing gap,
249
+ // not a regression: the original code left this value to whatever a
250
+ // prior, unrelated operation had last set in the shared env
251
+ // registry (an accidental "URI:undefined" or a stale value from a
252
+ // different CA entirely), so this is deterministic where the
253
+ // original was not, even though neither describes the subordinate.
254
+ await this.#withConfig(ca, caAltName(ca), async (configFile, options) => {
255
+ const caRootDir = options.cwd;
256
+ const passin = await this.#passin(ca);
257
+ await execute_openssl([
258
+ "x509",
259
+ "-sha256",
260
+ "-req",
261
+ "-days",
262
+ String(validityDays),
263
+ "-extensions",
264
+ "v3_ca",
265
+ "-extfile",
266
+ n(configFile),
267
+ "-in",
268
+ n(csrFile),
269
+ "-CA",
270
+ n(ca.caCertificate),
271
+ "-CAkey",
272
+ n(path.join(caRootDir, "private/cakey.pem")),
273
+ "-CAserial",
274
+ n(path.join(caRootDir, "serial")),
275
+ "-out",
276
+ n(certFile),
277
+ ...passin.args
278
+ ], { ...options, env: passin.env });
279
+ });
280
+ }
281
+ async signEndEntityCsr(ca, certificate, csr, params1, sanOverride) {
282
+ await this.#withConfig(ca, buildSubjectAltNameString(sanOverride), async (configFile, options) => {
283
+ displaySubtitle("- then we ask the authority to sign the certificate signing request");
284
+ const passin = await this.#passin(ca);
285
+ await execute_openssl([
286
+ "ca",
287
+ "-config",
288
+ configFile,
289
+ "-startdate",
290
+ x509Date(params1.startDate),
291
+ "-enddate",
292
+ x509Date(params1.endDate),
293
+ "-batch",
294
+ "-out",
295
+ n(certificate),
296
+ "-in",
297
+ n(csr),
298
+ ...passin.args
299
+ ], { ...options, env: passin.env });
300
+ displaySubtitle("- dump the certificate for a check");
301
+ await execute_openssl(["x509", "-in", n(certificate), "-dates", "-fingerprint", "-purpose", "-noout"], options);
302
+ });
303
+ }
304
+ async revoke(ca, certificate, reason) {
305
+ // one render serves the revocation and the CRL regeneration
306
+ // openssl writes its entropy file here; the native backend has no such notion
307
+ setEnv("RANDFILE", path.join(ca.rootDir, "random.rnd"));
308
+ await this.#withConfig(ca, caAltName(ca), async (configFile, options) => {
309
+ displaySubtitle("Revoke certificate");
310
+ const passin = await this.#passin(ca);
311
+ await execute_openssl_no_failure(["ca", "-verbose", "-config", n(configFile), "-revoke", certificate, "-crl_reason", reason, ...passin.args], { ...options, env: passin.env });
312
+ // regenerate CRL (Certificate Revocation List)
313
+ await this.#regenerateCrlWith(ca, configFile, options);
314
+ displaySubtitle("Verify that certificate is revoked");
315
+ await execute_openssl_no_failure([
316
+ "verify",
317
+ "-verbose",
318
+ "-CRLfile",
319
+ n(ca.revocationList),
320
+ "-CAfile",
321
+ n(ca.caCertificate),
322
+ "-crl_check",
323
+ n(certificate)
324
+ ], options);
325
+ // produce CRL in DER format
326
+ displaySubtitle("Produce CRL in DER form ");
327
+ await execute_openssl(["crl", "-in", n(ca.revocationList), "-out", "crl/revocation_list.der", "-outform", "der"], options);
328
+ // produce CRL in PEM format with text
329
+ displaySubtitle("Produce CRL in PEM form ");
330
+ await execute_openssl(["crl", "-in", n(ca.revocationList), "-out", "crl/revocation_list.pem", "-outform", "pem", "-text"], options);
331
+ });
332
+ }
333
+ async createSelfSignedCertificate(ca, certificateFile, privateKeyFile, params) {
334
+ // Explicit overrides like every other method: `$ENV::ALTNAME` in the
335
+ // rendered config comes from THIS call's params, never from whatever
336
+ // the shared env registry happened to hold — the registry-based
337
+ // render made a concurrent operation's SANs (or an empty ALTNAME
338
+ // from a concurrent revoke) leak into this certificate. CDP/AIA now
339
+ // deterministically follow this CA's configured URLs as well.
340
+ const envOverrides = caConfigEnvOverrides(ca, buildSubjectAltNameString(params));
341
+ const configFile = generateStaticConfig(ca.configFile, { cwd: ca.rootDir }, envOverrides);
342
+ const options = {
343
+ cwd: ca.rootDir,
344
+ openssl_conf: makePath(configFile)
345
+ };
346
+ try {
347
+ const subject = params.subject ? new Subject(params.subject).toString() : "";
348
+ const subjectOptions = subject && subject.length > 1 ? ["-subj", subject] : [];
349
+ const csrFile = `${certificateFile}_csr`;
350
+ // `req -new -key` reads (and, for an encrypted key, must decrypt)
351
+ // privateKeyFile too: without -passin it hangs indefinitely
352
+ // waiting on a passphrase prompt that never comes, even with
353
+ // stdin redirected to /dev/null — unlike e.g. `pkcs12`/`rsa
354
+ // -pubout`, which fail fast instead. Reproduced directly against
355
+ // OpenSSL 3.5.4. Empty passin is a no-op against a plaintext key.
356
+ const passin = await this.#passin(ca);
357
+ displaySubtitle("- the certificate signing request");
358
+ await execute_openssl([
359
+ "req",
360
+ "-new",
361
+ "-sha256",
362
+ ...subjectOptions,
363
+ "-batch",
364
+ "-key",
365
+ n(privateKeyFile),
366
+ "-out",
367
+ n(csrFile),
368
+ ...passin.args
369
+ ], { ...options, env: passin.env });
370
+ displaySubtitle("- creating the self-signed certificate");
371
+ await execute_openssl([
372
+ "ca",
373
+ "-selfsign",
374
+ "-keyfile",
375
+ n(privateKeyFile),
376
+ "-startdate",
377
+ x509Date(params.startDate),
378
+ "-enddate",
379
+ x509Date(params.endDate),
380
+ "-batch",
381
+ "-out",
382
+ n(certificateFile),
383
+ "-in",
384
+ n(csrFile),
385
+ ...passin.args
386
+ ], { ...options, env: passin.env });
387
+ displaySubtitle("- dump the certificate for a check");
388
+ await execute_openssl(["x509", "-in", n(certificateFile), "-dates", "-fingerprint", "-purpose", "-noout"], {});
389
+ displaySubtitle("- verify self-signed certificate");
390
+ await execute_openssl_no_failure(["verify", "-verbose", "-CAfile", n(certificateFile), n(certificateFile)], options);
391
+ await fs.promises.unlink(csrFile);
392
+ }
393
+ finally {
394
+ await cleanupStaticConfig(configFile, { cwd: ca.rootDir });
395
+ }
396
+ }
397
+ }
398
+ //# sourceMappingURL=openssl_ca_backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openssl_ca_backend.js","sourceRoot":"","sources":["../../../../lib/ca/backends/openssl_ca_backend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { type OpensslPassArg } from "../toolbox/with_openssl/index.js";
2
+ import { CertificateAuthorityCore, type CertificateAuthorityCoreOptions } from "./core/certificate_authority_core.js";
3
+ export * from "./core/certificate_authority_core.js";
4
+ /**
5
+ * Options for {@link CertificateAuthority}: the core's, except that the
6
+ * backend is named rather than supplied.
7
+ */
8
+ export interface CertificateAuthorityOptions extends Omit<CertificateAuthorityCoreOptions, "backend"> {
9
+ /**
10
+ * Signing backend to use.
11
+ *
12
+ * - `"openssl"` (default): shells out to the `openssl` CLI, as this
13
+ * class always has.
14
+ * - `"native"`: signs in pure JS via `node-opcua-crypto`, writing the
15
+ * same on-disk database format, and needs no `openssl` executable.
16
+ *
17
+ * Setting `signer` implies `"native"`, since the openssl CLI can only
18
+ * load a key from a file.
19
+ *
20
+ * To supply a backend instance directly - including one of your own -
21
+ * use {@link CertificateAuthorityCore}, which is also the class to
22
+ * build against when you do not want the openssl backend in your
23
+ * bundle at all.
24
+ */
25
+ backend?: "openssl" | "native";
26
+ }
27
+ /**
28
+ * A Certificate Authority with a backend chosen for you.
29
+ *
30
+ * This is {@link CertificateAuthorityCore} plus the convenience that made
31
+ * it the historical API: name a backend, or name nothing and get openssl.
32
+ * Because it resolves the name, it necessarily references both backends,
33
+ * which is why the core exists separately - a program that never imports
34
+ * this class never pulls the openssl backend into its bundle.
35
+ */
36
+ export declare class CertificateAuthority extends CertificateAuthorityCore {
37
+ constructor(options: CertificateAuthorityOptions);
38
+ /**
39
+ * @internal `-passin env:` argv + env for an openssl call that loads
40
+ * this CA's key (always emitted, empty when none).
41
+ *
42
+ * The openssl backend builds its own now; this remains so that external
43
+ * code calling it keeps working, and lives here rather than on the core
44
+ * because the flag means nothing to a backend that spawns nothing.
45
+ */
46
+ _opensslPassin(): Promise<OpensslPassArg>;
47
+ /**
48
+ * @internal
49
+ * Legacy shim: publish the `CDP_URL` / `AIA_VALUE` config substitution
50
+ * values to the shared env registry, or unset them so the matching
51
+ * `{{#KEY}}...{{/KEY}}` blocks are stripped. Nothing in this package
52
+ * reads the registry any more - every openssl config render receives
53
+ * these values explicitly, from the same {@link caConfigEnvOverrides}
54
+ * builder this delegates to, so the two cannot drift - kept only for
55
+ * external code that renders openssl config templates against the
56
+ * registry directly.
57
+ *
58
+ * It lives on this class rather than the core because it is meaningful
59
+ * only to the openssl backend.
60
+ */
61
+ _wireRevocationEnvVars(): void;
62
+ }
@@ -0,0 +1,91 @@
1
+ // ---------------------------------------------------------------------------------------------------------------------
2
+ // node-opcua-pki
3
+ // ---------------------------------------------------------------------------------------------------------------------
4
+ // Copyright (c) 2014-2026 - Etienne Rossignon - etienne.rossignon (at) gadz.org
5
+ // Copyright (c) 2022-2026 - Sterfive.com
6
+ // ---------------------------------------------------------------------------------------------------------------------
7
+ //
8
+ // This project is licensed under the terms of the MIT license.
9
+ //
10
+ // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
11
+ // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
12
+ // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
13
+ // permit persons to whom the Software is furnished to do so, subject to the following conditions:
14
+ //
15
+ // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
16
+ // Software.
17
+ //
18
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
19
+ // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20
+ // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ // ---------------------------------------------------------------------------------------------------------------------
23
+ import { passinArg, setEnv, unsetEnv } from "../toolbox/with_openssl/index.js";
24
+ import { NativeCaBackend } from "./backends/native_ca_backend.js";
25
+ import { caConfigEnvOverrides, OpenSslCaBackend } from "./backends/openssl_ca_backend.js";
26
+ import { CertificateAuthorityCore } from "./core/certificate_authority_core.js";
27
+ // Everything the CA exposes lives in the core module; re-exported here so
28
+ // that `import { ... } from "./ca/certificate_authority"` keeps resolving
29
+ // exactly as it did before the split.
30
+ export * from "./core/certificate_authority_core.js";
31
+ /**
32
+ * A Certificate Authority with a backend chosen for you.
33
+ *
34
+ * This is {@link CertificateAuthorityCore} plus the convenience that made
35
+ * it the historical API: name a backend, or name nothing and get openssl.
36
+ * Because it resolves the name, it necessarily references both backends,
37
+ * which is why the core exists separately - a program that never imports
38
+ * this class never pulls the openssl backend into its bundle.
39
+ */
40
+ export class CertificateAuthority extends CertificateAuthorityCore {
41
+ constructor(options) {
42
+ if (options.signer && options.backend === "openssl") {
43
+ throw new Error("CertificateAuthority: backend 'openssl' cannot be combined with 'signer' - " +
44
+ "the openssl CLI loads its key from a file and cannot call an external signer. " +
45
+ "Drop the backend option (a signer implies 'native') or drop the signer.");
46
+ }
47
+ const backend = options.signer || options.backend === "native" ? new NativeCaBackend() : new OpenSslCaBackend();
48
+ super({ ...options, backend });
49
+ }
50
+ /**
51
+ * @internal `-passin env:` argv + env for an openssl call that loads
52
+ * this CA's key (always emitted, empty when none).
53
+ *
54
+ * The openssl backend builds its own now; this remains so that external
55
+ * code calling it keeps working, and lives here rather than on the core
56
+ * because the flag means nothing to a backend that spawns nothing.
57
+ */
58
+ async _opensslPassin() {
59
+ return passinArg(await this._privateKeyPassphrase());
60
+ }
61
+ /**
62
+ * @internal
63
+ * Legacy shim: publish the `CDP_URL` / `AIA_VALUE` config substitution
64
+ * values to the shared env registry, or unset them so the matching
65
+ * `{{#KEY}}...{{/KEY}}` blocks are stripped. Nothing in this package
66
+ * reads the registry any more - every openssl config render receives
67
+ * these values explicitly, from the same {@link caConfigEnvOverrides}
68
+ * builder this delegates to, so the two cannot drift - kept only for
69
+ * external code that renders openssl config templates against the
70
+ * registry directly.
71
+ *
72
+ * It lives on this class rather than the core because it is meaningful
73
+ * only to the openssl backend.
74
+ */
75
+ _wireRevocationEnvVars() {
76
+ const overrides = caConfigEnvOverrides(this);
77
+ if (overrides.CDP_URL) {
78
+ setEnv("CDP_URL", overrides.CDP_URL);
79
+ }
80
+ else {
81
+ unsetEnv("CDP_URL");
82
+ }
83
+ if (overrides.AIA_VALUE) {
84
+ setEnv("AIA_VALUE", overrides.AIA_VALUE);
85
+ }
86
+ else {
87
+ unsetEnv("AIA_VALUE");
88
+ }
89
+ }
90
+ }
91
+ //# sourceMappingURL=certificate_authority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certificate_authority.js","sourceRoot":"","sources":["../../../lib/ca/certificate_authority.ts"],"names":[],"mappings":"AAAA,wHAAwH;AACxH,iBAAiB;AACjB,wHAAwH;AACxH,gFAAgF;AAChF,yCAAyC;AACzC,wHAAwH;AACxH,EAAE;AACF,gEAAgE;AAChE,EAAE;AACF,+GAA+G;AAC/G,sHAAsH;AACtH,kHAAkH;AAClH,mGAAmG;AACnG,EAAE;AACF,uHAAuH;AACvH,YAAY;AACZ,EAAE;AACF,uHAAuH;AACvH,wHAAwH;AACxH,mHAAmH;AACnH,mHAAmH;AACnH,wHAAwH;AAExH,OAAO,EAAuB,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AACpG,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAC1F,OAAO,EAAE,wBAAwB,EAAwC,MAAM,sCAAsC,CAAC;AAEtH,0EAA0E;AAC1E,0EAA0E;AAC1E,sCAAsC;AACtC,cAAc,sCAAsC,CAAC;AA0BrD;;;;;;;;GAQG;AACH,MAAM,OAAO,oBAAqB,SAAQ,wBAAwB;IAC9D,YAAY,OAAoC;QAC5C,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CACX,6EAA6E;gBACzE,gFAAgF;gBAChF,yEAAyE,CAChF,CAAC;QACN,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,gBAAgB,EAAE,CAAC;QAChH,KAAK,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACnC,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,cAAc;QACvB,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;IACzD,CAAC;IAED;;;;;;;;;;;;;OAaG;IACI,sBAAsB;QACzB,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACJ,QAAQ,CAAC,SAAS,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACJ,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC;IACL,CAAC;CACJ"}