node-opcua-pki 6.22.0 → 7.0.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.
Files changed (137) hide show
  1. package/bin/install_prerequisite.ts +1 -1
  2. package/bin/pki.ts +1 -1
  3. package/dist/bin/install_prerequisite.d.ts +2 -0
  4. package/dist/bin/install_prerequisite.js +6 -0
  5. package/dist/bin/install_prerequisite.js.map +1 -0
  6. package/dist/bin/pki.d.ts +2 -0
  7. package/dist/bin/pki.js +4 -0
  8. package/dist/bin/pki.js.map +1 -0
  9. package/dist/lib/ca/backends/native_ca_backend.d.ts +49 -0
  10. package/dist/lib/ca/backends/native_ca_backend.js +365 -0
  11. package/dist/lib/ca/backends/native_ca_backend.js.map +1 -0
  12. package/dist/lib/ca/backends/openssl_ca_backend.d.ts +47 -0
  13. package/dist/lib/ca/backends/openssl_ca_backend.js +398 -0
  14. package/dist/lib/ca/backends/openssl_ca_backend.js.map +1 -0
  15. package/dist/lib/ca/certificate_authority.d.ts +62 -0
  16. package/dist/lib/ca/certificate_authority.js +91 -0
  17. package/dist/lib/ca/certificate_authority.js.map +1 -0
  18. package/dist/lib/ca/core/ca_backend.d.ts +89 -0
  19. package/dist/lib/ca/core/ca_backend.js +24 -0
  20. package/dist/lib/ca/core/ca_backend.js.map +1 -0
  21. package/dist/lib/ca/core/ca_database.d.ts +91 -0
  22. package/dist/lib/ca/core/ca_database.js +267 -0
  23. package/dist/lib/ca/core/ca_database.js.map +1 -0
  24. package/dist/{core-BwqSJPHc.d.mts → lib/ca/core/certificate_authority_core.d.ts} +45 -394
  25. package/dist/lib/ca/core/certificate_authority_core.js +1300 -0
  26. package/dist/lib/ca/core/certificate_authority_core.js.map +1 -0
  27. package/dist/lib/ca/core/index.d.ts +17 -0
  28. package/dist/lib/ca/core/index.js +25 -0
  29. package/dist/lib/ca/core/index.js.map +1 -0
  30. package/dist/lib/ca/crypto_create_CA.d.ts +1 -0
  31. package/dist/lib/ca/crypto_create_CA.js +821 -0
  32. package/dist/lib/ca/crypto_create_CA.js.map +1 -0
  33. package/dist/lib/ca/index.d.ts +1 -0
  34. package/dist/lib/ca/index.js +2 -0
  35. package/dist/lib/ca/index.js.map +1 -0
  36. package/dist/lib/ca/templates/ca_config_template.cnf.d.ts +2 -0
  37. package/dist/lib/ca/templates/ca_config_template.cnf.js +170 -0
  38. package/dist/lib/ca/templates/ca_config_template.cnf.js.map +1 -0
  39. package/dist/lib/core.d.ts +33 -0
  40. package/dist/lib/core.js +56 -0
  41. package/dist/lib/core.js.map +1 -0
  42. package/dist/lib/index.d.ts +11 -0
  43. package/dist/lib/index.js +37 -0
  44. package/dist/lib/index.js.map +1 -0
  45. package/dist/lib/misc/applicationurn.d.ts +1 -0
  46. package/dist/lib/misc/applicationurn.js +40 -0
  47. package/dist/lib/misc/applicationurn.js.map +1 -0
  48. package/dist/lib/misc/hostname.d.ts +8 -0
  49. package/dist/lib/misc/hostname.js +82 -0
  50. package/dist/lib/misc/hostname.js.map +1 -0
  51. package/dist/lib/misc/subject.d.ts +2 -0
  52. package/dist/lib/misc/subject.js +2 -0
  53. package/dist/lib/misc/subject.js.map +1 -0
  54. package/dist/{index.d.ts → lib/pki/certificate_manager.d.ts} +24 -246
  55. package/dist/lib/pki/certificate_manager.js +2302 -0
  56. package/dist/lib/pki/certificate_manager.js.map +1 -0
  57. package/dist/lib/pki/templates/simple_config_template.cnf.d.ts +2 -0
  58. package/dist/lib/pki/templates/simple_config_template.cnf.js +74 -0
  59. package/dist/lib/pki/templates/simple_config_template.cnf.js.map +1 -0
  60. package/dist/lib/pki/toolbox_pfx.d.ts +127 -0
  61. package/dist/lib/pki/toolbox_pfx.js +248 -0
  62. package/dist/lib/pki/toolbox_pfx.js.map +1 -0
  63. package/dist/lib/toolbox/common.d.ts +150 -0
  64. package/dist/lib/toolbox/common.js +82 -0
  65. package/dist/lib/toolbox/common.js.map +1 -0
  66. package/dist/lib/toolbox/common2.d.ts +25 -0
  67. package/dist/lib/toolbox/common2.js +97 -0
  68. package/dist/lib/toolbox/common2.js.map +1 -0
  69. package/dist/lib/toolbox/config.d.ts +5 -0
  70. package/dist/lib/toolbox/config.js +28 -0
  71. package/dist/lib/toolbox/config.js.map +1 -0
  72. package/dist/lib/toolbox/debug.d.ts +5 -0
  73. package/dist/lib/toolbox/debug.js +35 -0
  74. package/dist/lib/toolbox/debug.js.map +1 -0
  75. package/dist/lib/toolbox/display.d.ts +4 -0
  76. package/dist/lib/toolbox/display.js +56 -0
  77. package/dist/lib/toolbox/display.js.map +1 -0
  78. package/dist/lib/toolbox/index.d.ts +5 -0
  79. package/dist/lib/toolbox/index.js +28 -0
  80. package/dist/lib/toolbox/index.js.map +1 -0
  81. package/dist/lib/toolbox/with_openssl/_create_random_file.d.ts +4 -0
  82. package/dist/lib/toolbox/with_openssl/_create_random_file.js +50 -0
  83. package/dist/lib/toolbox/with_openssl/_create_random_file.js.map +1 -0
  84. package/dist/lib/toolbox/with_openssl/_env.d.ts +58 -0
  85. package/dist/lib/toolbox/with_openssl/_env.js +126 -0
  86. package/dist/lib/toolbox/with_openssl/_env.js.map +1 -0
  87. package/dist/lib/toolbox/with_openssl/create_certificate_signing_request.d.ts +5 -0
  88. package/dist/lib/toolbox/with_openssl/create_certificate_signing_request.js +72 -0
  89. package/dist/lib/toolbox/with_openssl/create_certificate_signing_request.js.map +1 -0
  90. package/dist/lib/toolbox/with_openssl/create_private_key.d.ts +5 -0
  91. package/dist/lib/toolbox/with_openssl/create_private_key.js +92 -0
  92. package/dist/lib/toolbox/with_openssl/create_private_key.js.map +1 -0
  93. package/dist/lib/toolbox/with_openssl/create_self_signed_certificate.d.ts +5 -0
  94. package/dist/lib/toolbox/with_openssl/create_self_signed_certificate.js +135 -0
  95. package/dist/lib/toolbox/with_openssl/create_self_signed_certificate.js.map +1 -0
  96. package/dist/lib/toolbox/with_openssl/execute_openssl.d.ts +67 -0
  97. package/dist/lib/toolbox/with_openssl/execute_openssl.js +246 -0
  98. package/dist/lib/toolbox/with_openssl/execute_openssl.js.map +1 -0
  99. package/dist/lib/toolbox/with_openssl/index.d.ts +5 -0
  100. package/dist/lib/toolbox/with_openssl/index.js +30 -0
  101. package/dist/lib/toolbox/with_openssl/index.js.map +1 -0
  102. package/dist/lib/toolbox/with_openssl/install_prerequisite.d.ts +7 -0
  103. package/dist/lib/toolbox/with_openssl/install_prerequisite.js +358 -0
  104. package/dist/lib/toolbox/with_openssl/install_prerequisite.js.map +1 -0
  105. package/dist/lib/toolbox/with_openssl/toolbox.d.ts +53 -0
  106. package/dist/lib/toolbox/with_openssl/toolbox.js +190 -0
  107. package/dist/lib/toolbox/with_openssl/toolbox.js.map +1 -0
  108. package/dist/lib/toolbox/without_openssl/create_certificate_signing_request.d.ts +5 -0
  109. package/dist/lib/toolbox/without_openssl/create_certificate_signing_request.js +69 -0
  110. package/dist/lib/toolbox/without_openssl/create_certificate_signing_request.js.map +1 -0
  111. package/dist/lib/toolbox/without_openssl/create_self_signed_certificate.d.ts +3 -0
  112. package/dist/lib/toolbox/without_openssl/create_self_signed_certificate.js +78 -0
  113. package/dist/lib/toolbox/without_openssl/create_self_signed_certificate.js.map +1 -0
  114. package/dist/lib/toolbox/without_openssl/index.d.ts +2 -0
  115. package/dist/lib/toolbox/without_openssl/index.js +25 -0
  116. package/dist/lib/toolbox/without_openssl/index.js.map +1 -0
  117. package/package.json +11 -30
  118. package/dist/bin/install_prerequisite.mjs +0 -18
  119. package/dist/bin/install_prerequisite.mjs.map +0 -1
  120. package/dist/bin/pki.mjs +0 -5895
  121. package/dist/bin/pki.mjs.map +0 -1
  122. package/dist/chunk-EQ4DGI4M.mjs +0 -1917
  123. package/dist/chunk-EQ4DGI4M.mjs.map +0 -1
  124. package/dist/chunk-GCHH54PS.mjs +0 -30
  125. package/dist/chunk-GCHH54PS.mjs.map +0 -1
  126. package/dist/core-BwqSJPHc.d.ts +0 -1041
  127. package/dist/core.d.mts +0 -2
  128. package/dist/core.d.ts +0 -2
  129. package/dist/core.js +0 -1902
  130. package/dist/core.js.map +0 -1
  131. package/dist/core.mjs +0 -21
  132. package/dist/core.mjs.map +0 -1
  133. package/dist/index.d.mts +0 -1001
  134. package/dist/index.js +0 -4968
  135. package/dist/index.js.map +0 -1
  136. package/dist/index.mjs +0 -3106
  137. package/dist/index.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { install_prerequisite } from "node-opcua-pki";
2
+ import { install_prerequisite } from "../lib/toolbox/with_openssl/install_prerequisite.js";
3
3
 
4
4
  install_prerequisite().catch((err: Error) => {
5
5
  console.log("err = ", err.message);
package/bin/pki.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { main as pki_main } from "../lib/ca/crypto_create_CA";
2
+ import { main as pki_main } from "../lib/ca/crypto_create_CA.js";
3
3
 
4
4
  pki_main(process.argv.splice(2));
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import { install_prerequisite } from "../lib/toolbox/with_openssl/install_prerequisite.js";
3
+ install_prerequisite().catch((err) => {
4
+ console.log("err = ", err.message);
5
+ });
6
+ //# sourceMappingURL=install_prerequisite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install_prerequisite.js","sourceRoot":"","sources":["../../bin/install_prerequisite.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qDAAqD,CAAC;AAE3F,oBAAoB,EAAE,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACxC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { main as pki_main } from "../lib/ca/crypto_create_CA.js";
3
+ pki_main(process.argv.splice(2));
4
+ //# sourceMappingURL=pki.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pki.js","sourceRoot":"","sources":["../../bin/pki.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAEjE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { type Params, type ProcessAltNamesParam } from "../../toolbox/index.js";
2
+ import type { CaBackend } from "../core/ca_backend.js";
3
+ import type { CertificateAuthorityCore } from "../core/certificate_authority_core.js";
4
+ /**
5
+ * A native (pure-JS, no `openssl` child process) {@link CaBackend}: it
6
+ * bootstraps a CA, signs end-entity and subordinate-CA requests, revokes,
7
+ * and builds CRLs entirely through `node-opcua-crypto`'s signing
8
+ * primitives and {@link CaDatabase}'s write path, so the resulting
9
+ * `index.txt`/`serial`/`crlnumber`/`certs/` are the same on-disk format
10
+ * `openssl ca` produces and an install can move between backends.
11
+ *
12
+ * The signing key reaches every operation through
13
+ * `CertificateAuthority._getSigningKey()`, which yields either the on-disk
14
+ * key or an external `CaSigner`. Nothing below can tell the difference,
15
+ * which is the point: a CA whose key lives in an HSM never has a
16
+ * `private/cakey.pem` and never needs one.
17
+ *
18
+ * Two deliberate differences from the openssl backend, both improvements:
19
+ * a subordinate CA's certificate is recorded in the issuer's `index.txt`
20
+ * (`openssl x509 -CAserial` bumps the serial file but records nothing),
21
+ * and a subordinate's SAN is taken from its own CSR rather than being
22
+ * stamped with the issuer's.
23
+ */
24
+ export declare class NativeCaBackend implements CaBackend {
25
+ #private;
26
+ /** Nothing to check: this backend spawns no process and needs no tool on PATH. */
27
+ /** Signing goes through `ca._getSigningKey()`, which may be an external signer. */
28
+ readonly supportsExternalSigner = true;
29
+ preflight(): Promise<void>;
30
+ /**
31
+ * Write a CSR for the CA's own key, the `[v3_ca_req]` equivalent. The
32
+ * key comes from the CA rather than from `privateKeyFile`: on a
33
+ * signer-backed CA that file does not exist.
34
+ */
35
+ generateCaCsr(ca: CertificateAuthorityCore, _caRootDir: string, _privateKeyFile: string, csrFile: string): Promise<void>;
36
+ bootstrap(ca: CertificateAuthorityCore): Promise<void>;
37
+ /** Sign a subordinate CA's request with this CA's key, the `[v3_ca]` equivalent. */
38
+ signSubordinateCsr(ca: CertificateAuthorityCore, csrFile: string, certFile: string, validityDays: number): Promise<void>;
39
+ /**
40
+ * Self-sign a certificate with a caller-supplied key file and record it
41
+ * in this CA's database: the native equivalent of `openssl req -new`
42
+ * followed by `openssl ca -selfsign`, which likewise applies the
43
+ * end-entity profile and updates `index.txt`.
44
+ */
45
+ createSelfSignedCertificate(ca: CertificateAuthorityCore, certificateFile: string, privateKeyFile: string, params: Params): Promise<void>;
46
+ signEndEntityCsr(ca: CertificateAuthorityCore, certificate: string, csr: string, params: Params, sanOverride: Required<ProcessAltNamesParam>): Promise<void>;
47
+ regenerateCrl(ca: CertificateAuthorityCore): Promise<void>;
48
+ revoke(ca: CertificateAuthorityCore, certificate: string, reason: string): Promise<void>;
49
+ }
@@ -0,0 +1,365 @@
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 { CertificatePurpose, createCertificateFromCsr, createCertificateSigningRequest, createCrl, isCaSigner, privateKeyToCryptoKey, readPrivateKey, Subject, x509 } from "node-opcua-crypto";
26
+ import { displaySubtitle, displayTitle } from "../../toolbox/index.js";
27
+ import { CaDatabase } from "../core/ca_database.js";
28
+ /** The CA-certificate lifetime the openssl backend hard-codes (`x509 -req -days 3650`). */
29
+ const CA_CERT_VALIDITY_DAYS = 3650;
30
+ const RSA_SHA256 = { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-256" } };
31
+ /** A signer declares its own algorithm; a raw key is always the RSA/SHA-256 this CA generates. */
32
+ function signingAlgorithmOf(key) {
33
+ return isCaSigner(key) ? key.algorithm : RSA_SHA256;
34
+ }
35
+ function daysFromNow(notBefore, days) {
36
+ return new Date(notBefore.getTime() + days * 24 * 60 * 60 * 1000);
37
+ }
38
+ /**
39
+ * The SAN every CA certificate carries. RFC 5280 does not require one on a
40
+ * CA certificate, but the OPC UA profile does, and validators (UaExpert,
41
+ * the compliance tools) reject a CA without it - so mirror what the
42
+ * openssl backend puts in `[v3_ca]`: `URI:urn:<commonName>`.
43
+ */
44
+ function caSanUri(ca) {
45
+ return `urn:${ca.subject.commonName || "NodeOPCUA-CA"}`;
46
+ }
47
+ /**
48
+ * The subject alternative names a CSR asked for, in the shape the signing
49
+ * primitive wants. `openssl ca` does not copy SANs across from the CSR
50
+ * (openssl/openssl#10458), which is why the caller has to re-derive them;
51
+ * peculiar decodes IP addresses to dotted form for us.
52
+ */
53
+ function sanFromCsr(csrPem) {
54
+ const request = new x509.Pkcs10CertificateRequest(csrPem);
55
+ const extension = request.getExtension("2.5.29.17");
56
+ const dns = [];
57
+ const ip = [];
58
+ let applicationUri;
59
+ for (const name of extension?.names.toJSON() ?? []) {
60
+ if (name.type === "dns") {
61
+ dns.push(name.value);
62
+ }
63
+ else if (name.type === "ip") {
64
+ ip.push(name.value);
65
+ }
66
+ else if (name.type === "url" && applicationUri === undefined) {
67
+ applicationUri = name.value;
68
+ }
69
+ }
70
+ return { dns, ip, applicationUri };
71
+ }
72
+ /**
73
+ * Maps this codebase's CRL revocation reason strings (see
74
+ * `CertificateAuthority.revokeCertificate`'s `crlReasons` list) to
75
+ * `@peculiar/x509`'s `X509CrlReason` enum keys — same reasons, but
76
+ * `X509CrlReason.cACompromise` is lowercase-first where this codebase's
77
+ * `"CACompromise"` is not.
78
+ */
79
+ const REASON_TO_X509_CRL_REASON = {
80
+ unspecified: x509.X509CrlReason.unspecified,
81
+ keyCompromise: x509.X509CrlReason.keyCompromise,
82
+ CACompromise: x509.X509CrlReason.cACompromise,
83
+ affiliationChanged: x509.X509CrlReason.affiliationChanged,
84
+ superseded: x509.X509CrlReason.superseded,
85
+ cessationOfOperation: x509.X509CrlReason.cessationOfOperation,
86
+ certificateHold: x509.X509CrlReason.certificateHold,
87
+ removeFromCRL: x509.X509CrlReason.removeFromCRL
88
+ };
89
+ /**
90
+ * Builds OpenSSL's slash-delimited one-line subject (`"/CN=Leaf/O=Acme"`)
91
+ * from the certificate's parsed subject attributes — NOT by re-splitting
92
+ * `Name.toString()`. The subject comes verbatim from the requester's CSR,
93
+ * so it is attacker-controlled; the string form escapes `,` (which a
94
+ * `split(",")` would then mangle) and, because its control-character
95
+ * `replace()` has no `g` flag, escapes only the FIRST `\n`/`\t` per value,
96
+ * letting later ones through raw — which would let a crafted CN inject a
97
+ * forged row into the tab/newline-delimited `index.txt`. Working from
98
+ * `toJSON()` sidesteps that entirely; {@link CaDatabase} additionally
99
+ * escapes every control character it writes, as `X509_NAME_oneline` does.
100
+ */
101
+ function toOpenSslSubjectString(subjectName) {
102
+ const parts = [];
103
+ for (const rdn of subjectName.toJSON()) {
104
+ for (const [type, values] of Object.entries(rdn)) {
105
+ for (const value of values) {
106
+ parts.push(`${type}=${value}`);
107
+ }
108
+ }
109
+ }
110
+ return `/${parts.join("/")}`;
111
+ }
112
+ /**
113
+ * A native (pure-JS, no `openssl` child process) {@link CaBackend}: it
114
+ * bootstraps a CA, signs end-entity and subordinate-CA requests, revokes,
115
+ * and builds CRLs entirely through `node-opcua-crypto`'s signing
116
+ * primitives and {@link CaDatabase}'s write path, so the resulting
117
+ * `index.txt`/`serial`/`crlnumber`/`certs/` are the same on-disk format
118
+ * `openssl ca` produces and an install can move between backends.
119
+ *
120
+ * The signing key reaches every operation through
121
+ * `CertificateAuthority._getSigningKey()`, which yields either the on-disk
122
+ * key or an external `CaSigner`. Nothing below can tell the difference,
123
+ * which is the point: a CA whose key lives in an HSM never has a
124
+ * `private/cakey.pem` and never needs one.
125
+ *
126
+ * Two deliberate differences from the openssl backend, both improvements:
127
+ * a subordinate CA's certificate is recorded in the issuer's `index.txt`
128
+ * (`openssl x509 -CAserial` bumps the serial file but records nothing),
129
+ * and a subordinate's SAN is taken from its own CSR rather than being
130
+ * stamped with the issuer's.
131
+ */
132
+ export class NativeCaBackend {
133
+ /** Nothing to check: this backend spawns no process and needs no tool on PATH. */
134
+ /** Signing goes through `ca._getSigningKey()`, which may be an external signer. */
135
+ supportsExternalSigner = true;
136
+ async preflight() {
137
+ // intentionally empty
138
+ }
139
+ /**
140
+ * Write a CSR for the CA's own key, the `[v3_ca_req]` equivalent. The
141
+ * key comes from the CA rather than from `privateKeyFile`: on a
142
+ * signer-backed CA that file does not exist.
143
+ */
144
+ async generateCaCsr(ca, _caRootDir, _privateKeyFile, csrFile) {
145
+ displayTitle("Generate a certificate request for the CA key");
146
+ const signingKey = await ca._getSigningKey();
147
+ const { csr } = await createCertificateSigningRequest({
148
+ privateKey: signingKey,
149
+ subject: ca.subject.toString(),
150
+ applicationUri: caSanUri(ca),
151
+ purpose: CertificatePurpose.ForCertificateAuthority
152
+ });
153
+ await fs.promises.writeFile(csrFile, csr);
154
+ }
155
+ async bootstrap(ca) {
156
+ const caRootDir = path.resolve(ca.rootDir);
157
+ const csrFile = path.join(caRootDir, "private/cakey.csr");
158
+ await this.generateCaCsr(ca, caRootDir, path.join(caRootDir, "private/cakey.pem"), csrFile);
159
+ const issuerCA = ca._issuerCA;
160
+ if (issuerCA) {
161
+ displayTitle("Generate CA Certificate (signed by issuer CA)");
162
+ // The issuer's serial file and database are mutated here, so the
163
+ // issuer's own lock is required - the caller only holds this
164
+ // (subordinate) CA's. Subordinate -> issuer is the only cross-CA
165
+ // lock edge in this codebase and it is never reversed, so it
166
+ // cannot deadlock; the exception is two CAs sharing one rootDir,
167
+ // where the lock is already held and re-acquiring the
168
+ // non-reentrant file lock would deadlock against itself.
169
+ const signWithIssuer = () => this.signSubordinateCsr(issuerCA, csrFile, ca.caCertificate, CA_CERT_VALIDITY_DAYS);
170
+ if (path.resolve(issuerCA.rootDir) === caRootDir) {
171
+ await signWithIssuer();
172
+ }
173
+ else {
174
+ await issuerCA._withCaDirectoryLock(signWithIssuer);
175
+ }
176
+ }
177
+ else {
178
+ displayTitle("Generate CA Certificate (self-signed)");
179
+ const csrPem = await fs.promises.readFile(csrFile, "utf-8");
180
+ const signingKey = await ca._getSigningKey();
181
+ const request = new x509.Pkcs10CertificateRequest(csrPem);
182
+ const notBefore = new Date();
183
+ const { cert } = await createCertificateFromCsr({
184
+ csr: csrPem,
185
+ // the CSR's own parsed subject, so issuer and subject are
186
+ // byte-identical on a self-signed root: re-encoding a string
187
+ // form could differ and break chain building
188
+ issuerName: request.subjectName,
189
+ issuerPublicKey: request.publicKey,
190
+ signingKey,
191
+ signingAlgorithm: signingAlgorithmOf(signingKey),
192
+ notBefore,
193
+ notAfter: daysFromNow(notBefore, CA_CERT_VALIDITY_DAYS),
194
+ purpose: CertificatePurpose.ForCertificateAuthority,
195
+ applicationUri: caSanUri(ca),
196
+ revocation: {
197
+ crlDistributionUrl: ca.crlDistributionUrl,
198
+ ocspResponderUrl: ca.ocspResponderUrl,
199
+ caIssuersUrl: ca.caIssuersUrl
200
+ }
201
+ });
202
+ await fs.promises.writeFile(ca.caCertificate, cert);
203
+ }
204
+ displaySubtitle("generate initial CRL (Certificate Revocation List)");
205
+ await this.#regenerateCrlLocked(ca, new CaDatabase(ca.rootDir));
206
+ displayTitle("Create Certificate Authority (CA) ---> DONE");
207
+ }
208
+ /** Sign a subordinate CA's request with this CA's key, the `[v3_ca]` equivalent. */
209
+ async signSubordinateCsr(ca, csrFile, certFile, validityDays) {
210
+ const { signingKey, signingAlgorithm, issuerPublicKey, issuerName } = await this.#issuerContext(ca);
211
+ const csrPem = await fs.promises.readFile(csrFile, "utf-8");
212
+ const db = new CaDatabase(ca.rootDir);
213
+ const serialNumber = db.nextSerial();
214
+ const notBefore = new Date();
215
+ const notAfter = daysFromNow(notBefore, validityDays);
216
+ const { cert } = await createCertificateFromCsr({
217
+ csr: csrPem,
218
+ issuerName,
219
+ issuerPublicKey,
220
+ signingKey,
221
+ signingAlgorithm,
222
+ serialNumber,
223
+ notBefore,
224
+ notAfter,
225
+ purpose: CertificatePurpose.ForCertificateAuthority,
226
+ // the subordinate's own SAN, not the issuer's
227
+ ...sanFromCsr(csrPem),
228
+ revocation: {
229
+ crlDistributionUrl: ca.crlDistributionUrl,
230
+ ocspResponderUrl: ca.ocspResponderUrl,
231
+ caIssuersUrl: ca.caIssuersUrl
232
+ }
233
+ });
234
+ await fs.promises.writeFile(certFile, cert);
235
+ this.#record(db, serialNumber, cert, notAfter);
236
+ }
237
+ /**
238
+ * Self-sign a certificate with a caller-supplied key file and record it
239
+ * in this CA's database: the native equivalent of `openssl req -new`
240
+ * followed by `openssl ca -selfsign`, which likewise applies the
241
+ * end-entity profile and updates `index.txt`.
242
+ */
243
+ async createSelfSignedCertificate(ca, certificateFile, privateKeyFile, params) {
244
+ displaySubtitle("- the certificate signing request");
245
+ const key = await privateKeyToCryptoKey(readPrivateKey(privateKeyFile, await ca._privateKeyPassphrase()));
246
+ const { csr } = await createCertificateSigningRequest({
247
+ privateKey: key,
248
+ subject: params.subject ? new Subject(params.subject).toString() : ca.subject.toString(),
249
+ dns: params.dns,
250
+ ip: params.ip,
251
+ applicationUri: params.applicationUri,
252
+ purpose: CertificatePurpose.ForApplication
253
+ });
254
+ displaySubtitle("- creating the self-signed certificate");
255
+ const request = new x509.Pkcs10CertificateRequest(csr);
256
+ const db = new CaDatabase(ca.rootDir);
257
+ const serialNumber = db.nextSerial();
258
+ const notBefore = params.startDate ?? new Date();
259
+ const notAfter = params.endDate ?? daysFromNow(notBefore, params.validity ?? 365);
260
+ const { cert } = await createCertificateFromCsr({
261
+ csr,
262
+ issuerName: request.subjectName,
263
+ issuerPublicKey: request.publicKey,
264
+ signingKey: key,
265
+ signingAlgorithm: RSA_SHA256,
266
+ serialNumber,
267
+ notBefore,
268
+ notAfter,
269
+ purpose: CertificatePurpose.ForApplication,
270
+ ...sanFromCsr(csr)
271
+ });
272
+ await fs.promises.writeFile(certificateFile, cert);
273
+ this.#record(db, serialNumber, cert, notAfter);
274
+ }
275
+ /** `certs/<SERIAL>.pem` plus the `V` row, exactly as `openssl ca` writes them. */
276
+ #record(db, serialNumber, certPem, notAfter) {
277
+ db.storeCertificate(serialNumber, certPem);
278
+ db.appendIssued({
279
+ serial: serialNumber,
280
+ expiryDate: notAfter,
281
+ subject: toOpenSslSubjectString(new x509.X509Certificate(certPem).subjectName)
282
+ });
283
+ }
284
+ /**
285
+ * The CA's signing key and issuer identity, resolved fresh on every
286
+ * call and never cached across operations. The identity is read back
287
+ * from the CA certificate on disk so that the issuer field of anything
288
+ * this CA signs is byte-identical to that certificate's subject.
289
+ */
290
+ async #issuerContext(ca) {
291
+ const signingKey = await ca._getSigningKey();
292
+ const caCertPem = await fs.promises.readFile(ca.caCertificate, "utf-8");
293
+ const caCert = new x509.X509Certificate(caCertPem);
294
+ return {
295
+ signingKey,
296
+ signingAlgorithm: signingAlgorithmOf(signingKey),
297
+ issuerPublicKey: caCert.publicKey,
298
+ issuerName: caCert.subjectName
299
+ };
300
+ }
301
+ async signEndEntityCsr(ca, certificate, csr, params, sanOverride) {
302
+ const { signingKey, signingAlgorithm, issuerPublicKey, issuerName } = await this.#issuerContext(ca);
303
+ const db = new CaDatabase(ca.rootDir);
304
+ const serialNumber = db.nextSerial();
305
+ const csrPem = await fs.promises.readFile(csr, "utf-8");
306
+ const notBefore = params.startDate ?? new Date();
307
+ const notAfter = params.endDate ?? new Date(notBefore.getTime() + (params.validity ?? 365) * 24 * 60 * 60 * 1000);
308
+ const { cert } = await createCertificateFromCsr({
309
+ csr: csrPem,
310
+ issuerName,
311
+ issuerPublicKey,
312
+ signingKey,
313
+ signingAlgorithm,
314
+ serialNumber,
315
+ notBefore,
316
+ notAfter,
317
+ purpose: CertificatePurpose.ForApplication,
318
+ dns: sanOverride.dns,
319
+ ip: sanOverride.ip,
320
+ applicationUri: sanOverride.applicationUri,
321
+ revocation: {
322
+ crlDistributionUrl: ca.crlDistributionUrl,
323
+ ocspResponderUrl: ca.ocspResponderUrl,
324
+ caIssuersUrl: ca.caIssuersUrl
325
+ }
326
+ });
327
+ await fs.promises.writeFile(certificate, cert);
328
+ this.#record(db, serialNumber, cert, notAfter);
329
+ }
330
+ async #regenerateCrlLocked(ca, db) {
331
+ const { signingKey, signingAlgorithm, issuerPublicKey, issuerName } = await this.#issuerContext(ca);
332
+ const crlNumber = db.nextCrlNumber();
333
+ const entries = db
334
+ .readIndex()
335
+ .filter((r) => r.status === "revoked")
336
+ .map((r) => ({
337
+ serialNumber: r.serial,
338
+ revocationDate: r.revocationDate ? new Date(r.revocationDate) : new Date(),
339
+ reason: r.reason ? REASON_TO_X509_CRL_REASON[r.reason] : undefined
340
+ }));
341
+ const { crl } = await createCrl({
342
+ issuerName,
343
+ issuerPublicKey,
344
+ signingKey,
345
+ signingAlgorithm,
346
+ crlNumber: BigInt(`0x${crlNumber}`),
347
+ entries
348
+ });
349
+ await fs.promises.writeFile(ca.revocationList, crl);
350
+ const der = new x509.X509Crl(crl).rawData;
351
+ await fs.promises.writeFile(ca.revocationListDER, Buffer.from(der));
352
+ }
353
+ async regenerateCrl(ca) {
354
+ const db = new CaDatabase(ca.rootDir);
355
+ await this.#regenerateCrlLocked(ca, db);
356
+ }
357
+ async revoke(ca, certificate, reason) {
358
+ const certPem = await fs.promises.readFile(certificate, "utf-8");
359
+ const cert = new x509.X509Certificate(certPem);
360
+ const db = new CaDatabase(ca.rootDir);
361
+ db.markRevoked(cert.serialNumber, new Date(), reason);
362
+ await this.#regenerateCrlLocked(ca, db);
363
+ }
364
+ }
365
+ //# sourceMappingURL=native_ca_backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native_ca_backend.js","sourceRoot":"","sources":["../../../../lib/ca/backends/native_ca_backend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { type Params, type ProcessAltNamesParam } from "../../toolbox/index.js";
2
+ import type { CaBackend } from "../core/ca_backend.js";
3
+ import type { CertificateAuthorityCore } from "../core/certificate_authority_core.js";
4
+ /**
5
+ * Every render of `conf/caconfig.cnf` needs `ALTNAME` / `CDP_URL` /
6
+ * `AIA_VALUE` resolved, **even for an `openssl` subcommand that only reads
7
+ * a different section** (`ca -gencrl` only needs `[crl_ext]`, `ca -revoke`
8
+ * only needs `[ca]`): openssl's config loader (`NCONF_load`) expands every
9
+ * `$ENV::NAME` reference in the file line by line as it parses it, not
10
+ * lazily per queried section, and every section in this template — not
11
+ * just the two gated behind `{{#CDP_URL}}` / `{{#AIA_VALUE}}` — references
12
+ * `$ENV::ALTNAME` unconditionally. Leaving any of the three unresolved
13
+ * makes openssl fall through to its own native `$ENV::` resolution (a real
14
+ * OS environment variable, which is never set) and fail with "variable has
15
+ * no value".
16
+ *
17
+ * Passed explicitly rather than relying on whatever `setEnv()` last wrote
18
+ * to the shared registry (see {@link generateStaticConfig}'s
19
+ * `envOverrides`) — empty string means "omit the extension" for the two
20
+ * gated keys (the template's `{{#KEY}}` block strips itself on an empty
21
+ * value), never "fall back to the registry".
22
+ *
23
+ * Exported as the single implementation of the CDP/AIA value format:
24
+ * `CertificateAuthority._wireRevocationEnvVars` (the legacy registry shim)
25
+ * delegates here so the format cannot drift between the two mechanisms.
26
+ */
27
+ export declare function caConfigEnvOverrides(ca: CertificateAuthorityCore, altName?: string): Record<string, string>;
28
+ /**
29
+ * The default {@link CaBackend}: shells out to the `openssl` CLI, exactly as
30
+ * `CertificateAuthority` always has — this is a pure code move (plus a lock
31
+ * around every database-mutating operation, temp-config cleanup, and
32
+ * explicit `envOverrides` on every config render) with no change in the
33
+ * openssl commands issued or the files produced.
34
+ */
35
+ export declare class OpenSslCaBackend implements CaBackend {
36
+ #private;
37
+ /** The openssl CLI loads its key from a file, so it cannot call out to an HSM. */
38
+ readonly supportsExternalSigner = false;
39
+ preflight(): Promise<void>;
40
+ generateCaCsr(ca: CertificateAuthorityCore, _caRootDir: string, privateKeyFile: string, csrFile: string): Promise<void>;
41
+ bootstrap(ca: CertificateAuthorityCore): Promise<void>;
42
+ regenerateCrl(ca: CertificateAuthorityCore): Promise<void>;
43
+ signSubordinateCsr(ca: CertificateAuthorityCore, csrFile: string, certFile: string, validityDays: number): Promise<void>;
44
+ signEndEntityCsr(ca: CertificateAuthorityCore, certificate: string, csr: string, params1: Params, sanOverride: Required<ProcessAltNamesParam>): Promise<void>;
45
+ revoke(ca: CertificateAuthorityCore, certificate: string, reason: string): Promise<void>;
46
+ createSelfSignedCertificate(ca: CertificateAuthorityCore, certificateFile: string, privateKeyFile: string, params: Params): Promise<void>;
47
+ }