@zetra/citrineos-util 1.8.3-fork.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 (142) hide show
  1. package/dist/authorization/ApiAuthPlugin.d.ts +52 -0
  2. package/dist/authorization/ApiAuthPlugin.js +122 -0
  3. package/dist/authorization/ApiAuthPlugin.js.map +1 -0
  4. package/dist/authorization/OidcTokenProvider.d.ts +15 -0
  5. package/dist/authorization/OidcTokenProvider.js +47 -0
  6. package/dist/authorization/OidcTokenProvider.js.map +1 -0
  7. package/dist/authorization/index.d.ts +4 -0
  8. package/dist/authorization/index.js +8 -0
  9. package/dist/authorization/index.js.map +1 -0
  10. package/dist/authorization/provider/LocalByPassAuthProvider.d.ts +34 -0
  11. package/dist/authorization/provider/LocalByPassAuthProvider.js +62 -0
  12. package/dist/authorization/provider/LocalByPassAuthProvider.js.map +1 -0
  13. package/dist/authorization/provider/OIDCAuthProvider.d.ts +62 -0
  14. package/dist/authorization/provider/OIDCAuthProvider.js +173 -0
  15. package/dist/authorization/provider/OIDCAuthProvider.js.map +1 -0
  16. package/dist/authorization/rbac/RbacRulesLoader.d.ts +32 -0
  17. package/dist/authorization/rbac/RbacRulesLoader.js +105 -0
  18. package/dist/authorization/rbac/RbacRulesLoader.js.map +1 -0
  19. package/dist/authorization/rbac/UrlMatcher.d.ts +14 -0
  20. package/dist/authorization/rbac/UrlMatcher.js +44 -0
  21. package/dist/authorization/rbac/UrlMatcher.js.map +1 -0
  22. package/dist/authorizer/RealTimeAuthorizer.d.ts +28 -0
  23. package/dist/authorizer/RealTimeAuthorizer.js +152 -0
  24. package/dist/authorizer/RealTimeAuthorizer.js.map +1 -0
  25. package/dist/authorizer/index.d.ts +1 -0
  26. package/dist/authorizer/index.js +5 -0
  27. package/dist/authorizer/index.js.map +1 -0
  28. package/dist/cache/memory.d.ts +19 -0
  29. package/dist/cache/memory.js +147 -0
  30. package/dist/cache/memory.js.map +1 -0
  31. package/dist/cache/redis.d.ts +16 -0
  32. package/dist/cache/redis.js +120 -0
  33. package/dist/cache/redis.js.map +1 -0
  34. package/dist/certificate/CertificateAuthority.d.ts +38 -0
  35. package/dist/certificate/CertificateAuthority.js +233 -0
  36. package/dist/certificate/CertificateAuthority.js.map +1 -0
  37. package/dist/certificate/CertificateUtil.d.ts +60 -0
  38. package/dist/certificate/CertificateUtil.js +317 -0
  39. package/dist/certificate/CertificateUtil.js.map +1 -0
  40. package/dist/certificate/client/acme.d.ts +37 -0
  41. package/dist/certificate/client/acme.js +138 -0
  42. package/dist/certificate/client/acme.js.map +1 -0
  43. package/dist/certificate/client/hubject.d.ts +41 -0
  44. package/dist/certificate/client/hubject.js +221 -0
  45. package/dist/certificate/client/hubject.js.map +1 -0
  46. package/dist/certificate/client/interface.d.ts +12 -0
  47. package/dist/certificate/client/interface.js +5 -0
  48. package/dist/certificate/client/interface.js.map +1 -0
  49. package/dist/certificate/index.d.ts +2 -0
  50. package/dist/certificate/index.js +6 -0
  51. package/dist/certificate/index.js.map +1 -0
  52. package/dist/files/ftpServer.d.ts +4 -0
  53. package/dist/files/ftpServer.js +9 -0
  54. package/dist/files/ftpServer.js.map +1 -0
  55. package/dist/files/gcpCloudStorage.d.ts +39 -0
  56. package/dist/files/gcpCloudStorage.js +130 -0
  57. package/dist/files/gcpCloudStorage.js.map +1 -0
  58. package/dist/files/localStorage.d.ts +14 -0
  59. package/dist/files/localStorage.js +57 -0
  60. package/dist/files/localStorage.js.map +1 -0
  61. package/dist/files/s3Storage.d.ts +17 -0
  62. package/dist/files/s3Storage.js +118 -0
  63. package/dist/files/s3Storage.js.map +1 -0
  64. package/dist/index.d.ts +21 -0
  65. package/dist/index.js +25 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/networkconnection/WebsocketNetworkConnection.d.ts +135 -0
  68. package/dist/networkconnection/WebsocketNetworkConnection.js +474 -0
  69. package/dist/networkconnection/WebsocketNetworkConnection.js.map +1 -0
  70. package/dist/networkconnection/authenticator/Authenticator.d.ts +20 -0
  71. package/dist/networkconnection/authenticator/Authenticator.js +39 -0
  72. package/dist/networkconnection/authenticator/Authenticator.js.map +1 -0
  73. package/dist/networkconnection/authenticator/AuthenticatorFilter.d.ts +11 -0
  74. package/dist/networkconnection/authenticator/AuthenticatorFilter.js +30 -0
  75. package/dist/networkconnection/authenticator/AuthenticatorFilter.js.map +1 -0
  76. package/dist/networkconnection/authenticator/BasicAuthenticationFilter.d.ts +17 -0
  77. package/dist/networkconnection/authenticator/BasicAuthenticationFilter.js +51 -0
  78. package/dist/networkconnection/authenticator/BasicAuthenticationFilter.js.map +1 -0
  79. package/dist/networkconnection/authenticator/ConnectedStationFilter.d.ts +14 -0
  80. package/dist/networkconnection/authenticator/ConnectedStationFilter.js +25 -0
  81. package/dist/networkconnection/authenticator/ConnectedStationFilter.js.map +1 -0
  82. package/dist/networkconnection/authenticator/NetworkProfileFilter.d.ts +16 -0
  83. package/dist/networkconnection/authenticator/NetworkProfileFilter.js +84 -0
  84. package/dist/networkconnection/authenticator/NetworkProfileFilter.js.map +1 -0
  85. package/dist/networkconnection/authenticator/UnknownStationFilter.d.ts +16 -0
  86. package/dist/networkconnection/authenticator/UnknownStationFilter.js +25 -0
  87. package/dist/networkconnection/authenticator/UnknownStationFilter.js.map +1 -0
  88. package/dist/networkconnection/authenticator/errors/AuthenticationError.d.ts +6 -0
  89. package/dist/networkconnection/authenticator/errors/AuthenticationError.js +25 -0
  90. package/dist/networkconnection/authenticator/errors/AuthenticationError.js.map +1 -0
  91. package/dist/networkconnection/authenticator/errors/IUpgradeError.d.ts +9 -0
  92. package/dist/networkconnection/authenticator/errors/IUpgradeError.js +5 -0
  93. package/dist/networkconnection/authenticator/errors/IUpgradeError.js.map +1 -0
  94. package/dist/networkconnection/authenticator/errors/UnknownError.d.ts +6 -0
  95. package/dist/networkconnection/authenticator/errors/UnknownError.js +24 -0
  96. package/dist/networkconnection/authenticator/errors/UnknownError.js.map +1 -0
  97. package/dist/networkconnection/index.d.ts +5 -0
  98. package/dist/networkconnection/index.js +9 -0
  99. package/dist/networkconnection/index.js.map +1 -0
  100. package/dist/queue/index.d.ts +4 -0
  101. package/dist/queue/index.js +8 -0
  102. package/dist/queue/index.js.map +1 -0
  103. package/dist/queue/kafka/receiver.d.ts +35 -0
  104. package/dist/queue/kafka/receiver.js +179 -0
  105. package/dist/queue/kafka/receiver.js.map +1 -0
  106. package/dist/queue/kafka/sender.d.ts +53 -0
  107. package/dist/queue/kafka/sender.js +189 -0
  108. package/dist/queue/kafka/sender.js.map +1 -0
  109. package/dist/queue/rabbit-mq/receiver.d.ts +89 -0
  110. package/dist/queue/rabbit-mq/receiver.js +472 -0
  111. package/dist/queue/rabbit-mq/receiver.js.map +1 -0
  112. package/dist/queue/rabbit-mq/sender.d.ts +90 -0
  113. package/dist/queue/rabbit-mq/sender.js +251 -0
  114. package/dist/queue/rabbit-mq/sender.js.map +1 -0
  115. package/dist/security/SignedMeterValuesUtil.d.ts +44 -0
  116. package/dist/security/SignedMeterValuesUtil.js +135 -0
  117. package/dist/security/SignedMeterValuesUtil.js.map +1 -0
  118. package/dist/security/authentication.d.ts +2 -0
  119. package/dist/security/authentication.js +26 -0
  120. package/dist/security/authentication.js.map +1 -0
  121. package/dist/util/RequestOperations.d.ts +14 -0
  122. package/dist/util/RequestOperations.js +25 -0
  123. package/dist/util/RequestOperations.js.map +1 -0
  124. package/dist/util/StringOperations.d.ts +1 -0
  125. package/dist/util/StringOperations.js +8 -0
  126. package/dist/util/StringOperations.js.map +1 -0
  127. package/dist/util/emaidCheckDigitCalculator.d.ts +15 -0
  128. package/dist/util/emaidCheckDigitCalculator.js +179 -0
  129. package/dist/util/emaidCheckDigitCalculator.js.map +1 -0
  130. package/dist/util/idGenerator.d.ts +7 -0
  131. package/dist/util/idGenerator.js +10 -0
  132. package/dist/util/idGenerator.js.map +1 -0
  133. package/dist/util/parser.d.ts +31 -0
  134. package/dist/util/parser.js +60 -0
  135. package/dist/util/parser.js.map +1 -0
  136. package/dist/util/swagger.d.ts +5 -0
  137. package/dist/util/swagger.js +154 -0
  138. package/dist/util/swagger.js.map +1 -0
  139. package/dist/util/validator.d.ts +110 -0
  140. package/dist/util/validator.js +534 -0
  141. package/dist/util/validator.js.map +1 -0
  142. package/package.json +46 -0
@@ -0,0 +1,317 @@
1
+ // SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ import * as pkijs from 'pkijs';
5
+ import { CertificationRequest } from 'pkijs';
6
+ import * as asn1js from 'asn1js';
7
+ import { fromBER } from 'asn1js';
8
+ import { Certificate, CountryNameEnumType, SignatureAlgorithmEnumType } from '@citrineos/data';
9
+ import jsrsasign from 'jsrsasign';
10
+ import { fromBase64, stringToArrayBuffer } from 'pvutils';
11
+ import moment from 'moment';
12
+ import { Logger } from 'tslog';
13
+ var KJUR = jsrsasign.KJUR;
14
+ var OCSPRequest = jsrsasign.KJUR.asn1.ocsp.OCSPRequest;
15
+ var Request = jsrsasign.KJUR.asn1.ocsp.Request;
16
+ var X509 = jsrsasign.X509;
17
+ var KEYUTIL = jsrsasign.KEYUTIL;
18
+ export const dateTimeFormat = 'YYMMDDHHmmssZ';
19
+ export function getValidityTimeString(time) {
20
+ return time.utc().format('YYMMDDHHmmss').concat('Z');
21
+ }
22
+ export function createPemBlock(content) {
23
+ return `-----BEGIN CERTIFICATE-----\n${content}\n-----END CERTIFICATE-----\n`;
24
+ }
25
+ /*
26
+ * Parse the certificate chain and extract certificates
27
+ * @param pem - certificate chain pem containing multiple certificate blocks
28
+ * @return array of certificate pem blocks
29
+ */
30
+ export function parseCertificateChainPem(pem) {
31
+ const certs = [];
32
+ pem
33
+ .match(/-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/g)
34
+ ?.forEach((certPem) => certs.push(certPem));
35
+ return certs;
36
+ }
37
+ /**
38
+ * Decode the pem and extract certificates
39
+ * @param pem - base64 encoded certificate chain string without header and footer
40
+ * @return array of pkijs.CertificateSetItem
41
+ */
42
+ export function extractCertificateArrayFromEncodedString(pem) {
43
+ try {
44
+ const cmsSignedBuffer = Buffer.from(pem, 'base64');
45
+ const asn1 = asn1js.fromBER(cmsSignedBuffer);
46
+ const cmsContent = new pkijs.ContentInfo({ schema: asn1.result });
47
+ const cmsSigned = new pkijs.SignedData({ schema: cmsContent.content });
48
+ if (cmsSigned.certificates && cmsSigned.certificates.length > 0) {
49
+ return cmsSigned.certificates;
50
+ }
51
+ else {
52
+ return [];
53
+ }
54
+ }
55
+ catch (e) {
56
+ throw new Error(`Failed to extract certificate ${pem} due to ${e}`);
57
+ }
58
+ }
59
+ /**
60
+ * extracts the base64-encoded content from a pem encoded csr
61
+ * @param csrPem
62
+ * @private
63
+ * @return {string} The parsed CSR or the original CSR if it cannot be parsed
64
+ */
65
+ export function extractEncodedContentFromCSR(csrPem) {
66
+ return csrPem
67
+ .replace(/-----BEGIN CERTIFICATE REQUEST-----/, '')
68
+ .replace(/-----END CERTIFICATE REQUEST-----/, '')
69
+ .replace(/\n/g, '');
70
+ }
71
+ /**
72
+ * Generate certificate and its private key
73
+ *
74
+ * @param certificateEntity - the certificate
75
+ * @param logger - the logger
76
+ * @param issuerKeyPem - the issuer private key
77
+ * @param issuerCertPem - the issuer certificate
78
+ *
79
+ * @return generated certificate pem and its private key pem
80
+ */
81
+ export function generateCertificate(certificateEntity, logger, issuerKeyPem, issuerCertPem) {
82
+ // Generate a key pair
83
+ let keyPair;
84
+ logger.debug(`Private key signAlgorithm: ${certificateEntity.signatureAlgorithm}`);
85
+ if (certificateEntity.signatureAlgorithm === SignatureAlgorithmEnumType.RSA) {
86
+ keyPair = jsrsasign.KEYUTIL.generateKeypair('RSA', certificateEntity.keyLength ? certificateEntity.keyLength : 2048);
87
+ }
88
+ else {
89
+ keyPair = jsrsasign.KEYUTIL.generateKeypair('EC', 'secp256r1');
90
+ }
91
+ const privateKeyPem = jsrsasign.KEYUTIL.getPEM(keyPair.prvKeyObj, 'PKCS8PRV');
92
+ const publicKeyPem = jsrsasign.KEYUTIL.getPEM(keyPair.pubKeyObj);
93
+ logger.debug(`Created publicKeyPem: ${publicKeyPem}`);
94
+ let issuerCertObj;
95
+ if (issuerCertPem) {
96
+ issuerCertObj = new X509();
97
+ issuerCertObj.readCertPEM(issuerCertPem);
98
+ }
99
+ // Prepare certificate attributes
100
+ let subjectNotAfter = certificateEntity.validBefore
101
+ ? moment(certificateEntity.validBefore)
102
+ : moment().add(1, 'year');
103
+ const subjectString = `/CN=${certificateEntity.commonName}/O=${certificateEntity.organizationName}/C=${certificateEntity.countryName}`;
104
+ let issuerParam = { str: subjectString };
105
+ if (issuerCertObj) {
106
+ const issuerNotAfter = moment(issuerCertObj.getNotAfter(), dateTimeFormat);
107
+ if (subjectNotAfter.isAfter(issuerNotAfter)) {
108
+ subjectNotAfter = issuerNotAfter;
109
+ }
110
+ issuerParam = { str: issuerCertObj.getSubjectString() };
111
+ }
112
+ // Prepare certificate extensions
113
+ const keyUsages = ['digitalSignature', 'keyCertSign', 'crlSign'];
114
+ if (!certificateEntity.isCA) {
115
+ keyUsages.push('keyEncipherment');
116
+ }
117
+ let basicConstraints = {
118
+ extname: 'basicConstraints',
119
+ critical: true,
120
+ cA: certificateEntity.isCA,
121
+ };
122
+ if (certificateEntity.pathLen) {
123
+ basicConstraints = {
124
+ extname: 'basicConstraints',
125
+ cA: certificateEntity.isCA,
126
+ pathLen: certificateEntity.pathLen,
127
+ };
128
+ }
129
+ const extensions = [
130
+ basicConstraints,
131
+ { extname: 'keyUsage', critical: true, names: keyUsages },
132
+ { extname: 'subjectKeyIdentifier', kid: publicKeyPem },
133
+ ];
134
+ if (issuerCertObj) {
135
+ extensions.push({
136
+ extname: 'authorityKeyIdentifier',
137
+ kid: issuerCertPem,
138
+ isscert: issuerCertPem,
139
+ });
140
+ }
141
+ // Prepare certificate sign parameters
142
+ const signAlgorithm = certificateEntity.signatureAlgorithm === SignatureAlgorithmEnumType.RSA
143
+ ? SignatureAlgorithmEnumType.RSA
144
+ : SignatureAlgorithmEnumType.ECDSA;
145
+ logger.debug(`Certificate SignAlgorithm: ${signAlgorithm}`);
146
+ const caKey = issuerKeyPem ? issuerKeyPem : privateKeyPem;
147
+ // Generate certificate
148
+ const certificate = new KJUR.asn1.x509.Certificate({
149
+ version: 3,
150
+ serial: { int: moment().valueOf() },
151
+ notbefore: getValidityTimeString(moment()),
152
+ notafter: getValidityTimeString(subjectNotAfter),
153
+ issuer: issuerParam,
154
+ subject: { str: subjectString },
155
+ sbjpubkey: keyPair.pubKeyObj,
156
+ ext: extensions,
157
+ sigalg: signAlgorithm,
158
+ cakey: caKey,
159
+ });
160
+ return [certificate.getPEM(), privateKeyPem];
161
+ }
162
+ /**
163
+ * Create a signed certificate for the provided CSR using the issuer certificate, and its private key.
164
+ *
165
+ * @param csrPem - The CSR that need to be signed.
166
+ * @param issuerCertPem - The issuer certificate.
167
+ * @param issuerPrivateKeyPem - The issuer private key.
168
+ * @return {KJUR.asn1.x509.Certificate} The signed certificate.
169
+ */
170
+ export function createSignedCertificateFromCSR(csrPem, issuerCertPem, issuerPrivateKeyPem) {
171
+ const csrObj = jsrsasign.KJUR.asn1.csr.CSRUtil.getParam(csrPem);
172
+ const issuerCertObj = new X509();
173
+ issuerCertObj.readCertPEM(issuerCertPem);
174
+ let subjectNotAfter = moment().add(1, 'year');
175
+ const issuerNotAfter = moment(issuerCertObj.getNotAfter(), dateTimeFormat);
176
+ if (subjectNotAfter.isAfter(issuerNotAfter)) {
177
+ subjectNotAfter = issuerNotAfter;
178
+ }
179
+ let extensions;
180
+ if (csrObj.extreq) {
181
+ extensions = csrObj.extreq;
182
+ }
183
+ else {
184
+ extensions = [
185
+ { extname: 'basicConstraints', cA: false },
186
+ {
187
+ extname: 'keyUsage',
188
+ critical: true,
189
+ names: ['digitalSignature', 'keyEncipherment'],
190
+ },
191
+ ];
192
+ }
193
+ extensions.push({ extname: 'subjectKeyIdentifier', kid: csrObj.sbjpubkey });
194
+ extensions.push({
195
+ extname: 'authorityKeyIdentifier',
196
+ kid: issuerCertPem,
197
+ isscert: issuerCertPem,
198
+ });
199
+ return new KJUR.asn1.x509.Certificate({
200
+ version: 3,
201
+ serial: { int: moment().valueOf() },
202
+ issuer: { str: issuerCertObj.getSubjectString() },
203
+ subject: { str: csrObj.subject.str },
204
+ notbefore: getValidityTimeString(moment()),
205
+ notafter: getValidityTimeString(subjectNotAfter),
206
+ sbjpubkey: csrObj.sbjpubkey,
207
+ ext: extensions,
208
+ sigalg: csrObj.sigalg,
209
+ cakey: issuerPrivateKeyPem,
210
+ });
211
+ }
212
+ export async function sendOCSPRequest(ocspRequest, responderURL) {
213
+ const response = await fetch(responderURL, {
214
+ method: 'POST',
215
+ headers: {
216
+ 'Content-Type': 'application/ocsp-request',
217
+ Accept: 'application/ocsp-response',
218
+ },
219
+ body: ocspRequest.getEncodedHex(),
220
+ });
221
+ if (!response.ok) {
222
+ throw new Error(`Failed to fetch OCSP response from ${responderURL}: ${response.status} with error: ${await response.text()}`);
223
+ }
224
+ return await response.text();
225
+ }
226
+ export function parseCSRForVerification(csrPem) {
227
+ const certificateBuffer = stringToArrayBuffer(fromBase64(extractEncodedContentFromCSR(csrPem)));
228
+ const asn1 = fromBER(certificateBuffer);
229
+ return new CertificationRequest({ schema: asn1.result });
230
+ }
231
+ export function generateCSR(certificate) {
232
+ let keyPair;
233
+ if (certificate.signatureAlgorithm === SignatureAlgorithmEnumType.RSA) {
234
+ keyPair = KEYUTIL.generateKeypair('RSA', certificate.keyLength ? certificate.keyLength : 2048);
235
+ }
236
+ else {
237
+ keyPair = KEYUTIL.generateKeypair('EC', 'secp256r1');
238
+ }
239
+ const privateKeyPem = jsrsasign.KEYUTIL.getPEM(keyPair.prvKeyObj, 'PKCS8PRV');
240
+ const publicKeyPem = jsrsasign.KEYUTIL.getPEM(keyPair.pubKeyObj);
241
+ let basicConstraintParam;
242
+ if (certificate.pathLen) {
243
+ basicConstraintParam = {
244
+ cA: certificate.isCA,
245
+ pathLen: certificate.pathLen,
246
+ };
247
+ }
248
+ else {
249
+ basicConstraintParam = { cA: certificate.isCA };
250
+ }
251
+ const csr = new KJUR.asn1.csr.CertificationRequest({
252
+ subject: {
253
+ str: `/CN=${certificate.commonName}/O=${certificate.organizationName}/C=${certificate.countryName}`,
254
+ },
255
+ sbjpubkey: publicKeyPem,
256
+ extreq: [
257
+ { extname: 'basicConstraints', array: [basicConstraintParam] },
258
+ {
259
+ extname: 'keyUsage',
260
+ array: [
261
+ {
262
+ names: ['digitalSignature', 'keyEncipherment', 'keyCertSign', 'crlSign'],
263
+ },
264
+ ],
265
+ },
266
+ ],
267
+ sigalg: certificate.signatureAlgorithm
268
+ ? certificate.signatureAlgorithm
269
+ : SignatureAlgorithmEnumType.ECDSA,
270
+ sbjprvkey: privateKeyPem,
271
+ });
272
+ return [csr.getPEM(), privateKeyPem];
273
+ }
274
+ export const parseX509Date = (date) => {
275
+ if (/^\d{14}Z$/.test(date)) {
276
+ // GeneralizedTime: YYYYMMDDHHMMSSZ
277
+ return moment.utc(date, 'YYYYMMDDHHmmss[Z]', true).toDate();
278
+ }
279
+ else if (/^\d{12}Z$/.test(date)) {
280
+ // UTCTime: YYMMDDHHMMSSZ (YY interpreted as 1950-2049)
281
+ return moment.utc(date, 'YYMMDDHHmmss[Z]', true).toDate();
282
+ }
283
+ else {
284
+ console.error(`Invalid X.509 date format: ${date}`);
285
+ return null;
286
+ }
287
+ };
288
+ export const extractCertificateDetails = (pemString) => {
289
+ try {
290
+ const cert = new jsrsasign.X509();
291
+ cert.readCertPEM(pemString);
292
+ // Extract details
293
+ const serialNumber = parseInt(cert.getSerialNumberHex());
294
+ const issuerName = cert.getIssuerString();
295
+ const organizationName = cert.getSubjectString().match(/\/O=([^/]+)/)?.[1] || null;
296
+ const commonName = cert.getSubjectString().match(/\/CN=([^/]+)/)?.[1] || null;
297
+ const countryName = (cert.getSubjectString().match(/\/C=([^/]+)/)?.[1] ||
298
+ null);
299
+ const notAfter = cert.getNotAfter();
300
+ const validBefore = parseX509Date(notAfter);
301
+ const signatureAlgorithm = cert.getSignatureAlgorithmField();
302
+ return {
303
+ serialNumber,
304
+ issuerName,
305
+ organizationName,
306
+ commonName,
307
+ countryName,
308
+ validBefore,
309
+ signatureAlgorithm,
310
+ };
311
+ }
312
+ catch (error) {
313
+ console.error('Error extracting certificate details:', error);
314
+ throw new Error('Invalid PEM format or unsupported certificate');
315
+ }
316
+ };
317
+ //# sourceMappingURL=CertificateUtil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CertificateUtil.js","sourceRoot":"","sources":["../../src/certificate/CertificateUtil.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { IChargingStationCertificateAuthorityClient } from './interface.js';
2
+ import type { SystemConfig } from '@citrineos/base';
3
+ import { Client } from 'acme-client';
4
+ import type { ILogObj } from 'tslog';
5
+ import { Logger } from 'tslog';
6
+ export declare class Acme implements IChargingStationCertificateAuthorityClient {
7
+ private readonly _directoryUrl;
8
+ private readonly _email;
9
+ private readonly _preferredChain;
10
+ private _securityCertChainKeyMap;
11
+ private _client;
12
+ private _logger;
13
+ constructor(config: SystemConfig, logger?: Logger<ILogObj>, client?: Client);
14
+ /**
15
+ * Get LetsEncrypt Root CA certificate, ISRG Root X1.
16
+ * @return {Promise<string>} The CA certificate pem.
17
+ */
18
+ getRootCACertificate(): Promise<string>;
19
+ /**
20
+ * Retrieves a signed certificate based on the provided CSR.
21
+ * The returned certificate will be signed by Let's Encrypt, ISRG Root X1.
22
+ * which is listed in https://ccadb.my.salesforce-sites.com/mozilla/CAAIdentifiersReport
23
+ *
24
+ * @param {string} csrString - The certificate signing request.
25
+ * @return {Promise<string>} The signed certificate.
26
+ */
27
+ signCertificateByExternalCA(csrString: string): Promise<string>;
28
+ /**
29
+ * Get sub CA from the certificate chain.
30
+ * Use it to sign certificate based on the CSR string.
31
+ *
32
+ * @param {string} csrString - The Certificate Signing Request (CSR) string.
33
+ * @return {Promise<string>} - The signed certificate followed by sub CA in PEM format.
34
+ */
35
+ getCertificateChain(csrString: string): Promise<string>;
36
+ updateCertificateChainKeyMap(serverId: string, certificateChain: string, privateKey: string): void;
37
+ }
@@ -0,0 +1,138 @@
1
+ // SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ import * as acme from 'acme-client';
5
+ import { Client } from 'acme-client';
6
+ import { Logger } from 'tslog';
7
+ import fs from 'fs';
8
+ import { createSignedCertificateFromCSR, parseCertificateChainPem } from '../CertificateUtil.js';
9
+ export class Acme {
10
+ _directoryUrl = acme.directory.letsencrypt.staging;
11
+ _email;
12
+ _preferredChain = {
13
+ name: 'ISRG Root X1',
14
+ file: 'isrgrootx1',
15
+ };
16
+ // Key: serverId, Value: [cert chain, sub ca private key]
17
+ _securityCertChainKeyMap = new Map();
18
+ _client;
19
+ _logger;
20
+ constructor(config, logger, client) {
21
+ this._logger = logger
22
+ ? logger.getSubLogger({ name: this.constructor.name })
23
+ : new Logger({ name: this.constructor.name });
24
+ config.util.networkConnection.websocketServers.forEach((server) => {
25
+ if (server.securityProfile === 3) {
26
+ try {
27
+ this._securityCertChainKeyMap.set(server.id, [
28
+ fs.readFileSync(server.tlsCertificateChainFilePath, 'utf8'),
29
+ fs.readFileSync(server.mtlsCertificateAuthorityKeyFilePath, 'utf8'),
30
+ ]);
31
+ }
32
+ catch (error) {
33
+ this._logger.error('Unable to start Certificates module due to invalid security certificates for {}: {}', server, error);
34
+ throw error;
35
+ }
36
+ }
37
+ });
38
+ this._email = config.util.certificateAuthority.chargingStationCA.acme?.email;
39
+ const accountKey = fs.readFileSync(config.util.certificateAuthority.chargingStationCA?.acme?.accountKeyFilePath);
40
+ const acmeEnv = config.util.certificateAuthority.chargingStationCA?.acme?.env;
41
+ if (acmeEnv === 'production') {
42
+ this._directoryUrl = acme.directory.letsencrypt.production;
43
+ }
44
+ this._client =
45
+ client ||
46
+ new acme.Client({
47
+ directoryUrl: this._directoryUrl,
48
+ accountKey: accountKey.toString(),
49
+ });
50
+ }
51
+ /**
52
+ * Get LetsEncrypt Root CA certificate, ISRG Root X1.
53
+ * @return {Promise<string>} The CA certificate pem.
54
+ */
55
+ async getRootCACertificate() {
56
+ const response = await fetch(`https://letsencrypt.org/certs/${this._preferredChain.file}.pem`);
57
+ if (!response.ok && response.status !== 304) {
58
+ throw new Error(`Failed to fetch certificate: ${response.status}: ${await response.text()}`);
59
+ }
60
+ return await response.text();
61
+ }
62
+ /**
63
+ * Retrieves a signed certificate based on the provided CSR.
64
+ * The returned certificate will be signed by Let's Encrypt, ISRG Root X1.
65
+ * which is listed in https://ccadb.my.salesforce-sites.com/mozilla/CAAIdentifiersReport
66
+ *
67
+ * @param {string} csrString - The certificate signing request.
68
+ * @return {Promise<string>} The signed certificate.
69
+ */
70
+ async signCertificateByExternalCA(csrString) {
71
+ const folderPath = '/usr/local/apps/citrineos/Server/src/assets/.well-known/acme-challenge';
72
+ const cert = await this._client?.auto({
73
+ csr: csrString,
74
+ email: this._email,
75
+ termsOfServiceAgreed: true,
76
+ preferredChain: this._preferredChain.name,
77
+ challengePriority: ['http-01'],
78
+ skipChallengeVerification: true,
79
+ challengeCreateFn: async (authz, challenge, keyAuthorization) => {
80
+ this._logger.debug('Triggered challengeCreateFn()');
81
+ const filePath = `${folderPath}/${challenge.token}`;
82
+ if (!fs.existsSync(folderPath)) {
83
+ fs.mkdirSync(folderPath, { recursive: true });
84
+ this._logger.debug(`Directory created: ${folderPath}`);
85
+ }
86
+ else {
87
+ this._logger.debug(`Directory already exists: ${folderPath}`);
88
+ }
89
+ const fileContents = keyAuthorization;
90
+ this._logger.debug(`Creating challenge response ${fileContents} for ${authz.identifier.value} at path: ${filePath}`);
91
+ fs.writeFileSync(filePath, fileContents);
92
+ },
93
+ challengeRemoveFn: async (_authz, _challenge, _keyAuthorization) => {
94
+ this._logger.debug(`Triggered challengeRemoveFn(). Would remove "${folderPath}`);
95
+ fs.rmSync(folderPath, { recursive: true, force: true });
96
+ },
97
+ });
98
+ if (!cert) {
99
+ throw new Error('Failed to get signed certificate');
100
+ }
101
+ this._logger.debug(`Certificate singed by external CA: ${cert}`);
102
+ return cert;
103
+ }
104
+ /**
105
+ * Get sub CA from the certificate chain.
106
+ * Use it to sign certificate based on the CSR string.
107
+ *
108
+ * @param {string} csrString - The Certificate Signing Request (CSR) string.
109
+ * @return {Promise<string>} - The signed certificate followed by sub CA in PEM format.
110
+ */
111
+ async getCertificateChain(csrString) {
112
+ const nextEntry = this._securityCertChainKeyMap.entries().next().value;
113
+ if (!nextEntry) {
114
+ throw new Error('Failed to get certificate chain, securityCertChainKeyMap is empty');
115
+ }
116
+ const [serverId, [certChain, subCAPrivateKey]] = nextEntry;
117
+ this._logger.debug(`Found certificate chain in server ${serverId}: ${certChain}`);
118
+ const certChainArray = parseCertificateChainPem(certChain);
119
+ if (certChainArray.length < 2) {
120
+ throw new Error(`The size of the chain is ${certChainArray.length}. Sub CA certificate for signing not found`);
121
+ }
122
+ this._logger.info(`Found Sub CA certificate: ${certChainArray[1]}`);
123
+ const signedCertPem = createSignedCertificateFromCSR(csrString, certChainArray[1], subCAPrivateKey).getPEM();
124
+ // Generate and return certificate chain for signed certificate
125
+ certChainArray[0] = signedCertPem.replace(/\n+$/, '');
126
+ return certChainArray.join('\n');
127
+ }
128
+ updateCertificateChainKeyMap(serverId, certificateChain, privateKey) {
129
+ if (this._securityCertChainKeyMap.has(serverId)) {
130
+ this._securityCertChainKeyMap.set(serverId, [certificateChain, privateKey]);
131
+ this._logger.info(`Updated certificate chain key map for server ${serverId}`);
132
+ }
133
+ else {
134
+ this._logger.error(`Server ${serverId} not found in the map`);
135
+ }
136
+ }
137
+ }
138
+ //# sourceMappingURL=acme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acme.js","sourceRoot":"","sources":["../../../src/certificate/client/acme.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { IV2GCertificateAuthorityClient } from './interface.js';
2
+ import { type ICache, type SystemConfig } from '@citrineos/base';
3
+ import type { ILogObj } from 'tslog';
4
+ import { Logger } from 'tslog';
5
+ export declare class Hubject implements IV2GCertificateAuthorityClient {
6
+ private readonly _baseUrl;
7
+ private readonly _tokenUrl;
8
+ private readonly _clientId;
9
+ private readonly _clientSecret;
10
+ private readonly _logger;
11
+ private readonly _cache;
12
+ private static readonly AUTH_TOKEN_CACHE_KEY;
13
+ private static readonly AUTH_TOKEN_CACHE_NAMESPACE;
14
+ constructor(config: SystemConfig, cache: ICache, logger?: Logger<ILogObj>);
15
+ /**
16
+ * Retrieves a signed certificate based on the provided CSR.
17
+ * DOC: https://hubject.stoplight.io/docs/open-plugncharge/486f0b8b3ded4-simple-enroll-iso-15118-2-and-iso-15118-20
18
+ *
19
+ * @param {string} csrString - The certificate signing request from SignCertificateRequest.
20
+ * @return {Promise<string>} The signed certificate without header and footer.
21
+ */
22
+ getSignedCertificate(csrString: string): Promise<string>;
23
+ /**
24
+ * Retrieves the CA certificates including sub CAs and root CA.
25
+ * DOC: https://hubject.stoplight.io/docs/open-plugncharge/e246aa213bc22-obtaining-ca-certificates-iso-15118-2-and-iso-15118-20
26
+ *
27
+ * @return {Promise<string>} The CA certificates.
28
+ */
29
+ getCACertificates(): Promise<string>;
30
+ getSignedContractData(xsdMsgDefNamespace: string, certificateInstallationReq: string): Promise<string>;
31
+ /**
32
+ * Retrieves all root certificates from Hubject.
33
+ * Refer to https://hubject.stoplight.io/docs/open-plugncharge/fdc9bdfdd4fb2-get-all-root-certificates
34
+ *
35
+ * @return {Promise<string[]>} Array of root certificate.
36
+ */
37
+ getRootCertificates(): Promise<string[]>;
38
+ private _getAuthorizationToken;
39
+ private _fetchNewToken;
40
+ private _makeAuthenticatedRequest;
41
+ }