Changes/bugfixes due to experience in 4th International Testing Symposium in San Diego, California (April 2016)
- shortend all IDs of reference signature headers to 3 characters like the example given in Annex J (because some embedded systems might restrict the length to 3 characters) - SecurityUtils: minor additional checks in verifySignature() method - avoided NullPointerException when incoming message does not have ISO 15118 schema (for example DINSPEC 70121 XSD schema for DC charging) - made sure optional parameters of ServiceDiscoveryRes are not empty when sent - added logging message which shows which payment option was chosen by EVCC - added optional parameter EVSEIsolationStatus in DCEVSEStatus as some EVCC systems tend to need this value according to testival - bug fix: applied correct private key for signing sales tariff (must be MOSub2CA private key) - made sure EVCC does not choose contract based payment if SECC offers it although no TLS communication is set up
This commit is contained in:
parent
458babda11
commit
6345846e7b
|
@ -68,7 +68,7 @@ RequestedPaymentOption =
|
|||
# - DC_extended
|
||||
# - DC_combo_core
|
||||
# - DC_unique
|
||||
RequestedEnergyTransferMode = AC_three_phase_core
|
||||
RequestedEnergyTransferMode =
|
||||
|
||||
|
||||
# XML representation of messages
|
||||
|
|
|
@ -48,10 +48,12 @@ public class DummyEVController implements IACEVController, IDCEVController {
|
|||
|
||||
@Override
|
||||
public PaymentOptionType getPaymentOption(PaymentOptionListType paymentOptionsOffered) {
|
||||
if (paymentOptionsOffered.getPaymentOption().contains(PaymentOptionType.CONTRACT))
|
||||
return PaymentOptionType.CONTRACT;
|
||||
else
|
||||
return PaymentOptionType.EXTERNAL_PAYMENT;
|
||||
if (paymentOptionsOffered.getPaymentOption().contains(PaymentOptionType.CONTRACT)) {
|
||||
if (!getCommSessionContext().isTlsConnection()) {
|
||||
getLogger().warn("SECC offered CONTRACT based payment although no TLS connectionis used. Choosing EIM instead");
|
||||
return PaymentOptionType.EXTERNAL_PAYMENT;
|
||||
} else return PaymentOptionType.CONTRACT;
|
||||
} else return PaymentOptionType.EXTERNAL_PAYMENT;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -253,7 +253,13 @@ public abstract class ClientState extends State {
|
|||
|
||||
if (genChallenge != null) {
|
||||
authorizationReq.setGenChallenge(genChallenge);
|
||||
authorizationReq.setId("authorizationReq");
|
||||
/*
|
||||
* Experience from the test symposium in San Diego (April 2016):
|
||||
* The Id element of the signature is not restricted in size by the standard itself. But on embedded
|
||||
* systems, the memory is very limited which is why we should not use long IDs for the signature reference
|
||||
* element. A good size would be 3 characters max (like the example in the ISO 15118-2 annex J)
|
||||
*/
|
||||
authorizationReq.setId("id1");
|
||||
}
|
||||
|
||||
return authorizationReq;
|
||||
|
|
|
@ -162,7 +162,7 @@ public class WaitForChargeParameterDiscoveryRes extends ClientState {
|
|||
X509Certificate moSub2Certificate = SecurityUtils.getMOSub2Certificate(
|
||||
GlobalValues.EVCC_KEYSTORE_FILEPATH.toString());
|
||||
if (moSub2Certificate == null) {
|
||||
getLogger().error("No MOSub2Certificate found");
|
||||
getLogger().error("No MOSub2Certificate found, signature of sales tariff could therefore not be verified");
|
||||
return false;
|
||||
} else {
|
||||
ECPublicKey ecPublicKey = (ECPublicKey) moSub2Certificate.getPublicKey();
|
||||
|
|
|
@ -38,7 +38,13 @@ public class WaitForChargingStatusRes extends ClientState {
|
|||
// ReceiptRequired has higher priority than a possible EVSENotification=Renegotiate
|
||||
if (chargingStatusRes.isReceiptRequired()) {
|
||||
MeteringReceiptReqType meteringReceiptReq = new MeteringReceiptReqType();
|
||||
meteringReceiptReq.setId("meteringReceiptReq");
|
||||
/*
|
||||
* Experience from the test symposium in San Diego (April 2016):
|
||||
* The Id element of the signature is not restricted in size by the standard itself. But on embedded
|
||||
* systems, the memory is very limited which is why we should not use long IDs for the signature reference
|
||||
* element. A good size would be 3 characters max (like the example in the ISO 15118-2 annex J)
|
||||
*/
|
||||
meteringReceiptReq.setId("id1");
|
||||
meteringReceiptReq.setMeterInfo(chargingStatusRes.getMeterInfo());
|
||||
meteringReceiptReq.setSAScheduleTupleID(chargingStatusRes.getSAScheduleTupleID());
|
||||
meteringReceiptReq.setSessionID(getCommSessionContext().getSessionID());
|
||||
|
|
|
@ -37,7 +37,13 @@ public class WaitForCurrentDemandRes extends ClientState {
|
|||
// ReceiptRequired has higher priority than a possible EVSENotification=Renegotiate
|
||||
if (currentDemandRes.isReceiptRequired()) {
|
||||
MeteringReceiptReqType meteringReceiptReq = new MeteringReceiptReqType();
|
||||
meteringReceiptReq.setId("MeterInfo");
|
||||
/*
|
||||
* Experience from the test symposium in San Diego (April 2016):
|
||||
* The Id element of the signature is not restricted in size by the standard itself. But on embedded
|
||||
* systems, the memory is very limited which is why we should not use long IDs for the signature reference
|
||||
* element. A good size would be 3 characters max (like the example in the ISO 15118-2 annex J)
|
||||
*/
|
||||
meteringReceiptReq.setId("id1");
|
||||
meteringReceiptReq.setMeterInfo(currentDemandRes.getMeterInfo());
|
||||
meteringReceiptReq.setSAScheduleTupleID(currentDemandRes.getSAScheduleTupleID());
|
||||
meteringReceiptReq.setSessionID(getCommSessionContext().getSessionID());
|
||||
|
|
|
@ -43,6 +43,7 @@ public class WaitForPaymentDetailsRes extends ClientState {
|
|||
} else {
|
||||
// Set xml reference element
|
||||
AuthorizationReqType authorizationReq = getAuthorizationReq(paymentDetailsRes.getGenChallenge());
|
||||
|
||||
getXMLSignatureRefElements().put(
|
||||
authorizationReq.getId(),
|
||||
SecurityUtils.generateDigest(authorizationReq, false));
|
||||
|
|
|
@ -72,7 +72,13 @@ public class WaitForPaymentServiceSelectionRes extends ClientState {
|
|||
GlobalValues.PASSPHRASE_FOR_CERTIFICATES_AND_KEYS.toString());
|
||||
|
||||
CertificateInstallationReqType certInstallationReq = new CertificateInstallationReqType();
|
||||
certInstallationReq.setId("certificateInstallationReq");
|
||||
/*
|
||||
* Experience from the test symposium in San Diego (April 2016):
|
||||
* The Id element of the signature is not restricted in size by the standard itself. But on embedded
|
||||
* systems, the memory is very limited which is why we should not use long IDs for the signature reference
|
||||
* element. A good size would be 3 characters max (like the example in the ISO 15118-2 annex J)
|
||||
*/
|
||||
certInstallationReq.setId("id1");
|
||||
certInstallationReq.setListOfRootCertificateIDs(
|
||||
SecurityUtils.getListOfRootCertificateIDs(
|
||||
GlobalValues.EVCC_TRUSTSTORE_FILEPATH.toString(),
|
||||
|
@ -105,7 +111,13 @@ public class WaitForPaymentServiceSelectionRes extends ClientState {
|
|||
GlobalValues.PASSPHRASE_FOR_CERTIFICATES_AND_KEYS.toString()),
|
||||
GlobalValues.ALIAS_CONTRACT_CERTIFICATE.toString()));
|
||||
certificateUpdateReq.setEMAID(SecurityUtils.getEMAID(GlobalValues.PASSPHRASE_FOR_CERTIFICATES_AND_KEYS.toString()).getValue());
|
||||
certificateUpdateReq.setId("certificateUpdateReq");
|
||||
/*
|
||||
* Experience from the test symposium in San Diego (April 2016):
|
||||
* The Id element of the signature is not restricted in size by the standard itself. But on embedded
|
||||
* systems, the memory is very limited which is why we should not use long IDs for the signature reference
|
||||
* element. A good size would be 3 characters max (like the example in the ISO 15118-2 annex J)
|
||||
*/
|
||||
certificateUpdateReq.setId("id1");
|
||||
certificateUpdateReq.setListOfRootCertificateIDs(
|
||||
SecurityUtils.getListOfRootCertificateIDs(
|
||||
GlobalValues.EVCC_TRUSTSTORE_FILEPATH.toString(),
|
||||
|
|
|
@ -93,7 +93,8 @@ public class WaitForServiceDiscoveryRes extends ClientState {
|
|||
* Furthermore, it must be checked if VAS are allowed (-> only if TLS connection is used)
|
||||
*/
|
||||
private boolean useVAS(ServiceDiscoveryResType serviceDiscoveryRes) {
|
||||
if (getCommSessionContext().getTransportLayerClient() instanceof TLSClient) {
|
||||
if (serviceDiscoveryRes.getServiceList() != null &&
|
||||
getCommSessionContext().getTransportLayerClient() instanceof TLSClient) {
|
||||
// Check if certificate service is needed
|
||||
if (isCertificateServiceOffered(serviceDiscoveryRes.getServiceList())) {
|
||||
getCommSessionContext().setContractCertStatus(SecurityUtils.getContractCertificateStatus());
|
||||
|
@ -128,6 +129,11 @@ public class WaitForServiceDiscoveryRes extends ClientState {
|
|||
|
||||
|
||||
private boolean isCertificateServiceOffered(ServiceListType offeredServiceList) {
|
||||
if (offeredServiceList == null) {
|
||||
getLogger().debug("No value added services offered by EVCC");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ServiceType service : offeredServiceList.getService()) {
|
||||
if (service.getServiceCategory().equals(ServiceCategoryType.CONTRACT_CERTIFICATE))
|
||||
return true;
|
||||
|
|
|
@ -20,7 +20,6 @@ import javax.xml.namespace.QName;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.eclipse.risev2g.secc.session.V2GCommunicationSessionSECC;
|
||||
import org.eclipse.risev2g.secc.states.ServerState;
|
||||
import org.eclipse.risev2g.shared.enumerations.GlobalValues;
|
||||
import org.eclipse.risev2g.shared.utils.SecurityUtils;
|
||||
import org.eclipse.risev2g.shared.v2gMessages.msgDef.CertificateChainType;
|
||||
|
@ -34,6 +33,11 @@ import org.eclipse.risev2g.shared.v2gMessages.msgDef.SalesTariffEntryType;
|
|||
import org.eclipse.risev2g.shared.v2gMessages.msgDef.SalesTariffType;
|
||||
import org.eclipse.risev2g.shared.v2gMessages.msgDef.UnitSymbolType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class DummyBackendInterface implements IBackendInterface {
|
||||
|
||||
private V2GCommunicationSessionSECC commSessionContext;
|
||||
|
@ -97,7 +101,13 @@ public class DummyBackendInterface implements IBackendInterface {
|
|||
* IMPORTANT: check that you do not add more sales tariff entries than parameter maxEntriesSAScheduleTuple
|
||||
*/
|
||||
SalesTariffType salesTariff = new SalesTariffType();
|
||||
salesTariff.setId("salesTariff");
|
||||
/*
|
||||
* Experience from the test symposium in San Diego (April 2016):
|
||||
* The Id element of the signature is not restricted in size by the standard itself. But on embedded
|
||||
* systems, the memory is very limited which is why we should not use long IDs for the signature reference
|
||||
* element. A good size would be 3 characters max (like the example in the ISO 15118-2 annex J)
|
||||
*/
|
||||
salesTariff.setId("id1");
|
||||
salesTariff.setSalesTariffID((short) 1);
|
||||
salesTariff.getSalesTariffEntry().add(createSalesTariffEntry(0L, (short) 1));
|
||||
salesTariff.getSalesTariffEntry().add(createSalesTariffEntry(1800L, (short) 4));
|
||||
|
@ -179,12 +189,20 @@ public class DummyBackendInterface implements IBackendInterface {
|
|||
|
||||
@Override
|
||||
public ECPrivateKey getSAProvisioningCertificatePrivateKey() {
|
||||
KeyStore keyStore = SecurityUtils.getPKCS12KeyStore(
|
||||
"./provServiceCert.p12",
|
||||
GlobalValues.PASSPHRASE_FOR_CERTIFICATES_AND_KEYS.toString());
|
||||
return SecurityUtils.getPrivateKey(keyStore);
|
||||
Path pathToPrivateKey = FileSystems.getDefault().getPath("./MOSub2_ISO-UG_2016-1_key.bin");
|
||||
byte[] moSub2PrivateKey = null;
|
||||
|
||||
try {
|
||||
moSub2PrivateKey = Files.readAllBytes(pathToPrivateKey);
|
||||
} catch (IOException e) {
|
||||
getLogger().error("IOException occurred while trying to read MOSub2 private key for signing sales tariff");
|
||||
return null;
|
||||
}
|
||||
|
||||
return SecurityUtils.getPrivateKey(moSub2PrivateKey);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CertificateChainType getSAProvisioningCertificateChain() {
|
||||
return SecurityUtils.getCertificateChain("./provServiceCert.p12");
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.eclipse.risev2g.shared.v2gMessages.msgDef.DCEVSEChargeParameterType;
|
|||
import org.eclipse.risev2g.shared.v2gMessages.msgDef.DCEVSEStatusCodeType;
|
||||
import org.eclipse.risev2g.shared.v2gMessages.msgDef.DCEVSEStatusType;
|
||||
import org.eclipse.risev2g.shared.v2gMessages.msgDef.EVSENotificationType;
|
||||
import org.eclipse.risev2g.shared.v2gMessages.msgDef.IsolationLevelType;
|
||||
import org.eclipse.risev2g.shared.v2gMessages.msgDef.MeterInfoType;
|
||||
import org.eclipse.risev2g.shared.v2gMessages.msgDef.PhysicalValueType;
|
||||
import org.eclipse.risev2g.shared.v2gMessages.msgDef.UnitSymbolType;
|
||||
|
@ -87,7 +88,7 @@ public class DummyDCEVSEController implements IDCEVSEController {
|
|||
dcEvseStatus.setNotificationMaxDelay(0);
|
||||
dcEvseStatus.setEVSENotification((notification != null) ? notification : EVSENotificationType.NONE);
|
||||
dcEvseStatus.setEVSEStatusCode(DCEVSEStatusCodeType.EVSE_READY);
|
||||
// dcEvseStatus.setEVSEIsolationStatus(IsolationLevelType.INVALID);
|
||||
dcEvseStatus.setEVSEIsolationStatus(IsolationLevelType.VALID);
|
||||
|
||||
return dcEvseStatus;
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ public class V2GCommunicationSessionHandlerSECC implements Observer {
|
|||
*/
|
||||
byte[] seccAddress = (isSecureCommunication()) ? TLSServer.getInstance().getServerAddress().getAddress() : TCPServer.getInstance().getServerAddress().getAddress();
|
||||
int seccPort = (isSecureCommunication()) ? TLSServer.getInstance().getServerPort() : TCPServer.getInstance().getServerPort();
|
||||
|
||||
|
||||
SECCDiscoveryRes seccDiscoveryRes = new SECCDiscoveryRes(
|
||||
seccAddress,
|
||||
ByteUtils.toByteArrayFromInt(seccPort, true),
|
||||
|
|
|
@ -76,9 +76,11 @@ public class WaitForAuthorizationReq extends ServerState {
|
|||
// Verify signature
|
||||
HashMap<String, byte[]> verifyXMLSigRefElements = new HashMap<String, byte[]>();
|
||||
verifyXMLSigRefElements.put(authorizationReq.getId(), SecurityUtils.generateDigest(authorizationReq, false));
|
||||
|
||||
ECPublicKey ecPublicKey = (ECPublicKey) SecurityUtils.getCertificate(
|
||||
getCommSessionContext().getContractSignatureCertChain().getCertificate())
|
||||
.getPublicKey();
|
||||
|
||||
if (!SecurityUtils.verifySignature(signature, verifyXMLSigRefElements, ecPublicKey)) {
|
||||
authorizationRes.setResponseCode(ResponseCodeType.FAILED_SIGNATURE_ERROR);
|
||||
return false;
|
||||
|
|
|
@ -61,13 +61,19 @@ public class WaitForCertificateInstallationReq extends ServerState {
|
|||
getCommSessionContext().getBackendInterface().getContractCertificatePrivateKey());
|
||||
|
||||
certificateInstallationRes.setContractSignatureCertChain(saContractCertificateChain);
|
||||
certificateInstallationRes.getContractSignatureCertChain().setId("contractSignatureCertChain");
|
||||
/*
|
||||
* Experience from the test symposium in San Diego (April 2016):
|
||||
* The Id element of the signature is not restricted in size by the standard itself. But on embedded
|
||||
* systems, the memory is very limited which is why we should not use long IDs for the signature reference
|
||||
* element. A good size would be 3 characters max (like the example in the ISO 15118-2 annex J)
|
||||
*/
|
||||
certificateInstallationRes.getContractSignatureCertChain().setId("id1"); // contractSignatureCertChain
|
||||
certificateInstallationRes.setContractSignatureEncryptedPrivateKey(encryptedContractCertPrivateKey);
|
||||
certificateInstallationRes.getContractSignatureEncryptedPrivateKey().setId("contractSignatureEncryptedPrivateKey");
|
||||
certificateInstallationRes.getContractSignatureEncryptedPrivateKey().setId("id2"); // contractSignatureEncryptedPrivateKey
|
||||
certificateInstallationRes.setDHpublickey(SecurityUtils.getDHPublicKey(ecdhKeyPair));
|
||||
certificateInstallationRes.getDHpublickey().setId("dhPublicKey");
|
||||
certificateInstallationRes.getDHpublickey().setId("id3"); // dhPublicKey
|
||||
certificateInstallationRes.setEMAID(SecurityUtils.getEMAID(saContractCertificateChain));
|
||||
certificateInstallationRes.getEMAID().setId("emaid");
|
||||
certificateInstallationRes.getEMAID().setId("id4"); // emaid
|
||||
certificateInstallationRes.setSAProvisioningCertificateChain(
|
||||
getCommSessionContext().getBackendInterface().getSAProvisioningCertificateChain());
|
||||
|
||||
|
|
|
@ -63,13 +63,19 @@ public class WaitForCertificateUpdateReq extends ServerState {
|
|||
getCommSessionContext().getBackendInterface().getContractCertificatePrivateKey());
|
||||
|
||||
certificateUpdateRes.setContractSignatureCertChain(contractCertificateChain);
|
||||
certificateUpdateRes.getContractSignatureCertChain().setId("contractSignatureCertChain");
|
||||
/*
|
||||
* Experience from the test symposium in San Diego (April 2016):
|
||||
* The Id element of the signature is not restricted in size by the standard itself. But on embedded
|
||||
* systems, the memory is very limited which is why we should not use long IDs for the signature reference
|
||||
* element. A good size would be 3 characters max (like the example in the ISO 15118-2 annex J)
|
||||
*/
|
||||
certificateUpdateRes.getContractSignatureCertChain().setId("id1"); // contractSignatureCertChain
|
||||
certificateUpdateRes.setContractSignatureEncryptedPrivateKey(encryptedContractCertPrivateKey);
|
||||
certificateUpdateRes.getContractSignatureEncryptedPrivateKey().setId("contractSignatureEncryptedPrivateKey");
|
||||
certificateUpdateRes.getContractSignatureEncryptedPrivateKey().setId("id2"); // contractSignatureEncryptedPrivateKey
|
||||
certificateUpdateRes.setDHpublickey(SecurityUtils.getDHPublicKey(ecdhKeyPair));
|
||||
certificateUpdateRes.getDHpublickey().setId("dhPublicKey");
|
||||
certificateUpdateRes.getDHpublickey().setId("id3"); // dhPublicKey
|
||||
certificateUpdateRes.setEMAID(SecurityUtils.getEMAID(contractCertificateChain));
|
||||
certificateUpdateRes.getEMAID().setId("emaid");
|
||||
certificateUpdateRes.getEMAID().setId("id4"); // emaid
|
||||
certificateUpdateRes.setSAProvisioningCertificateChain(getCommSessionContext().getBackendInterface().getSAProvisioningCertificateChain());
|
||||
|
||||
// In case of negative response code, try at next charging (retryCounter = 0)
|
||||
|
|
|
@ -37,6 +37,9 @@ public class WaitForPaymentServiceSelectionReq extends ServerState {
|
|||
PaymentServiceSelectionReqType paymentServiceSelectionReq =
|
||||
(PaymentServiceSelectionReqType) v2gMessageReq.getBody().getBodyElement().getValue();
|
||||
|
||||
getLogger().info("Payment option " + paymentServiceSelectionReq.getSelectedPaymentOption().toString() +
|
||||
" has been chosen by EVCC");
|
||||
|
||||
if (isResponseCodeOK(paymentServiceSelectionReq)) {
|
||||
// see [V2G2-551]
|
||||
if (paymentServiceSelectionReq.getSelectedPaymentOption().equals(PaymentOptionType.CONTRACT)) {
|
||||
|
|
|
@ -78,8 +78,19 @@ public class WaitForServiceDiscoveryReq extends ServerState {
|
|||
chargeService.setSupportedEnergyTransferMode(supportedEnergyTransferModes);
|
||||
chargeService.setServiceCategory(ServiceCategoryType.EV_CHARGING);
|
||||
chargeService.setServiceID(1); // according to Table 105 ISO/IEC 15118-2
|
||||
chargeService.setServiceName("EV charging (AC/DC)"); // optional value
|
||||
chargeService.setServiceScope(""); // optional value
|
||||
|
||||
/*
|
||||
* Is an optional value, but fill it with a non-empty string if used,
|
||||
* otherwise an EXI decoding error could occur on the other side!
|
||||
*/
|
||||
chargeService.setServiceName("EV charging (AC/DC)");
|
||||
|
||||
/*
|
||||
* Is an optional value, but fill it with a non-empty string if used,
|
||||
* otherwise an EXI decoding error could occur on the other side!
|
||||
*/
|
||||
// chargeService.setServiceScope("");
|
||||
|
||||
chargeService.setFreeService(false); // it is supposed that charging is by default not for free
|
||||
|
||||
return chargeService;
|
||||
|
|
|
@ -77,10 +77,18 @@ public class WaitForSupportedAppProtocolReq extends ServerState {
|
|||
} else if (message instanceof SECCDiscoveryReq) {
|
||||
getLogger().debug("Another SECCDiscoveryReq was received, changing to state WaitForSECCDiscoveryReq");
|
||||
return new ChangeProcessingState(message, getCommSessionContext().getStates().get(V2GMessages.SECC_DISCOVERY_REQ));
|
||||
} else {
|
||||
} else if (message != null) {
|
||||
/*
|
||||
* This check has been introduced to make sure the application can deal with incoming messages which rely
|
||||
* on the DINSPEC 70121 XSD schema (which is different from the ISO 15118-2 schema. Without this check,
|
||||
* the message.getClass() would throw a NullPointerException and the application would die.
|
||||
*/
|
||||
getLogger().error("Invalid message (" + message.getClass().getSimpleName() +
|
||||
") at this state (" + this.getClass().getSimpleName() + ")");
|
||||
supportedAppProtocolRes.setResponseCode(ResponseCodeType.FAILED_NO_NEGOTIATION);
|
||||
} else {
|
||||
getLogger().error("Invalid message at this state, message seems to be null. Check if same XSD schema is used on EVCC side.");
|
||||
supportedAppProtocolRes.setResponseCode(ResponseCodeType.FAILED_NO_NEGOTIATION);
|
||||
}
|
||||
|
||||
return getSendMessage(supportedAppProtocolRes,
|
||||
|
|
|
@ -264,7 +264,7 @@ public final class MiscUtils {
|
|||
* (I don't know how to infer the type correctly)
|
||||
*
|
||||
* @param messageOrField The message or field for which a digest is to be generated
|
||||
* @return
|
||||
* @return The JAXBElement of the provided message or field
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public static JAXBElement getJaxbElement(Object messageOrField) {
|
||||
|
|
|
@ -600,7 +600,13 @@ public final class SecurityUtils {
|
|||
*/
|
||||
public static DiffieHellmanPublickeyType getDHPublicKey(KeyPair ecdhKeyPair) {
|
||||
DiffieHellmanPublickeyType dhPublicKey = new DiffieHellmanPublickeyType();
|
||||
dhPublicKey.setId("dhPublicKey");
|
||||
/*
|
||||
* Experience from the test symposium in San Diego (April 2016):
|
||||
* The Id element of the signature is not restricted in size by the standard itself. But on embedded
|
||||
* systems, the memory is very limited which is why we should not use long IDs for the signature reference
|
||||
* element. A good size would be 3 characters max (like the example in the ISO 15118-2 annex J)
|
||||
*/
|
||||
dhPublicKey.setId("id1"); // dhPublicKey
|
||||
dhPublicKey.setValue(ecdhKeyPair.getPublic().getEncoded());
|
||||
|
||||
return dhPublicKey;
|
||||
|
@ -1537,7 +1543,7 @@ public final class SecurityUtils {
|
|||
SignatureType signature,
|
||||
HashMap<String, byte[]> verifyXMLSigRefElements,
|
||||
ECPublicKey ecPublicKey) {
|
||||
byte[] providedDigest;
|
||||
byte[] calculatedReferenceDigest;
|
||||
boolean match;
|
||||
|
||||
/*
|
||||
|
@ -1548,17 +1554,28 @@ public final class SecurityUtils {
|
|||
for (String id : verifyXMLSigRefElements.keySet()) {
|
||||
getLogger().debug("Verifying digest for element '" + id + "'");
|
||||
match = false;
|
||||
providedDigest = verifyXMLSigRefElements.get(id);
|
||||
calculatedReferenceDigest = verifyXMLSigRefElements.get(id);
|
||||
|
||||
// A bit inefficient, but there are max. 4 elements to iterate over (what would be more efficient?)
|
||||
for (ReferenceType reference : signature.getSignedInfo().getReference()) {
|
||||
if (reference.getId().equals(id) && Arrays.equals(reference.getDigestValue(), providedDigest))
|
||||
if (reference == null) {
|
||||
getLogger().warn("Reference element to check is null");
|
||||
continue;
|
||||
}
|
||||
|
||||
// We need to check the URI attribute, the Id attribute is likely to be null
|
||||
if (reference.getURI() == null) {
|
||||
getLogger().warn("Reference ID element is null");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reference.getURI().equals('#' + id) && Arrays.equals(reference.getDigestValue(), calculatedReferenceDigest))
|
||||
match = true;
|
||||
}
|
||||
|
||||
if (!match) {
|
||||
getLogger().error("No matching signature found for ID '" + id + "' and digest value " +
|
||||
ByteUtils.toHexString(providedDigest));
|
||||
ByteUtils.toHexString(calculatedReferenceDigest));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue