From 429a5a6c8c3dd0491b803aae59716761e5642776 Mon Sep 17 00:00:00 2001 From: Achim Friedland Date: Sun, 5 May 2024 07:20:20 +0200 Subject: [PATCH 1/2] Add PKI details screen --- src/index.html | 28 +++++++ src/scss/chargy.scss | 37 ++++++++- src/ts/EMHCrypt01.ts | 32 +++++--- src/ts/chargy.ts | 43 ++++++----- src/ts/chargyApp.ts | 149 +++++++++++++++++++++++++++++-------- src/ts/chargyInterfaces.ts | 2 + 6 files changed, 226 insertions(+), 65 deletions(-) diff --git a/src/index.html b/src/index.html index d7a2b7a..c9298a6 100644 --- a/src/index.html +++ b/src/index.html @@ -528,6 +528,34 @@

Datenschutzerklärung für diesen Mängelmelder

+
+
+ +
+ +
+ +
+ Public Key Infrastructure +
+ +
+ +
+
+ +
+ +
+ + + +
+ +
+ diff --git a/src/scss/chargy.scss b/src/scss/chargy.scss index 7881a28..8786100 100644 --- a/src/scss/chargy.scss +++ b/src/scss/chargy.scss @@ -268,6 +268,9 @@ body { font-family: monospace; font-size: 110%; margin-top: 3px; + background-color: rgb(192 192 192 / 30%); + padding: 6px 8px; + border-radius: 4px; } #sigHead { @@ -495,7 +498,7 @@ body { .signer { display: table-cell; padding: 2px 0px 2px 5px; - vertical-align: middle; + vertical-align: middle; font-size: 85%; } @@ -2046,13 +2049,20 @@ body { .signatures { display: flex; - padding: 3px 0px 0px 0px; + padding-left: 5px; font-family: sans-serif; font-size: 70%; color: #6d6d6d; - i { - padding: 0px 3px 0px 10px; + .signature { + + padding: 3px 7px 2px 5px; + cursor: zoom-in; + + i { + padding-right: 4px; + } + } } @@ -2102,6 +2112,7 @@ body { form { + flex-grow: 2; padding: 5px 20px 20px 20px; .label { @@ -2209,6 +2220,24 @@ body { } + #pkiDetails { + + display: none; + + .overlayText { + + .footer { + + .overlayRightButton { + visibility: hidden; + } + + } + + } + + } + } .fullScreen { diff --git a/src/ts/EMHCrypt01.ts b/src/ts/EMHCrypt01.ts index 7553e17..d7fdcd9 100644 --- a/src/ts/EMHCrypt01.ts +++ b/src/ts/EMHCrypt01.ts @@ -366,16 +366,28 @@ export class EMHCrypt01 extends ACrypt { try { - const signatureDiv = PublicKeyDiv?.parentElement?.children[3]?.appendChild(document.createElement('div')); - - if (signatureDiv != null) - signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(measurementValue.measurement.chargingSession?.chargingStation, - measurementValue.measurement.chargingSession?.EVSE, - //@ts-ignore - measurementValue.measurement.chargingSession.EVSE.meters[0], - //@ts-ignore - measurementValue.measurement.chargingSession.EVSE.meters[0].publicKeys[0], - signature); + const signatureDiv = PublicKeyDiv.parentElement?.children[3]?.appendChild(document.createElement('div')); + + if (signatureDiv) + { + + signatureDiv.classList.add("signature"); + + signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature( + measurementValue.measurement.chargingSession?.chargingStation, + measurementValue.measurement.chargingSession?.EVSE, + //@ts-ignore + measurementValue.measurement.chargingSession.EVSE.meters[0], + //@ts-ignore + measurementValue.measurement.chargingSession.EVSE.meters[0].publicKeys[0], + signature + ); + + signatureDiv.onclick = () => { + this.chargy.showPKIDetails({}); + } + + } } catch (exception) diff --git a/src/ts/chargy.ts b/src/ts/chargy.ts index e27f621..7aa67d3 100644 --- a/src/ts/chargy.ts +++ b/src/ts/chargy.ts @@ -38,12 +38,13 @@ export class Chargy { //#region Data - public readonly i18n: any; - public readonly UILanguage: string; - public readonly elliptic: any; - public readonly moment: any; - public readonly asn1: any; - public readonly base32Decode: any; + public readonly i18n: any; + public readonly UILanguage: string; + public readonly elliptic: any; + public readonly moment: any; + public readonly asn1: any; + public readonly base32Decode: any; + public readonly showPKIDetails: chargyInterfaces.ShowPKIDetailsFunction; private chargingStationOperators = new Array(); private chargingPools = new Array(); @@ -60,19 +61,21 @@ export class Chargy { //#endregion - constructor(i18n: any, - UILanguage: string, - elliptic: any, - moment: any, - asn1: any, - base32Decode: any) { - - this.i18n = i18n; - this.UILanguage = UILanguage; - this.elliptic = elliptic; - this.moment = moment; - this.asn1 = asn1; - this.base32Decode = base32Decode; + constructor(i18n: any, + UILanguage: string, + elliptic: any, + moment: any, + asn1: any, + base32Decode: any, + ShowPKIDetails: chargyInterfaces.ShowPKIDetailsFunction) { + + this.i18n = i18n; + this.UILanguage = UILanguage; + this.elliptic = elliptic; + this.moment = moment; + this.asn1 = asn1; + this.base32Decode = base32Decode; + this.showPKIDetails = ShowPKIDetails; } @@ -239,7 +242,7 @@ export class Chargy { // update(Input, 'utf8'). // digest('hex'); - var result = new this.elliptic.ec('secp256k1'). + var result = new this.elliptic.ec('secp256r1'). keyFromPublic(signature.publicKey, 'hex'). verify (sha256value, signature.signature); diff --git a/src/ts/chargyApp.ts b/src/ts/chargyApp.ts index 826ea96..ee5dbac 100644 --- a/src/ts/chargyApp.ts +++ b/src/ts/chargyApp.ts @@ -73,6 +73,8 @@ export class ChargyApp { private aboutScreenDiv: HTMLDivElement; private applicationHashDiv: HTMLDivElement; private applicationHashValueDiv: HTMLDivElement; + private softwareInfosDiv: HTMLDivElement; + private openSourceLibsDiv: HTMLDivElement; private chargingSessionScreenDiv: HTMLDivElement; private invalidDataSetsScreenDiv: HTMLDivElement; private inputButtonsDiv: HTMLDivElement; @@ -86,31 +88,31 @@ export class ChargyApp { private errorTextDiv: HTMLDivElement; private feedbackDiv: HTMLDivElement; + private showFeedbackSection: Boolean; + private feedbackMethodsDiv: HTMLDivElement; + private feedbackEMailAnchor: HTMLAnchorElement; + private feedbackHotlineAnchor: HTMLAnchorElement; + private showIssueTrackerButton: HTMLButtonElement; + private issueTrackerText: HTMLDivElement; + private chargingTariffDetailsDiv: HTMLDivElement; private chargingTariffDetailsLeftButton: HTMLButtonElement; - private chargingPeriodDetailsDiv: HTMLDivElement; - private chargingPeriodDetailsLeftButton: HTMLButtonElement; + private chargingPeriodDetailsDiv: HTMLDivElement; + private chargingPeriodDetailsLeftButton: HTMLButtonElement; private measurementsDetailsDiv: HTMLDivElement; private measurementsDetailsLeftButton: HTMLButtonElement; -// private measurementsDetailsButton: HTMLButtonElement; - private issueTrackerDiv: HTMLDivElement; - private privacyStatement: HTMLDivElement; - private showFeedbackSection: Boolean; - private feedbackMethodsDiv: HTMLDivElement; - private feedbackEMailAnchor: HTMLAnchorElement; - private feedbackHotlineAnchor: HTMLAnchorElement; - private showIssueTrackerButton: HTMLButtonElement; - private issueTrackerText: HTMLDivElement; - private sendIssueButton: HTMLButtonElement; + private issueTrackerDiv: HTMLDivElement; private issueTrackerLeftButton: HTMLButtonElement; - + private privacyStatement: HTMLDivElement; private showPrivacyStatement: HTMLButtonElement; private privacyStatementAccepted: HTMLInputElement; - private softwareInfosDiv: HTMLDivElement; - private openSourceLibsDiv: HTMLDivElement; + private sendIssueButton: HTMLButtonElement; + + private pkiDetailsDiv: HTMLDivElement; + private pkiDetailsLeftButton: HTMLButtonElement; //#endregion @@ -213,6 +215,12 @@ export class ChargyApp { this.issueTrackerDiv.style.display = 'none'; } + this.pkiDetailsDiv = document.getElementById('pkiDetails') as HTMLDivElement; + this.pkiDetailsLeftButton = this.pkiDetailsDiv.querySelector(".overlayLeftButton") as HTMLButtonElement; + this.pkiDetailsLeftButton.onclick = () => { + this.pkiDetailsDiv.style.display = 'none'; + } + this.fileInputButton = document.getElementById('fileInputButton') as HTMLButtonElement; this.pasteButton = document.getElementById('pasteButton') as HTMLButtonElement; @@ -224,12 +232,15 @@ export class ChargyApp { //#endregion - this.chargy = new Chargy(this.i18n, - this.UILanguage, - this.elliptic, - this.moment, - this.asn1, - this.base32Decode); + this.chargy = new Chargy( + this.i18n, + this.UILanguage, + this.elliptic, + this.moment, + this.asn1, + this.base32Decode, + this.showPKIDetails.bind(this) + ); //#region OnWindowResize @@ -630,6 +641,7 @@ export class ChargyApp { //#endregion + //#region (private) loadI18n() private async loadI18n() { try { @@ -647,6 +659,10 @@ export class ChargyApp { } } + //#endregion + + //#region (private) loadPackageJSON() + private async loadPackageJSON() { try { @@ -700,8 +716,7 @@ export class ChargyApp { } } - - + //#endregion //#region UpdateFeedbackSection() @@ -961,7 +976,7 @@ export class ChargyApp { //#endregion - //#region calcApplicationHash(...) + //#region calcApplicationHash (...) private async calcApplicationHash() { @@ -992,7 +1007,7 @@ export class ChargyApp { //#endregion - //#region checkApplicationHashSignature(...) + //#region checkApplicationHashSignature (...) private checkApplicationHashSignature(app: any, version: any, @@ -1064,7 +1079,7 @@ export class ChargyApp { //#endregion - //#region detectAndConvertContentFormat(FileInfos) + //#region detectAndConvertContentFormat (FileInfos) private async detectAndConvertContentFormat(FileInfos: Array|chargyInterfaces.IFileInfo|string) { @@ -1108,7 +1123,7 @@ export class ChargyApp { //#endregion - //#region showChargeTransparencyRecord(CTR) + //#region showChargeTransparencyRecord (CTR) private async showChargeTransparencyRecord(CTR: chargyInterfaces.IChargeTransparencyRecord) { @@ -1984,7 +1999,7 @@ export class ChargyApp { //#endregion - //#region showChargingSessionDetails + //#region showChargingSessionDetails (chargingSession) private async showChargingSessionDetails(chargingSession: chargyInterfaces.IChargingSession) { @@ -2715,7 +2730,7 @@ export class ChargyApp { //#endregion - //#region showChargingTariffDetails + //#region showChargingTariffDetails (measurementValue) private showChargingTariffDetails(measurementValue: chargyInterfaces.IChargingTariff) : void { @@ -2787,7 +2802,7 @@ export class ChargyApp { //#endregion - //#region showChargingPeriodDetails + //#region showChargingPeriodDetails (chargingPeriod) private showChargingPeriodDetails(chargingPeriod: chargyInterfaces.IChargingPeriod) : void { @@ -2859,7 +2874,7 @@ export class ChargyApp { //#endregion - //#region showMeasurementCryptoDetails + //#region showMeasurementCryptoDetails (measurementValue) private showMeasurementCryptoDetails(measurementValue: chargyInterfaces.IMeasurementValue) : void { @@ -2931,6 +2946,78 @@ export class ChargyApp { //#endregion + //#region showPKIDetails (pkiData) + + private showPKIDetails(pkiData: any) : void + { + + function doError(text: String) + { + errorDiv.innerHTML = ' ' + text; + introDiv.style.display = "none"; + } + + //#region Headline + + const headlineDiv = this.pkiDetailsDiv.querySelector('.headline') as HTMLDivElement; + const errorDiv = headlineDiv. querySelector('.error') as HTMLDivElement; + const introDiv = headlineDiv. querySelector('.intro') as HTMLDivElement; + errorDiv.innerHTML = ""; + introDiv.style.display = "block"; + + //#endregion + + // if (!measurementValue?.measurement || + // !measurementValue.method) + // { + // doError(this.chargy.GetLocalizedMessage("Unknown meter data record format!")); + // return; + // } + + //#region Show data and result on overlay + + this.pkiDetailsDiv.style.display = 'block'; + + // const dataDiv = this.overlayDiv.querySelector('.data') as HTMLDivElement; + // const cryptoDataDiv = dataDiv. querySelector('#cryptoData') as HTMLDivElement; + // const bufferDiv = dataDiv. querySelector('#buffer .value') as HTMLDivElement; + // const hashedBufferDiv = dataDiv. querySelector('#hashedBuffer .value') as HTMLDivElement; + // const publicKeyDiv = dataDiv. querySelector('#publicKey .value') as HTMLDivElement; + // const signatureExpectedDiv = dataDiv. querySelector('#signatureExpected .value') as HTMLDivElement; + + // cryptoDataDiv.innerHTML = ''; + // bufferDiv.innerHTML = ''; + // hashedBufferDiv.innerHTML = '0x00000000000000000000000000000000000'; + // publicKeyDiv.innerHTML = '0x00000000000000000000000000000000000'; + // signatureExpectedDiv.innerHTML = '0x00000000000000000000000000000000000'; + + //#endregion + + //#region Footer + + //const footerDiv = this.measurementsDetailsDiv.querySelector('.footer') as HTMLDivElement; + //const signatureCheckDiv = footerDiv. querySelector('#signatureCheck') as HTMLDivElement; + + //signatureCheckDiv.innerHTML = ''; + + //#endregion + + // measurementValue.method.ViewMeasurement(measurementValue, + // errorDiv, + // introDiv, + + // cryptoDataDiv, + // bufferDiv, + // hashedBufferDiv, + // publicKeyDiv, + // signatureExpectedDiv, + + // signatureCheckDiv); + + } + + //#endregion + } diff --git a/src/ts/chargyInterfaces.ts b/src/ts/chargyInterfaces.ts index 92ab0f7..70fe8b4 100644 --- a/src/ts/chargyInterfaces.ts +++ b/src/ts/chargyInterfaces.ts @@ -912,3 +912,5 @@ export interface IParkingTariff { signatures?: Array } + +export type ShowPKIDetailsFunction = (pkiData: any) => void; From 14547f060b038c948ae5e1bbb27d1a2cd4427d5c Mon Sep 17 00:00:00 2001 From: Achim Friedland Date: Mon, 6 May 2024 14:32:18 +0200 Subject: [PATCH 2/2] Some i18n fixes. PublicKeySignature added to more CTR formats. --- ...eITContainer_externalCostsAndTariff.chargy | 36 +++- src/i18n.json | 170 +++++++++++++++++- src/ts/Alfen.ts | 11 +- src/ts/chargeIT.ts | 11 +- src/ts/chargyInterfaces.ts | 5 + 5 files changed, 219 insertions(+), 14 deletions(-) diff --git a/documentation/Alfen/ALFEN-Testdatensatz-10_newChargeITContainer_externalCostsAndTariff.chargy b/documentation/Alfen/ALFEN-Testdatensatz-10_newChargeITContainer_externalCostsAndTariff.chargy index c672230..40f76b7 100644 --- a/documentation/Alfen/ALFEN-Testdatensatz-10_newChargeITContainer_externalCostsAndTariff.chargy +++ b/documentation/Alfen/ALFEN-Testdatensatz-10_newChargeITContainer_externalCostsAndTariff.chargy @@ -26,7 +26,41 @@ "meterInfo": { "firmwareVersion": "123", "type": "eHZ IW8E EMH", - "manufacturer": "EMH" + "manufacturer": "EMH", + "publicKeySignatures": [ + { + "signer": "Open Charging Cloud", + "publicKey": "04a8ff0d82107922522e004a167cc658f0eef408c5020f98e7a2615be326e61852666877335f4f8d9a0a756c26f0c9fb3f401431416abb5317cc0f5d714d3026fe", + "timestamp": "2019-06-30T00:00:00Z", + "comment": { "en": "Hello world!" }, + "notBefore": "2018-11-04T16:47:01Z", + "notAfter": "2023-03-12T13:54:12Z", + "operations": { + "signCertificates": false, + "signMeterValues": true + }, + "revocationURIs": [], + "algorithm": "secp256k1", + "format": "DER", + "value": "303502181dce9223416d64e5362bc8eb46eddf23adcb74382b602e1f021900eca85b1a48bc1f64d25951e947c7e48fa0b070b82e2cae41" + }, + { + "signer": "chargeIT mobility", + "publicKey": "04a8ff0d82107922522e004a167cc658f0eef408c5020f98e7a2615be326e61852666877335f4f8d9a0a756c26f0c9fb3f401431416abb5317cc0f5d714d3026fe", + "timestamp": "2019-06-30T00:00:00Z", + "comment": { "en": "Hello world!" }, + "notBefore": "2018-11-04T16:47:01Z", + "notAfter": "2023-03-12T13:54:12Z", + "operations": { + "signCertificates": false, + "signMeterValues": true + }, + "revocationURIs": [], + "algorithm": "secp256k1", + "format": "DER", + "value": "303502181dce9223416d64e5362bc8eb46eddf23adcb74382b602e1f021900eca85b1a48bc1f64d25951e947c7e48fa0b070b82e2cae41" + } + ] }, "connectorInfo": { "type": "Typ-2 Socket", diff --git a/src/i18n.json b/src/i18n.json index 723d4ce..1d9c9e1 100644 --- a/src/i18n.json +++ b/src/i18n.json @@ -36,6 +36,16 @@ "en": "No charge transparency records found!" }, + "Invalid number of signed meter values!" : { + "de": "Ungültige Anzahl signierter Messwerte!", + "en": "Invalid number of signed meter values!" + }, + + "Invalid charging session format!": { + "de": "Ungültiges Ladevorgangsformat!", + "en": "Invalid charging session format!" + }, + "Unknown or invalid charge transparency record!": { "de": "Unbekannter oder ungültiger Transparenzdatensatz!", "en": "Unknown or invalid charge transparency record!" @@ -61,6 +71,11 @@ "en": "Unknown or invalid charging session format!" }, + "Inconsistent public keys!": { + "de": "Inkonsistente öffentliche Schlüssel!", + "en": "Inconsistent public keys!" + }, + "ValidChargingSession": { "de": "Gültiger Ladevorgang", "en": "Valid charging session" @@ -98,6 +113,11 @@ "en": "OBIS code" }, + "Inconsistent OBIS code!": { + "de": "Inkonsistente OBIS-Kennzahl!", + "en": "Inconsistent OBIS code!" + }, + "Plain text": { "de": "Klartext", "en": "Plain text" @@ -271,6 +291,11 @@ "en": "Missing or invalid meter information within the %p. signed meter value!" }, + "Inconsistent meter identification!": { + "de": "Inkonsistente Zähleridentifikation!", + "en": "Inconsistent meter identification!" + }, + "MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP": { "de": "Fehlende oder ungültige Zähleridentifikation im %p. signierten Messwert!", "en": "Missing or invalid meter identification within the %p. signed meter value!" @@ -531,6 +556,7 @@ }, + "Charging Tariffs": { "de": "Ladetarife", "en": "Charging Tariffs" @@ -541,9 +567,6 @@ "en": "Charging Tariff Id" }, - - - "Total Costs": { "de": "Gesamtkosten", "en": "Total Costs" @@ -670,6 +693,11 @@ "en": "Unknown charge transparency data format!" }, + "Invalid energy meter": { + "de": "Ungültiger Energiezähler", + "en": "Invalid energy meter" + }, + "Energy meter not found": { "de": "Energiezähler nicht gefunden", "en": "Energy meter not found" @@ -745,6 +773,141 @@ "en": "End value" }, + "Inconsistent Alfen adapter identification!": { + "de": "Inkonsistente Alfen-Adapter-Identifikation!", + "en": "Inconsistent Alfen adapter identification!" + }, + + "Inconsistent Alfen adapter firmware version!": { + "de": "Inkonsistente Alfen-Adapter-Firmwareversion!", + "en": "Inconsistent Alfen adapter firmware version!" + }, + + "Inconsistent Alfen adapter firmware checksum!": { + "de": "Inkonsistente Alfen-Adapter-Firmware-Prüfsumme!", + "en": "Inconsistent Alfen adapter firmware checksum!" + }, + + "Inconsistent unit (encoded) value!" : { + "de": "Inkonsistenter (enkodierter) Einheitenwert!", + "en": "Inconsistent unit (encoded) value!" + }, + + "Inconsistent measurement scalar!" : { + "de": "Inkonsistenter Messwert-Skalierungsfaktor!", + "en": "Inconsistent measurement scalar!" + }, + + "Inconsistent user identification!" : { + "de": "Inkonsistente Benutzeridentifikation!", + "en": "Inconsistent user identification!" + }, + + "Inconsistent internal charging session identification!" : { + "de": "Inkonsistente interne Ladevorgangsidentifikation!", + "en": "Inconsistent internal charging session identification!" + }, + + "Inconsistent timestamps!": { + "de": "Inkonsistente Zeitstempel!", + "en": "Inconsistent timestamps!" + }, + + "Exception occured: ": { + "de": "Ausnahmefehler aufgetreten: ", + "en": "Exception occured: " + }, + + "Hashed plain text": { + "de": "Gehashter Klartext", + "en": "Hashed plain text" + }, + + "Autorisierung": + { + "de": "Autorisierung", + "en": "Authorization" + }, + + "Invalid meter status!": { + "de": "Ungültiger Zählerstatus!", + "en": "Invalid meter status!" + }, + + "RTC error": { + "de": "RTC-Fehler", + "en": "RTC error" + }, + + "EEPROM error": { + "de": "EEPROM-Fehler", + "en": "EEPROM error" + }, + + "Dataflash error": { + "de": "Dataspeicher-Fehler", + "en": "Dataflash error" + }, + + "Phase L1 failure": { + "de": "Phasenausfall L1", + "en": "Phase L1 failure" + }, + + "Phase L2 failure": { + "de": "Phasenausfall L2", + "en": "Phase L2 failure" + }, + + "Phase L3 failure": { + "de": "Phasenausfall L3", + "en": "Phase L3 failure" + }, + + "Phase sequence wrong": { + "de": "Falsche Phasenfolge", + "en": "Phase sequence wrong" + }, + + "Adapter fatal error": { + "de": "Schwerer Adapter-Fehler", + "en": "Adapter fatal error" + }, + + "Stop and Start Meter reading mismatch": { + "de": "Start- und Endzählerstand stimmen nicht überein", + "en": "Stop and Start Meter reading mismatch" + }, + + "Intermediate command": { + "de": "Zwischenbefehl", + "en": "Intermediate command" + }, + + "Stop charge command": { + "de": "Ladevorgang beenden", + "en": "Stop charge command" + }, + + "Start charge command": { + "de": "Ladevorgang starten", + "en": "Start charge command" + }, + + "Adapter memory error": { + "de": "Adapter-Speicherfehler", + "en": "Adapter memory error" + }, + + "Meter communication error": { + "de": "Zählerkommunikationsfehler", + "en": "Meter communication error" + }, + + "Invalid status!": { + "de": "Ungültiger Status!", + "en": "Invalid status!" + }, "Adapter Id": { "de": "Adapter-Id", @@ -822,4 +985,5 @@ "en": "Charging Periods" } + } diff --git a/src/ts/Alfen.ts b/src/ts/Alfen.ts index 5acb6a7..23f132e 100644 --- a/src/ts/Alfen.ts +++ b/src/ts/Alfen.ts @@ -79,9 +79,9 @@ export class Alfen { UnitEncoded: 0, Scalar: "", UID: "", - InternalSessionId: 0, + InternalSessionId: 0, dataSets: [] as any[] - }; + }; let signedValues:string[] = []; if (typeof (Content) === 'string') @@ -333,7 +333,8 @@ export class Alfen { "format": "DER", "encoding": "base32" } - ] + ], + "publicKeySignatures": ContainerInfos.energyMeter?.publicKeySignatures } ] } @@ -622,14 +623,14 @@ export class AlfenCrypt01 extends ACrypt { try { - cryptoResult.publicKey = meter.publicKeys[0]?.value?.toLowerCase(); + cryptoResult.publicKey = meter.publicKeys[0]?.value; cryptoResult.publicKeyFormat = meter.publicKeys[0]?.format; cryptoResult.publicKeySignatures = meter.publicKeys[0]?.signatures; try { - const publicKey = chargyLib.buf2hex(this.chargy.base32Decode(cryptoResult.publicKey?.toUpperCase(), 'RFC4648')); + const publicKey = chargyLib.buf2hex(this.chargy.base32Decode(cryptoResult.publicKey, 'RFC4648')); let result = false; switch (meter?.publicKeys[0]?.algorithm ?? "") diff --git a/src/ts/chargeIT.ts b/src/ts/chargeIT.ts index 6fae3f0..f34dfdc 100644 --- a/src/ts/chargeIT.ts +++ b/src/ts/chargeIT.ts @@ -1137,6 +1137,7 @@ export class ChargeIT { const meterInfo_publicKeyEncoding = SomeJSON.meterInfo?.publicKeyEncoding; const meterInfo_signatureFormat = SomeJSON.meterInfo?.signatureFormat; const meterInfo_signatureEncoding = SomeJSON.meterInfo?.signatureEncoding; + const meterInfo_publicKeySignatures = SomeJSON.meterInfo?.publicKeySignatures; const connectorInfo = SomeJSON.connectorInfo; const connectorInfo_type = SomeJSON.connectorInfo?.type; @@ -1622,11 +1623,11 @@ export class ChargeIT { geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon }, address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country } }, - energyMeter: meterInfo, - connector: connectorInfo, - chargingTariffs: chargingTariffs, - chargingPeriods: chargingPeriods, - totalCosts: totalCosts + energyMeter: meterInfo, + connector: connectorInfo, + chargingTariffs: chargingTariffs, + chargingPeriods: chargingPeriods, + totalCosts: totalCosts }); } diff --git a/src/ts/chargyInterfaces.ts b/src/ts/chargyInterfaces.ts index 70fe8b4..19fd120 100644 --- a/src/ts/chargyInterfaces.ts +++ b/src/ts/chargyInterfaces.ts @@ -286,6 +286,10 @@ export interface IEVSE connectors?: Array; } +export interface IPublicKeySignature extends ISignatureRS { + +} + export interface IMeter { "@id": string; @@ -306,6 +310,7 @@ export interface IMeter signatureInfos?: ISignatureInfos; signatureFormat?: string; publicKeys?: Array; + publicKeySignatures?: Array; } export interface IConnector {