@open-charging-cloud/chargy-core 0.13.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/README.md +1 -1
- package/dist/DocumentSignatures.d.ts +70 -0
- package/dist/DocumentSignatures.d.ts.map +1 -0
- package/dist/browser/index.js +329 -25
- package/dist/browser/index.js.map +1 -1
- package/dist/chargy.d.ts +1 -0
- package/dist/chargy.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/interfaces/IChargeTransparencyLiveLink.d.ts +16 -0
- package/dist/interfaces/IChargeTransparencyLiveLink.d.ts.map +1 -1
- package/dist/node/index.js +329 -25
- package/dist/node/index.js.map +1 -1
- package/i18n.json +25 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,50 @@ While the version number is below 1.0.0, breaking changes are released in minor
|
|
|
7
7
|
versions and are always listed first below.
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
## [0.14.0] - 2026-08-30
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **The signatures over a whole document are verified.** A charge transparency
|
|
15
|
+
live link may be signed as a whole by its operator, and that signature is what
|
|
16
|
+
ties the transport URLs and the listed public keys to whoever signed them.
|
|
17
|
+
Until now the `signatures` array was carried around but never read. Every
|
|
18
|
+
entry is checked now: the properties it excludes are removed, what remains is
|
|
19
|
+
canonicalized and read as UTF-8, the key is resolved by the `keyId` the entry
|
|
20
|
+
names - following the document's own `keyIdGeneration` - and the signature is
|
|
21
|
+
verified with it. ECDSA over P-256, P-384 and P-521, Ed25519, Ed448 and
|
|
22
|
+
ML-DSA-44/65/87 are understood.
|
|
23
|
+
|
|
24
|
+
A key id is defined over the canonical `SubjectPublicKeyInfo` form of a key,
|
|
25
|
+
no matter which form the document stores the key in. A key stored as bare key
|
|
26
|
+
material - as Ed25519 keys usually are - is therefore wrapped before its id is
|
|
27
|
+
computed: hashing the raw bytes would yield a different id for the same key,
|
|
28
|
+
and the signature would look as though no key of the document had signed it.
|
|
29
|
+
|
|
30
|
+
- **`verifyDocumentSignatures()` and `collectDocumentPublicKeys()`** do this for
|
|
31
|
+
any JSON document, for callers who want to check one without going through
|
|
32
|
+
`DetectAndConvertContentFormat()`. Neither throws: a document that is
|
|
33
|
+
unsigned, signed by an unknown key or signed badly is reported as such.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- **A live link says what its signatures did, and stays usable either way.**
|
|
38
|
+
`IChargeTransparencyLiveLink.signatureVerification` carries the outcome per
|
|
39
|
+
signature, and anything short of "all valid" also adds a `warning`. None of it
|
|
40
|
+
is fatal: an unsigned document, an unknown key and even a signature that
|
|
41
|
+
demonstrably does not match are all warnings, never a reason to refuse the
|
|
42
|
+
document. Its transports still work, and its signed meter values carry their
|
|
43
|
+
own signatures, which are verified separately. The warnings are graded by what
|
|
44
|
+
they actually say - that nothing was claimed (unsigned), that the claim cannot
|
|
45
|
+
be judged here (unknown key, unsupported algorithm, malformed), or that the
|
|
46
|
+
claim is demonstrably false (the signature does not match).
|
|
47
|
+
|
|
48
|
+
Verification runs before anything is added to the document, because the
|
|
49
|
+
signatures cover every property but their own: a timestamp defaulted into
|
|
50
|
+
`created` first would become part of what is verified and would turn a good
|
|
51
|
+
signature into a bad one.
|
|
52
|
+
|
|
53
|
+
|
|
10
54
|
## [0.13.0] - 2026-08-28
|
|
11
55
|
|
|
12
56
|
### Breaking
|
package/README.md
CHANGED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as chargyLib from './interfaces/chargyLib';
|
|
2
|
+
/** How one signature over a whole document came out. */
|
|
3
|
+
export type DocumentSignatureStatus =
|
|
4
|
+
/** The key is known and the signature matches the signed data. */
|
|
5
|
+
"validSignature" |
|
|
6
|
+
/** Everything resolved, but the signature does not match the signed data. */
|
|
7
|
+
"invalidSignature" |
|
|
8
|
+
/** No public key of the document carries the key id the signature names. */
|
|
9
|
+
"unknownPublicKey" |
|
|
10
|
+
/** The algorithm or one of the encodings is not supported here. */
|
|
11
|
+
"unsupportedAlgorithm" |
|
|
12
|
+
/** The entry is not a well-formed signature at all. */
|
|
13
|
+
"malformed";
|
|
14
|
+
/** The outcome of one entry of the "signatures" array. */
|
|
15
|
+
export interface IDocumentSignatureResult {
|
|
16
|
+
/** Position within the "signatures" array. */
|
|
17
|
+
index: number;
|
|
18
|
+
/** The key id the signature names, when it names one. */
|
|
19
|
+
keyId?: string;
|
|
20
|
+
/** The algorithm the signature names, when it names one. */
|
|
21
|
+
algorithm?: string;
|
|
22
|
+
status: DocumentSignatureStatus;
|
|
23
|
+
/** Technical detail for developers; never localized, never shown as-is. */
|
|
24
|
+
details?: string;
|
|
25
|
+
}
|
|
26
|
+
/** How a document as a whole came out. */
|
|
27
|
+
export type DocumentSignaturesStatus =
|
|
28
|
+
/** No "signatures" array, or an empty one: nothing to verify. */
|
|
29
|
+
"unsigned" |
|
|
30
|
+
/** Every signature verified. */
|
|
31
|
+
"allValid" |
|
|
32
|
+
/** At least one verified and at least one did not. */
|
|
33
|
+
"someValid" |
|
|
34
|
+
/** Signatures are present, but not one of them verified. */
|
|
35
|
+
"noneValid";
|
|
36
|
+
export interface IDocumentSignaturesResult {
|
|
37
|
+
status: DocumentSignaturesStatus;
|
|
38
|
+
signatures: Array<IDocumentSignatureResult>;
|
|
39
|
+
validCount: number;
|
|
40
|
+
}
|
|
41
|
+
/** A public key as a document lists it. */
|
|
42
|
+
export interface IDocumentPublicKey {
|
|
43
|
+
algorithm: string;
|
|
44
|
+
encodings: Array<string>;
|
|
45
|
+
value: string;
|
|
46
|
+
keyUsage: Array<string>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Every public key a document lists, in the order they appear.
|
|
50
|
+
*
|
|
51
|
+
* The keys of a charge transparency live link live in two places: those of the
|
|
52
|
+
* operator, and the one of the energy meter of the EVSE. A key that does not
|
|
53
|
+
* carry the three things needed to use it - an algorithm, an encodings pipeline
|
|
54
|
+
* and a value - is skipped rather than guessed at.
|
|
55
|
+
*/
|
|
56
|
+
export declare function collectDocumentPublicKeys(Document: chargyLib.JSONObject): Array<IDocumentPublicKey>;
|
|
57
|
+
/**
|
|
58
|
+
* Verifies every signature a document carries over itself.
|
|
59
|
+
*
|
|
60
|
+
* A document without signatures is reported as "unsigned" rather than as a
|
|
61
|
+
* failure: whether that is acceptable depends on the document, and saying so is
|
|
62
|
+
* the caller's job. Nothing here throws.
|
|
63
|
+
*
|
|
64
|
+
* The document must be the one as it was read. Verification covers every
|
|
65
|
+
* property except those the signatures exclude, so anything added to the object
|
|
66
|
+
* beforehand - a default timestamp, a verification result - changes the bytes
|
|
67
|
+
* that are verified and makes a good signature look bad.
|
|
68
|
+
*/
|
|
69
|
+
export declare function verifyDocumentSignatures(Document: chargyLib.JSONObject): IDocumentSignaturesResult;
|
|
70
|
+
//# sourceMappingURL=DocumentSignatures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocumentSignatures.d.ts","sourceRoot":"","sources":["../src/DocumentSignatures.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,SAAS,MAAyB,wBAAwB,CAAA;AAQtE,wDAAwD;AACxD,MAAM,MAAM,uBAAuB;AAE/B,kEAAkE;AAClE,gBAAgB;AAEhB,6EAA6E;AAC7E,kBAAkB;AAElB,4EAA4E;AAC5E,kBAAkB;AAElB,mEAAmE;AACnE,sBAAsB;AAEtB,uDAAuD;AACvD,WAAW,CAAC;AAGhB,0DAA0D;AAC1D,MAAM,WAAW,wBAAwB;IAErC,8CAA8C;IAC9C,KAAK,EAAQ,MAAM,CAAC;IAEpB,yDAAyD;IACzD,KAAK,CAAC,EAAO,MAAM,CAAC;IAEpB,4DAA4D;IAC5D,SAAS,CAAC,EAAG,MAAM,CAAC;IAEpB,MAAM,EAAO,uBAAuB,CAAC;IAErC,2EAA2E;IAC3E,OAAO,CAAC,EAAK,MAAM,CAAC;CAEvB;AAGD,0CAA0C;AAC1C,MAAM,MAAM,wBAAwB;AAEhC,iEAAiE;AACjE,UAAU;AAEV,gCAAgC;AAChC,UAAU;AAEV,sDAAsD;AACtD,WAAW;AAEX,4DAA4D;AAC5D,WAAW,CAAC;AAGhB,MAAM,WAAW,yBAAyB;IACtC,MAAM,EAAO,wBAAwB,CAAC;IACtC,UAAU,EAAG,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC7C,UAAU,EAAG,MAAM,CAAC;CACvB;AAGD,2CAA2C;AAC3C,MAAM,WAAW,kBAAkB;IAC/B,SAAS,EAAG,MAAM,CAAC;IACnB,SAAS,EAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAO,MAAM,CAAC;IACnB,QAAQ,EAAI,KAAK,CAAC,MAAM,CAAC,CAAC;CAC7B;AA8RD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,GAAG,KAAK,CAAC,kBAAkB,CAAC,CA4CnG;AAiID;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,GAAG,yBAAyB,CAyBlG"}
|
package/dist/browser/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { ed448ph, ed448 } from '@noble/curves/ed448.js';
|
|
|
5
5
|
import { p521, p384, p256 } from '@noble/curves/nist.js';
|
|
6
6
|
import { secp256k1 } from '@noble/curves/secp256k1.js';
|
|
7
7
|
import { ml_dsa87, ml_dsa65, ml_dsa44 } from '@noble/post-quantum/ml-dsa.js';
|
|
8
|
-
import { sha256 as sha256$1 } from '@noble/hashes/sha2.js';
|
|
8
|
+
import { sha256 as sha256$1, sha512 as sha512$1, sha384 as sha384$1 } from '@noble/hashes/sha2.js';
|
|
9
9
|
import { fileTypeFromBuffer } from 'file-type';
|
|
10
10
|
import isURL from 'is-url-superb';
|
|
11
11
|
import jsQR from 'jsqr';
|
|
@@ -3073,10 +3073,10 @@ var NobleCompatibleCurve = class {
|
|
|
3073
3073
|
keyFromPublic(publicKey, encoding) {
|
|
3074
3074
|
if (encoding.toLowerCase() !== "hex")
|
|
3075
3075
|
throw new TypeError("Only hexadecimal public keys are supported by the compatibility API.");
|
|
3076
|
-
const
|
|
3077
|
-
if (!this.suite.isValidPublicKey(
|
|
3076
|
+
const publicKeyBytes2 = normalizeSEC1PublicKey(publicKey, this.coordinateLength);
|
|
3077
|
+
if (!this.suite.isValidPublicKey(publicKeyBytes2))
|
|
3078
3078
|
throw new TypeError("Public key is not a valid point on the selected curve.");
|
|
3079
|
-
return new NobleCompatiblePublicKey(this.suite,
|
|
3079
|
+
return new NobleCompatiblePublicKey(this.suite, publicKeyBytes2, this.coordinateLength);
|
|
3080
3080
|
}
|
|
3081
3081
|
};
|
|
3082
3082
|
var suites = {
|
|
@@ -5910,7 +5910,7 @@ async function signJSONMessage(JSONMessage, KeyPairs, options) {
|
|
|
5910
5910
|
continue;
|
|
5911
5911
|
const publicKeyEncoding = isRawSignatureAlgorithm(algorithm) ? "raw" : "sec1";
|
|
5912
5912
|
const signatureEncoding = options?.signatureEncoding ?? suite.signatureEncoding;
|
|
5913
|
-
const
|
|
5913
|
+
const publicKeyBytes2 = KeyPair.publicKey ?? suite.getPublicKey(KeyPair.privateKey);
|
|
5914
5914
|
const signatureBytes = suite.sign(
|
|
5915
5915
|
plainText,
|
|
5916
5916
|
KeyPair.privateKey,
|
|
@@ -5920,8 +5920,8 @@ async function signJSONMessage(JSONMessage, KeyPairs, options) {
|
|
|
5920
5920
|
algorithm,
|
|
5921
5921
|
publicKeyEncoding,
|
|
5922
5922
|
signatureEncoding,
|
|
5923
|
-
publicKey: bytesToBase64(
|
|
5924
|
-
publicKeyHEX: bytesToHex(
|
|
5923
|
+
publicKey: bytesToBase64(publicKeyBytes2),
|
|
5924
|
+
publicKeyHEX: bytesToHex(publicKeyBytes2),
|
|
5925
5925
|
signature: bytesToBase64(signatureBytes),
|
|
5926
5926
|
signatureHEX: bytesToHex(signatureBytes)
|
|
5927
5927
|
};
|
|
@@ -5932,7 +5932,7 @@ async function signJSONMessage(JSONMessage, KeyPairs, options) {
|
|
|
5932
5932
|
const signatureIsValid = suite.verify(
|
|
5933
5933
|
plainText,
|
|
5934
5934
|
signatureBytes,
|
|
5935
|
-
|
|
5935
|
+
publicKeyBytes2,
|
|
5936
5936
|
signatureOptions(options, signatureEncoding)
|
|
5937
5937
|
);
|
|
5938
5938
|
if (!signatureIsValid)
|
|
@@ -5975,11 +5975,11 @@ async function verifyJSONSignatureResult(JSONMessage, signature, options) {
|
|
|
5975
5975
|
const resolvedOptions = resolveSignOptions(options);
|
|
5976
5976
|
const algorithm = signature.algorithm ?? resolvedOptions.algorithm;
|
|
5977
5977
|
const suite = getSignatureSuite(algorithm);
|
|
5978
|
-
const
|
|
5978
|
+
const publicKeyBytes2 = hexToBytes(signature.publicKeyHEX);
|
|
5979
5979
|
const signatureBytes = hexToBytes(signature.signatureHEX);
|
|
5980
5980
|
const signatureEncoding = signature.signatureEncoding ?? (isRawSignatureAlgorithm(algorithm) ? "raw" : "der");
|
|
5981
5981
|
try {
|
|
5982
|
-
const publicKeyIsValid = suite.isValidPublicKey(
|
|
5982
|
+
const publicKeyIsValid = suite.isValidPublicKey(publicKeyBytes2);
|
|
5983
5983
|
if (!publicKeyIsValid)
|
|
5984
5984
|
return verificationResult(
|
|
5985
5985
|
"InvalidPublicKey" /* InvalidPublicKey */,
|
|
@@ -5995,7 +5995,7 @@ async function verifyJSONSignatureResult(JSONMessage, signature, options) {
|
|
|
5995
5995
|
const signatureIsValid = suite.verify(
|
|
5996
5996
|
plainText,
|
|
5997
5997
|
signatureBytes,
|
|
5998
|
-
|
|
5998
|
+
publicKeyBytes2,
|
|
5999
5999
|
signatureVerificationOptions(signature, options, signatureEncoding)
|
|
6000
6000
|
);
|
|
6001
6001
|
return signatureIsValid ? verificationResult("True" /* True */) : verificationResult(
|
|
@@ -8324,10 +8324,10 @@ var OCMF = class {
|
|
|
8324
8324
|
try {
|
|
8325
8325
|
if (typeof PublicKey !== "string")
|
|
8326
8326
|
throw new TypeError("EdDSA and ML-DSA public keys must use a raw string encoding.");
|
|
8327
|
-
const
|
|
8327
|
+
const publicKeyBytes2 = decodeRawOCMFBytes(PublicKey, PublicKeyEncoding);
|
|
8328
8328
|
const signatureBytes = OCMFJSONDocument.signatureBytes;
|
|
8329
8329
|
const rawPayload = OCMFJSONDocument.rawPayload;
|
|
8330
|
-
if (!signatureSuite.isValidPublicKey(
|
|
8330
|
+
if (!signatureSuite.isValidPublicKey(publicKeyBytes2))
|
|
8331
8331
|
throw new TypeError("Public key is invalid for the selected signature algorithm.");
|
|
8332
8332
|
if (signatureBytes == null)
|
|
8333
8333
|
throw new TypeError("Missing raw signature bytes.");
|
|
@@ -8336,7 +8336,7 @@ var OCMF = class {
|
|
|
8336
8336
|
const signatureValid = signatureSuite.verify(
|
|
8337
8337
|
new TextEncoder().encode(rawPayload),
|
|
8338
8338
|
signatureBytes,
|
|
8339
|
-
|
|
8339
|
+
publicKeyBytes2
|
|
8340
8340
|
);
|
|
8341
8341
|
if (!signatureValid)
|
|
8342
8342
|
this.AddValidationError(OCMFJSONDocument, "Verification_SignatureMismatch");
|
|
@@ -8353,7 +8353,7 @@ var OCMF = class {
|
|
|
8353
8353
|
if (curve === null)
|
|
8354
8354
|
throw new Error(`Unsupported ECC curve '${OCMFJSONDocument.signature.SA ?? ""}'!`);
|
|
8355
8355
|
OCMFJSONDocument.publicKey ??= PublicKey;
|
|
8356
|
-
let
|
|
8356
|
+
let publicKeyBytes2 = null;
|
|
8357
8357
|
if (typeof OCMFJSONDocument.publicKey === "string") {
|
|
8358
8358
|
const ECPoint = this.chargy.asn1.define("ECPoint", function() {
|
|
8359
8359
|
this.seq().obj(
|
|
@@ -8367,36 +8367,36 @@ var OCMF = class {
|
|
|
8367
8367
|
if (PublicKeyEncoding != null && PublicKeyEncoding.length > 0) {
|
|
8368
8368
|
switch (PublicKeyEncoding.toLowerCase()) {
|
|
8369
8369
|
case "hex":
|
|
8370
|
-
|
|
8370
|
+
publicKeyBytes2 = Buffer.from(OCMFJSONDocument.publicKey, "hex");
|
|
8371
8371
|
break;
|
|
8372
8372
|
case "base32":
|
|
8373
|
-
|
|
8373
|
+
publicKeyBytes2 = Buffer.from(this.chargy.base32Decode(OCMFJSONDocument.publicKey, "RFC4648"));
|
|
8374
8374
|
break;
|
|
8375
8375
|
case "base64":
|
|
8376
|
-
|
|
8376
|
+
publicKeyBytes2 = Buffer.from(OCMFJSONDocument.publicKey, "base64");
|
|
8377
8377
|
break;
|
|
8378
8378
|
}
|
|
8379
8379
|
}
|
|
8380
|
-
if (
|
|
8380
|
+
if (publicKeyBytes2 == null) {
|
|
8381
8381
|
const hexRegex = /^[0-9A-Fa-f]+$/;
|
|
8382
8382
|
const base32Regex = /^(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=)?$/;
|
|
8383
8383
|
const base64Regex = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
8384
8384
|
if (hexRegex.test(OCMFJSONDocument.publicKey)) {
|
|
8385
8385
|
PublicKeyEncoding = "hex";
|
|
8386
|
-
|
|
8386
|
+
publicKeyBytes2 = Buffer.from(OCMFJSONDocument.publicKey, "hex");
|
|
8387
8387
|
} else if (base32Regex.test(OCMFJSONDocument.publicKey)) {
|
|
8388
8388
|
PublicKeyEncoding = "base32";
|
|
8389
|
-
|
|
8389
|
+
publicKeyBytes2 = Buffer.from(this.chargy.base32Decode(OCMFJSONDocument.publicKey, "RFC4648"));
|
|
8390
8390
|
} else if (base64Regex.test(OCMFJSONDocument.publicKey)) {
|
|
8391
8391
|
PublicKeyEncoding = "base64";
|
|
8392
|
-
|
|
8392
|
+
publicKeyBytes2 = Buffer.from(OCMFJSONDocument.publicKey, "base64");
|
|
8393
8393
|
}
|
|
8394
8394
|
}
|
|
8395
|
-
if (
|
|
8395
|
+
if (publicKeyBytes2 == null) {
|
|
8396
8396
|
OCMFJSONDocument.validationStatus = "UnknownPublicKeyFormat" /* UnknownPublicKeyFormat */;
|
|
8397
8397
|
return OCMFJSONDocument.validationStatus;
|
|
8398
8398
|
}
|
|
8399
|
-
const decodedPublicKeyASN1 = ECPoint.decode(
|
|
8399
|
+
const decodedPublicKeyASN1 = ECPoint.decode(publicKeyBytes2, "der");
|
|
8400
8400
|
const publicKeyASN1 = decodedPublicKeyASN1;
|
|
8401
8401
|
const coordinates = publicKeyASN1.pubKey.data.subarray(1);
|
|
8402
8402
|
const halfLength = coordinates.length / 2;
|
|
@@ -12329,6 +12329,259 @@ var validationRules_default = {
|
|
|
12329
12329
|
}
|
|
12330
12330
|
}
|
|
12331
12331
|
};
|
|
12332
|
+
var defaultKeyIdGeneration = ["SubjectPublicKeyInfo", "DER", "SHA-256", "hex"];
|
|
12333
|
+
var defaultExcludedProperties = ["signatures"];
|
|
12334
|
+
var canonicalJSONEncodings = ["JSON", "JCS", "UTF-8"];
|
|
12335
|
+
var subjectPublicKeyInfoHeaders = {
|
|
12336
|
+
"EdDSA-Ed25519": "302A300506032B6570032100",
|
|
12337
|
+
"EdDSA-Ed448": "3043300506032B6571033A00",
|
|
12338
|
+
"ECDSA-secp256r1": "3059301306072A8648CE3D020106082A8648CE3D030107034200",
|
|
12339
|
+
"ECDSA-secp384r1": "3076301006072A8648CE3D020106052B81040022036200",
|
|
12340
|
+
"ECDSA-secp521r1": "30819B301006072A8648CE3D020106052B8104002303818600"
|
|
12341
|
+
};
|
|
12342
|
+
function readDERLength2(bytes, offset) {
|
|
12343
|
+
const first = bytes[offset];
|
|
12344
|
+
if (first === void 0)
|
|
12345
|
+
throw new Error("Truncated ASN.1 length!");
|
|
12346
|
+
if (first < 128)
|
|
12347
|
+
return { length: first, size: 1 };
|
|
12348
|
+
const count = first & 127;
|
|
12349
|
+
if (count === 0 || count > 4)
|
|
12350
|
+
throw new Error("Unsupported ASN.1 length!");
|
|
12351
|
+
let length = 0;
|
|
12352
|
+
for (let index = 1; index <= count; index++) {
|
|
12353
|
+
const byte = bytes[offset + index];
|
|
12354
|
+
if (byte === void 0)
|
|
12355
|
+
throw new Error("Truncated ASN.1 length!");
|
|
12356
|
+
length = length * 256 + byte;
|
|
12357
|
+
}
|
|
12358
|
+
return { length, size: count + 1 };
|
|
12359
|
+
}
|
|
12360
|
+
function subjectPublicKeyInfoKeyMaterial(spki) {
|
|
12361
|
+
if (spki[0] !== 48)
|
|
12362
|
+
throw new Error("A SubjectPublicKeyInfo must start with a SEQUENCE!");
|
|
12363
|
+
let index = 1 + readDERLength2(spki, 1).size;
|
|
12364
|
+
if (spki[index] !== 48)
|
|
12365
|
+
throw new Error("The SubjectPublicKeyInfo does not start with an AlgorithmIdentifier!");
|
|
12366
|
+
const algorithmLength = readDERLength2(spki, index + 1);
|
|
12367
|
+
index += 1 + algorithmLength.size + algorithmLength.length;
|
|
12368
|
+
if (spki[index] !== 3)
|
|
12369
|
+
throw new Error("The SubjectPublicKeyInfo does not contain a BIT STRING!");
|
|
12370
|
+
const keyLength = readDERLength2(spki, index + 1);
|
|
12371
|
+
const start = index + 1 + keyLength.size;
|
|
12372
|
+
if (spki[start] !== 0)
|
|
12373
|
+
throw new Error("The SubjectPublicKeyInfo BIT STRING has unused bits!");
|
|
12374
|
+
const keyMaterial = spki.subarray(start + 1, start + keyLength.length);
|
|
12375
|
+
if (keyMaterial.length === 0)
|
|
12376
|
+
throw new Error("The SubjectPublicKeyInfo contains no key material!");
|
|
12377
|
+
return keyMaterial;
|
|
12378
|
+
}
|
|
12379
|
+
function wrapInSubjectPublicKeyInfo(keyMaterial, algorithm) {
|
|
12380
|
+
const header = subjectPublicKeyInfoHeaders[algorithm];
|
|
12381
|
+
if (header === void 0)
|
|
12382
|
+
throw new Error("Cannot wrap a raw " + algorithm + " key into a SubjectPublicKeyInfo!");
|
|
12383
|
+
const headerBytes = hexToBytes(header);
|
|
12384
|
+
const spki = new Uint8Array(headerBytes.length + keyMaterial.length);
|
|
12385
|
+
spki.set(headerBytes, 0);
|
|
12386
|
+
spki.set(keyMaterial, headerBytes.length);
|
|
12387
|
+
return spki;
|
|
12388
|
+
}
|
|
12389
|
+
function decodeText(value, encoding) {
|
|
12390
|
+
switch (encoding) {
|
|
12391
|
+
case "hex":
|
|
12392
|
+
return hexToBytes(value);
|
|
12393
|
+
case "base64":
|
|
12394
|
+
return base64ToBytes(value);
|
|
12395
|
+
default:
|
|
12396
|
+
throw new Error("Unsupported text encoding: " + String(encoding));
|
|
12397
|
+
}
|
|
12398
|
+
}
|
|
12399
|
+
function encodeText(bytes, encoding) {
|
|
12400
|
+
switch (encoding) {
|
|
12401
|
+
case "hex":
|
|
12402
|
+
return bytesToHex(bytes).toUpperCase();
|
|
12403
|
+
case "base64":
|
|
12404
|
+
return bytesToBase64(bytes);
|
|
12405
|
+
default:
|
|
12406
|
+
return null;
|
|
12407
|
+
}
|
|
12408
|
+
}
|
|
12409
|
+
function publicKeyBytes(publicKey, structure) {
|
|
12410
|
+
const storedStructure = publicKey.encodings[0];
|
|
12411
|
+
const storedBytes = decodeText(publicKey.value, publicKey.encodings[publicKey.encodings.length - 1]);
|
|
12412
|
+
if (storedStructure === structure)
|
|
12413
|
+
return storedBytes;
|
|
12414
|
+
if (storedStructure === "SubjectPublicKeyInfo" && structure === "raw")
|
|
12415
|
+
return subjectPublicKeyInfoKeyMaterial(storedBytes);
|
|
12416
|
+
if (storedStructure === "raw" && structure === "SubjectPublicKeyInfo")
|
|
12417
|
+
return wrapInSubjectPublicKeyInfo(storedBytes, publicKey.algorithm);
|
|
12418
|
+
throw new Error("Cannot represent a " + String(storedStructure) + " key as " + structure + "!");
|
|
12419
|
+
}
|
|
12420
|
+
function computeKeyId(publicKey, keyIdGeneration) {
|
|
12421
|
+
let index = 0;
|
|
12422
|
+
const structure = keyIdGeneration[index++];
|
|
12423
|
+
if (structure === void 0)
|
|
12424
|
+
return null;
|
|
12425
|
+
if (structure === "SubjectPublicKeyInfo" && keyIdGeneration[index] === "DER")
|
|
12426
|
+
index++;
|
|
12427
|
+
let bytes;
|
|
12428
|
+
try {
|
|
12429
|
+
bytes = publicKeyBytes(publicKey, structure);
|
|
12430
|
+
} catch {
|
|
12431
|
+
return null;
|
|
12432
|
+
}
|
|
12433
|
+
for (; index < keyIdGeneration.length; index++) {
|
|
12434
|
+
const step = keyIdGeneration[index];
|
|
12435
|
+
if (step === void 0)
|
|
12436
|
+
return null;
|
|
12437
|
+
switch (step) {
|
|
12438
|
+
case "SHA-256":
|
|
12439
|
+
bytes = sha256$1(bytes);
|
|
12440
|
+
break;
|
|
12441
|
+
case "SHA-384":
|
|
12442
|
+
bytes = sha384$1(bytes);
|
|
12443
|
+
break;
|
|
12444
|
+
case "SHA-512":
|
|
12445
|
+
bytes = sha512$1(bytes);
|
|
12446
|
+
break;
|
|
12447
|
+
// A pipeline ends with the text encoding of the id.
|
|
12448
|
+
default:
|
|
12449
|
+
return encodeText(bytes, step);
|
|
12450
|
+
}
|
|
12451
|
+
}
|
|
12452
|
+
return null;
|
|
12453
|
+
}
|
|
12454
|
+
function nobleSignatureAlgorithm(algorithm) {
|
|
12455
|
+
switch (algorithm) {
|
|
12456
|
+
case "ECDSA-secp256r1-SHA256":
|
|
12457
|
+
return "ECDSA-P256";
|
|
12458
|
+
case "ECDSA-secp384r1-SHA384":
|
|
12459
|
+
return "ECDSA-P384";
|
|
12460
|
+
case "ECDSA-secp521r1-SHA512":
|
|
12461
|
+
return "ECDSA-P521";
|
|
12462
|
+
case "EdDSA-Ed25519":
|
|
12463
|
+
return "Ed25519";
|
|
12464
|
+
case "EdDSA-Ed448":
|
|
12465
|
+
return "Ed448";
|
|
12466
|
+
case "ML-DSA-44":
|
|
12467
|
+
return "ML-DSA-44";
|
|
12468
|
+
case "ML-DSA-65":
|
|
12469
|
+
return "ML-DSA-65";
|
|
12470
|
+
case "ML-DSA-87":
|
|
12471
|
+
return "ML-DSA-87";
|
|
12472
|
+
default:
|
|
12473
|
+
return null;
|
|
12474
|
+
}
|
|
12475
|
+
}
|
|
12476
|
+
function asStringArray(value) {
|
|
12477
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : void 0;
|
|
12478
|
+
}
|
|
12479
|
+
function collectDocumentPublicKeys(Document) {
|
|
12480
|
+
const publicKeys = new Array();
|
|
12481
|
+
const collectFrom = (candidates) => {
|
|
12482
|
+
if (!Array.isArray(candidates))
|
|
12483
|
+
return;
|
|
12484
|
+
for (const candidate of candidates) {
|
|
12485
|
+
const entry = asJSONObject(candidate);
|
|
12486
|
+
if (entry === void 0)
|
|
12487
|
+
continue;
|
|
12488
|
+
const algorithm = asString(entry["algorithm"]);
|
|
12489
|
+
const value = asString(entry["value"]);
|
|
12490
|
+
const encodings = asStringArray(entry["encodings"]);
|
|
12491
|
+
const keyUsage = asStringArray(entry["keyUsage"]) ?? [];
|
|
12492
|
+
if (algorithm === void 0 || algorithm === "" || value === void 0 || value === "" || encodings === void 0 || encodings.length === 0) {
|
|
12493
|
+
continue;
|
|
12494
|
+
}
|
|
12495
|
+
publicKeys.push({ algorithm, encodings, value, keyUsage });
|
|
12496
|
+
}
|
|
12497
|
+
};
|
|
12498
|
+
const chargingStation = asJSONObject(Document["chargingStation"]);
|
|
12499
|
+
const evse = asJSONObject(chargingStation?.["EVSE"]);
|
|
12500
|
+
collectFrom(asJSONObject(Document["chargingStationOperator"])?.["publicKeys"]);
|
|
12501
|
+
collectFrom(asJSONObject(evse?.["energyMeter"])?.["publicKeys"]);
|
|
12502
|
+
return publicKeys;
|
|
12503
|
+
}
|
|
12504
|
+
function verifyDocumentSignature(Document, Signature, Index, PublicKeys, KeyIdGeneration) {
|
|
12505
|
+
const entry = asJSONObject(Signature);
|
|
12506
|
+
if (entry === void 0)
|
|
12507
|
+
return { index: Index, status: "malformed", details: "The signature is not a JSON object." };
|
|
12508
|
+
const keyId = asString(entry["keyId"]);
|
|
12509
|
+
const algorithm = asString(entry["algorithm"]);
|
|
12510
|
+
const value = asString(entry["value"]);
|
|
12511
|
+
const encodings = asStringArray(entry["encodings"]);
|
|
12512
|
+
const signedData = asJSONObject(entry["signedData"]);
|
|
12513
|
+
const described = (status, details) => ({
|
|
12514
|
+
index: Index,
|
|
12515
|
+
...keyId !== void 0 ? { keyId } : {},
|
|
12516
|
+
...algorithm !== void 0 ? { algorithm } : {},
|
|
12517
|
+
status,
|
|
12518
|
+
...details !== void 0 ? { details } : {}
|
|
12519
|
+
});
|
|
12520
|
+
if (keyId === void 0 || keyId === "" || algorithm === void 0 || algorithm === "" || value === void 0 || value === "" || encodings === void 0 || encodings.length === 0) {
|
|
12521
|
+
return described("malformed", "A signature needs a keyId, an algorithm, encodings and a value.");
|
|
12522
|
+
}
|
|
12523
|
+
const signedEncodings = asStringArray(signedData?.["encodings"]) ?? canonicalJSONEncodings;
|
|
12524
|
+
if (signedEncodings.length !== canonicalJSONEncodings.length || !signedEncodings.every((step, position) => step === canonicalJSONEncodings[position])) {
|
|
12525
|
+
return described(
|
|
12526
|
+
"unsupportedAlgorithm",
|
|
12527
|
+
"Only [ " + canonicalJSONEncodings.join(", ") + " ] signed data is understood here."
|
|
12528
|
+
);
|
|
12529
|
+
}
|
|
12530
|
+
const excludedProperties = asStringArray(signedData?.["excludedProperties"]) ?? defaultExcludedProperties;
|
|
12531
|
+
if (!excludedProperties.includes("signatures"))
|
|
12532
|
+
excludedProperties.push("signatures");
|
|
12533
|
+
let signedBytes;
|
|
12534
|
+
try {
|
|
12535
|
+
signedBytes = canonicalJSONBytes(
|
|
12536
|
+
Object.fromEntries(
|
|
12537
|
+
Object.entries(Document).filter(([property]) => !excludedProperties.includes(property))
|
|
12538
|
+
)
|
|
12539
|
+
);
|
|
12540
|
+
} catch (exception) {
|
|
12541
|
+
return described(
|
|
12542
|
+
"malformed",
|
|
12543
|
+
"The signed properties could not be canonicalized: " + (exception instanceof Error ? exception.message : String(exception))
|
|
12544
|
+
);
|
|
12545
|
+
}
|
|
12546
|
+
const suiteAlgorithm = nobleSignatureAlgorithm(algorithm);
|
|
12547
|
+
if (suiteAlgorithm === null)
|
|
12548
|
+
return described("unsupportedAlgorithm", "Unsupported signature algorithm: " + algorithm);
|
|
12549
|
+
const wantedKeyId = keyId.toUpperCase();
|
|
12550
|
+
const publicKey = PublicKeys.find((candidate) => computeKeyId(candidate, KeyIdGeneration)?.toUpperCase() === wantedKeyId);
|
|
12551
|
+
if (publicKey === void 0)
|
|
12552
|
+
return described("unknownPublicKey", "No public key of this document has the key id " + keyId + ".");
|
|
12553
|
+
try {
|
|
12554
|
+
const suite = getSignatureSuite(suiteAlgorithm);
|
|
12555
|
+
const publicKeyBytes_ = publicKeyBytes(publicKey, "raw");
|
|
12556
|
+
const signatureBytes = decodeText(value, encodings[encodings.length - 1]);
|
|
12557
|
+
if (!suite.isValidPublicKey(publicKeyBytes_))
|
|
12558
|
+
return described("malformed", "The public key is not valid for " + algorithm + ".");
|
|
12559
|
+
return described(suite.verify(signedBytes, signatureBytes, publicKeyBytes_) ? "validSignature" : "invalidSignature");
|
|
12560
|
+
} catch (exception) {
|
|
12561
|
+
return described(
|
|
12562
|
+
"malformed",
|
|
12563
|
+
exception instanceof Error ? exception.message : String(exception)
|
|
12564
|
+
);
|
|
12565
|
+
}
|
|
12566
|
+
}
|
|
12567
|
+
function verifyDocumentSignatures(Document) {
|
|
12568
|
+
const signatures = Document["signatures"];
|
|
12569
|
+
if (!Array.isArray(signatures) || signatures.length === 0)
|
|
12570
|
+
return { status: "unsigned", signatures: [], validCount: 0 };
|
|
12571
|
+
const keyIdGeneration = asStringArray(Document["keyIdGeneration"]) ?? defaultKeyIdGeneration;
|
|
12572
|
+
const publicKeys = collectDocumentPublicKeys(Document);
|
|
12573
|
+
const results = signatures.map(
|
|
12574
|
+
(signature, index) => verifyDocumentSignature(Document, signature, index, publicKeys, keyIdGeneration)
|
|
12575
|
+
);
|
|
12576
|
+
const validCount = results.filter((result) => result.status === "validSignature").length;
|
|
12577
|
+
return {
|
|
12578
|
+
status: validCount === 0 ? "noneValid" : validCount === results.length ? "allValid" : "someValid",
|
|
12579
|
+
signatures: results,
|
|
12580
|
+
validCount
|
|
12581
|
+
};
|
|
12582
|
+
}
|
|
12583
|
+
|
|
12584
|
+
// src/chargy.ts
|
|
12332
12585
|
function isPdfAttachment(value) {
|
|
12333
12586
|
if (!isMandatoryJSONObject(value))
|
|
12334
12587
|
return false;
|
|
@@ -13265,6 +13518,7 @@ var Chargy = class {
|
|
|
13265
13518
|
throw new Error("Parsed JSON content is not a JSON object!");
|
|
13266
13519
|
const JSONContext = JSONContent["@context"];
|
|
13267
13520
|
if (IsAChargeTransparencyLiveLink(JSONContent)) {
|
|
13521
|
+
this.verifyLiveLinkSignatures(JSONContent);
|
|
13268
13522
|
JSONContent.created ??= (/* @__PURE__ */ new Date()).toISOString();
|
|
13269
13523
|
processedFile.result = JSONContent;
|
|
13270
13524
|
} else if (JSONContent["format"] === "ptb")
|
|
@@ -13434,6 +13688,56 @@ var Chargy = class {
|
|
|
13434
13688
|
return IsAChargeTransparencyRecord(verifiedCTR) ? verifiedCTR : void 0;
|
|
13435
13689
|
}
|
|
13436
13690
|
//#endregion
|
|
13691
|
+
//#region (private) verifyLiveLinkSignatures(LiveLink)
|
|
13692
|
+
// A live link may be signed as a whole by the operator, which is what ties
|
|
13693
|
+
// the transport URLs and the listed public keys to whoever signed them.
|
|
13694
|
+
// Those signatures are verified whenever the document carries any.
|
|
13695
|
+
//
|
|
13696
|
+
// Nothing here rejects a document. An unsigned live link, an unknown key or
|
|
13697
|
+
// even a signature that does not match is reported as a warning and the
|
|
13698
|
+
// document stays usable: its transports still work, and its signed meter
|
|
13699
|
+
// values carry their own signatures, which are verified separately. What a
|
|
13700
|
+
// reader makes of the warning is the reader's decision.
|
|
13701
|
+
//
|
|
13702
|
+
// Must run before anything is added to the document - see the note at the
|
|
13703
|
+
// call site.
|
|
13704
|
+
verifyLiveLinkSignatures(LiveLink) {
|
|
13705
|
+
const result = verifyDocumentSignatures(LiveLink);
|
|
13706
|
+
const warnings = new Array();
|
|
13707
|
+
const warn = (messageKey, level) => {
|
|
13708
|
+
const message = this.GetMultilanguageText(messageKey);
|
|
13709
|
+
if (!warnings.some((warning) => warning.message === message))
|
|
13710
|
+
warnings.push({ level, message });
|
|
13711
|
+
};
|
|
13712
|
+
if (result.status === "unsigned")
|
|
13713
|
+
warn("DocumentSignature_Missing", "low" /* low */);
|
|
13714
|
+
for (const signature of result.signatures) {
|
|
13715
|
+
switch (signature.status) {
|
|
13716
|
+
case "validSignature":
|
|
13717
|
+
break;
|
|
13718
|
+
// A signature that demonstrably does not match its document is
|
|
13719
|
+
// the one case that says something is actually wrong.
|
|
13720
|
+
case "invalidSignature":
|
|
13721
|
+
warn("DocumentSignature_Mismatch", "high" /* high */);
|
|
13722
|
+
break;
|
|
13723
|
+
// The rest mean "cannot be judged here", which is a weaker
|
|
13724
|
+
// statement than "is wrong".
|
|
13725
|
+
case "unknownPublicKey":
|
|
13726
|
+
warn("DocumentSignature_UnknownPublicKey", "medium" /* medium */);
|
|
13727
|
+
break;
|
|
13728
|
+
case "unsupportedAlgorithm":
|
|
13729
|
+
warn("DocumentSignature_UnsupportedAlgorithm", "medium" /* medium */);
|
|
13730
|
+
break;
|
|
13731
|
+
case "malformed":
|
|
13732
|
+
warn("DocumentSignature_Malformed", "medium" /* medium */);
|
|
13733
|
+
break;
|
|
13734
|
+
}
|
|
13735
|
+
}
|
|
13736
|
+
LiveLink.signatureVerification = result;
|
|
13737
|
+
if (warnings.length > 0)
|
|
13738
|
+
LiveLink.warnings = [...LiveLink.warnings ?? [], ...warnings];
|
|
13739
|
+
}
|
|
13740
|
+
//#endregion
|
|
13437
13741
|
//#region (private) collectLiveLinkMeterValueKeys(LiveLink)
|
|
13438
13742
|
// Every public key of the document that is allowed to sign meter values.
|
|
13439
13743
|
// A charging session is regularly signed by more than one of them: the
|
|
@@ -13813,6 +14117,6 @@ buffer/index.js:
|
|
|
13813
14117
|
*)
|
|
13814
14118
|
*/
|
|
13815
14119
|
|
|
13816
|
-
export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CreateError, CreateWarning, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EDL40, EDL40Crypt01, EDL40ValidationError, EDL40_OBIS, EDL40_SESSION_CONTEXT, EDL40_SIGNATURE_CONTEXT, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKey, IsAPublicKeyLookup, IsAPublicKeySignature, IsAPublicKeyXY, IsASessionCryptoResult, IsAURL, IsNullOrEmpty, IsValidURL, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFBonnTariffParseError, OCMFTransactionTypes, OCMF_SIGNATURE_ALGORITHMS, OCMFv1_x, OCPI, OIDInfo, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, PTB, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, IURL_exports as SimpleURL, TimeStatusTypes, URLContext, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, base64ToBytes, buf2hex, buildEDL40Signature, buildIsaSignature, buildMennekesSignatureData, bytesToBase64, bytesToHex, canParseEDL40, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, createCompatibleCurve, createHexString, createLegacyP192Curve, dateToMennekesLocalEpochSeconds, decodeSmlMessages, extractMennekesChargingProcesses, findEntryByObis, findGetListRes, firstKey, firstValue, generateSignatureKeyPair, getArrayElement, getArrayLikeElement, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getFirstArrayElement, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getLastArrayElement, getOCMFSignatureDisplay, getSignatureSuite, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isEncodedValue, isGeoLocation, isI18NString, isICryptoResult, isIFileInfo, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalStringArray, isOptionalStringOrOIDInfo, isOptionalURL, isPCDFText, isPublicKeySubject, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, isaListNameContext, jsonPrettyPrinter, measurementName2human, meterTimeZone, normalizePCDFPublicKeyHex, normalizeXMLText, ocmfBonnTariffToChargingTariff, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseEDL40, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parseOCMFBonnTariffText, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseSmlTime, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, readTLV, secp224k1, setUILocale, sha256, sha256____, sha384, sha384____, sha512, sha512____, signJSONMessage, signMessage, stripPCDFControlCharacters, stripTransport, time2human, timeZoneOffsetMinutes, toArrayBuffer, toSessionVerificationResults, toUint8Array, transformEDL40Status, tryParseOCMFBonnTariffText, unquotePCDFText, validatePCDFFields, verifyEDL40Document, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
|
|
14120
|
+
export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CreateError, CreateWarning, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EDL40, EDL40Crypt01, EDL40ValidationError, EDL40_OBIS, EDL40_SESSION_CONTEXT, EDL40_SIGNATURE_CONTEXT, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKey, IsAPublicKeyLookup, IsAPublicKeySignature, IsAPublicKeyXY, IsASessionCryptoResult, IsAURL, IsNullOrEmpty, IsValidURL, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFBonnTariffParseError, OCMFTransactionTypes, OCMF_SIGNATURE_ALGORITHMS, OCMFv1_x, OCPI, OIDInfo, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, PTB, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, IURL_exports as SimpleURL, TimeStatusTypes, URLContext, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, base64ToBytes, buf2hex, buildEDL40Signature, buildIsaSignature, buildMennekesSignatureData, bytesToBase64, bytesToHex, canParseEDL40, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, collectDocumentPublicKeys, createCompatibleCurve, createHexString, createLegacyP192Curve, dateToMennekesLocalEpochSeconds, decodeSmlMessages, extractMennekesChargingProcesses, findEntryByObis, findGetListRes, firstKey, firstValue, generateSignatureKeyPair, getArrayElement, getArrayLikeElement, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getFirstArrayElement, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getLastArrayElement, getOCMFSignatureDisplay, getSignatureSuite, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isEncodedValue, isGeoLocation, isI18NString, isICryptoResult, isIFileInfo, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalStringArray, isOptionalStringOrOIDInfo, isOptionalURL, isPCDFText, isPublicKeySubject, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, isaListNameContext, jsonPrettyPrinter, measurementName2human, meterTimeZone, normalizePCDFPublicKeyHex, normalizeXMLText, ocmfBonnTariffToChargingTariff, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseEDL40, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parseOCMFBonnTariffText, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseSmlTime, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, readTLV, secp224k1, setUILocale, sha256, sha256____, sha384, sha384____, sha512, sha512____, signJSONMessage, signMessage, stripPCDFControlCharacters, stripTransport, time2human, timeZoneOffsetMinutes, toArrayBuffer, toSessionVerificationResults, toUint8Array, transformEDL40Status, tryParseOCMFBonnTariffText, unquotePCDFText, validatePCDFFields, verifyDocumentSignatures, verifyEDL40Document, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
|
|
13817
14121
|
//# sourceMappingURL=index.js.map
|
|
13818
14122
|
//# sourceMappingURL=index.js.map
|