Bladeren bron

Added test data for CertificateInstallationRes to verify one's own implementation of creating and verifying XML-based signatures

Marc Mültin 8 jaren geleden
bovenliggende
commit
d2287e7355

+ 2 - 5
.gitignore

@@ -1,9 +1,4 @@
 *.jks
-*.p12
-*.pem
-*.cert
-*.cer
-*.key
 *.pfx
 *.bin
 *.der
@@ -19,5 +14,7 @@ RISE-V2G-Certificates/csrs
 RISE-V2G-Certificates/keystores
 RISE-V2G-Certificates/privateKeys
 RISE-V2G-Certificates/testing-symposia
+RISE-V2G-SECC/cpsCertChain.p12
+RISE-V2G-SECC/moCertChain.p12
 /.metadata/
 /.recommenders/

File diff suppressed because it is too large
+ 67 - 0
RISE-V2G-Certificates/signature-creation-testdata/README.txt


+ 12 - 0
RISE-V2G-Certificates/signature-creation-testdata/contractCert.pem

@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIB1DCCAXqgAwIBAgIBDDAKBggqhkjOPQQDAjBPMREwDwYDVQQDDAhNT1N1YkNB
+MjEZMBcGA1UECgwQUklTRSBWMkcgUHJvamVjdDELMAkGA1UEBhMCREUxEjAQBgoJ
+kiaJk/IsZAEZFgJNTzAeFw0xNzA4MjQxNTQ3MzNaFw0xOTA4MjQxNTQ3MzNaMFcx
+GTAXBgNVBAMMEERFLUFCQy1DMTIzQUJDNTYxGTAXBgNVBAoMEFJJU0UgVjJHIFBy
+b2plY3QxCzAJBgNVBAYTAkRFMRIwEAYKCZImiZPyLGQBGRYCTU8wWTATBgcqhkjO
+PQIBBggqhkjOPQMBBwNCAATWLNGBtvA+9+B1GcL7BdVkxx055ho14uVCjngxnO/p
+e4oaF/zhxn+BgjF8+zx4hzlabSSFHrpKedcfElrWMaApoz8wPTAMBgNVHRMBAf8E
+AjAAMA4GA1UdDwEB/wQEAwID6DAdBgNVHQ4EFgQU2KErOGsTJ2vc2dK2/yQ6eX8o
+ET8wCgYIKoZIzj0EAwIDSAAwRQIgEbwboObCxDqs4oIz3d6kvbNrAPAoLsiI1JWX
+3XbXU7MCIQDNOHDjmj1EZ8+F+xY1anObLaMJfJOt2yvcin6Ox/vxeg==
+-----END CERTIFICATE-----

BIN
RISE-V2G-Certificates/signature-creation-testdata/cpsCertChain.p12


+ 12 - 0
RISE-V2G-Certificates/signature-creation-testdata/cpsLeafCert.pem

@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIB0DCCAXagAwIBAgIBDzAKBggqhkjOPQQDAjBSMRMwEQYDVQQDDApQcm92U3Vi
+Q0EyMRkwFwYDVQQKDBBSSVNFIFYyRyBQcm9qZWN0MQswCQYDVQQGEwJERTETMBEG
+CgmSJomT8ixkARkWA0NQUzAeFw0xNzA4MjQxNTQ3MzNaFw0xNzExMjIxNTQ3MzNa
+MFAxETAPBgNVBAMMCENQUyBMZWFmMRkwFwYDVQQKDBBSSVNFIFYyRyBQcm9qZWN0
+MQswCQYDVQQGEwJERTETMBEGCgmSJomT8ixkARkWA0NQUzBZMBMGByqGSM49AgEG
+CCqGSM49AwEHA0IABAliSbuJvCZX7mUSSfLhTx7Xga7ZqkpVRJYqfzPxPoKku9if
+KZCK5yNdfr+jdl4rx54Xit6yCPlfWpxuSkzAxPijPzA9MAwGA1UdEwEB/wQCMAAw
+DgYDVR0PAQH/BAQDAgeAMB0GA1UdDgQWBBTj4VPerVdFt6xSJrWdtpFcb3sVETAK
+BggqhkjOPQQDAgNIADBFAiEAsGRTXuIfIuOa0owMEfD5MT/zYH6EiZao5+OkzeOf
+JXMCIB3JR3vt5l0mEWMLU+ShAmivkyUBw7O2rerExdMJttGX
+-----END CERTIFICATE-----

+ 12 - 0
RISE-V2G-Certificates/signature-creation-testdata/cpsSubCA1.pem

@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIB1zCCAX2gAwIBAgIBDTAKBggqhkjOPQQDAjBRMRIwEAYDVQQDDAlWMkdSb290
+Q0ExGTAXBgNVBAoMEFJJU0UgVjJHIFByb2plY3QxCzAJBgNVBAYTAkRFMRMwEQYK
+CZImiZPyLGQBGRYDVjJHMB4XDTE3MDgyNDE1NDczM1oXDTIxMDgyMzE1NDczM1ow
+UjETMBEGA1UEAwwKUHJvdlN1YkNBMTEZMBcGA1UECgwQUklTRSBWMkcgUHJvamVj
+dDELMAkGA1UEBhMCREUxEzARBgoJkiaJk/IsZAEZFgNDUFMwWTATBgcqhkjOPQIB
+BggqhkjOPQMBBwNCAARN2s0xy3U5Zb8hVqzTUIRjaCYFqmNQhz4cvx37M+K7LfcE
+wSKWJA3DV0NDqVjYx2xDuYEne40iKWkFBTVR0vVxo0UwQzASBgNVHRMBAf8ECDAG
+AQH/AgEBMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU76lySuYRBw7aRqQ7V1cN
+1K2zlfgwCgYIKoZIzj0EAwIDSAAwRQIhAOUOszuXtl1C0OXArVHEDvOvcQutMT9e
+ctVkId8YcKPUAiARFXXI6c3Fun5Xbka2IN1F/kKv+BC/P2GMlnJOYupBcw==
+-----END CERTIFICATE-----

+ 12 - 0
RISE-V2G-Certificates/signature-creation-testdata/cpsSubCA2.pem

@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIB2DCCAX6gAwIBAgIBDjAKBggqhkjOPQQDAjBSMRMwEQYDVQQDDApQcm92U3Vi
+Q0ExMRkwFwYDVQQKDBBSSVNFIFYyRyBQcm9qZWN0MQswCQYDVQQGEwJERTETMBEG
+CgmSJomT8ixkARkWA0NQUzAeFw0xNzA4MjQxNTQ3MzNaFw0xOTA4MjQxNTQ3MzNa
+MFIxEzARBgNVBAMMClByb3ZTdWJDQTIxGTAXBgNVBAoMEFJJU0UgVjJHIFByb2pl
+Y3QxCzAJBgNVBAYTAkRFMRMwEQYKCZImiZPyLGQBGRYDQ1BTMFkwEwYHKoZIzj0C
+AQYIKoZIzj0DAQcDQgAEGAVuEjd1iDZMfLe+Nx3++VQ4CUEGanjnE50TfIMJWMkg
+gW5yEfTW1Jvufc5y+DpUZt7gq7qv/avU49p+v6Wy76NFMEMwEgYDVR0TAQH/BAgw
+BgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFFU4w9oOBoEua91kTR+x
+7Cr+34aMMAoGCCqGSM49BAMCA0gAMEUCIBWwfkxUMuGD8B1TG9TqRTq5hMbdHAWk
+jrsn7OD9bIPxAiEA2+xoVcjPq06EG2u1VCKceY1WHhTcWFZAg2eG4X5/uBg=
+-----END CERTIFICATE-----

BIN
RISE-V2G-Certificates/signature-creation-testdata/moCertChain.p12


+ 12 - 0
RISE-V2G-Certificates/signature-creation-testdata/moSubCA1.pem

@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIB0TCCAXigAwIBAgIBCjAKBggqhkjOPQQDAjBPMREwDwYDVQQDDAhNT1Jvb3RD
+QTEZMBcGA1UECgwQUklTRSBWMkcgUHJvamVjdDELMAkGA1UEBhMCREUxEjAQBgoJ
+kiaJk/IsZAEZFgJNTzAeFw0xNzA4MjQxNTQ3MzNaFw0yMTA4MjMxNTQ3MzNaME8x
+ETAPBgNVBAMMCE1PU3ViQ0ExMRkwFwYDVQQKDBBSSVNFIFYyRyBQcm9qZWN0MQsw
+CQYDVQQGEwJERTESMBAGCgmSJomT8ixkARkWAk1PMFkwEwYHKoZIzj0CAQYIKoZI
+zj0DAQcDQgAEwNqTm722oOkhqoqu2n3o7KToKSm/F44sVYxZGE2e16kvouRECDK4
+qpFtqHSwIB+3ieERjkULjFR5WSLNrgKRK6NFMEMwEgYDVR0TAQH/BAgwBgEB/wIB
+ATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFEG8E3QNF3LZ0qEV7egtNs0OnR/0
+MAoGCCqGSM49BAMCA0cAMEQCIALepquQnisA0BszeLN1a+CP2tpo1U/bCalM0ddo
+zlxAAiBSEynyoLSSG09ujun7okXNLaMi0yI5ywdLOqrHja5S0Q==
+-----END CERTIFICATE-----

+ 8 - 0
RISE-V2G-Certificates/signature-creation-testdata/moSubCA2.key

@@ -0,0 +1,8 @@
+-----BEGIN EC PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,062540BA2D6472E54C487A11D95F3AC3
+
+aYWKJNn3VFjeSvvUqwJqqmszQmZ1tMlN++l3jHc6QfwZG8M3PJ4jCNFTjYnSyLxc
+lJwTEYmdURSrzBFXxOZwHMYhBn7cWS3DavsJk1SnukAR50DctrcXc74c5aBXY6HW
+zRFtKK/1PueHlfcetnhpTclz3dY1vLh26x33iZNcM74=
+-----END EC PRIVATE KEY-----

+ 12 - 0
RISE-V2G-Certificates/signature-creation-testdata/moSubCA2.pem

@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIB0zCCAXigAwIBAgIBCzAKBggqhkjOPQQDAjBPMREwDwYDVQQDDAhNT1N1YkNB
+MTEZMBcGA1UECgwQUklTRSBWMkcgUHJvamVjdDELMAkGA1UEBhMCREUxEjAQBgoJ
+kiaJk/IsZAEZFgJNTzAeFw0xNzA4MjQxNTQ3MzNaFw0yMTA4MjMxNTQ3MzNaME8x
+ETAPBgNVBAMMCE1PU3ViQ0EyMRkwFwYDVQQKDBBSSVNFIFYyRyBQcm9qZWN0MQsw
+CQYDVQQGEwJERTESMBAGCgmSJomT8ixkARkWAk1PMFkwEwYHKoZIzj0CAQYIKoZI
+zj0DAQcDQgAEHQtmsGpj+eG/xyigKHBNJLAzbFgM/v8JL0uHXgZ3/Lw6eznlNYJn
+L7tde9EXTiXqxUIzTsRDy6gdtZ14MLeUm6NFMEMwEgYDVR0TAQH/BAgwBgEB/wIB
+ADAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0OBBYEFB3V+E+Wq8bLNcbC8CMdNHXm1r4Q
+MAoGCCqGSM49BAMCA0kAMEYCIQDKMspcMuqaKjzDeUiqX6xrf0RSg2XC3ECzMGs8
+GVmKwgIhAKX/3F3Zfll+YKzboBtXymfSuCxg84sUgttIxj3t5YB/
+-----END CERTIFICATE-----

+ 12 - 0
RISE-V2G-Certificates/signature-creation-testdata/oemProvCert.pem

@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIB0TCCAXigAwIBAgIBCDAKBggqhkjOPQQDAjBRMRIwEAYDVQQDDAlPRU1TdWJD
+QTIxGTAXBgNVBAoMEFJJU0UgVjJHIFByb2plY3QxCzAJBgNVBAYTAkRFMRMwEQYK
+CZImiZPyLGQBGRYDT0VNMB4XDTE3MDgyNDE1NDczM1oXDTIxMDgyMzE1NDczM1ow
+UzEUMBIGA1UEAwwLT0VNUHJvdkNlcnQxGTAXBgNVBAoMEFJJU0UgVjJHIFByb2pl
+Y3QxCzAJBgNVBAYTAkRFMRMwEQYKCZImiZPyLGQBGRYDT0VNMFkwEwYHKoZIzj0C
+AQYIKoZIzj0DAQcDQgAEUqcvKGUqXWKyxSBWO/3FnqmlfMEMAnidDInpKGFiJmfE
+3UgNF3J3oJpjv9qUM3499WEpbT2CAo78x+mUDdpYl6M/MD0wDAYDVR0TAQH/BAIw
+ADAOBgNVHQ8BAf8EBAMCA4gwHQYDVR0OBBYEFCqlaYqeiG+DJv2rq+f1dfmIY5RU
+MAoGCCqGSM49BAMCA0cAMEQCICm9e1rqqqB7kwueHXqFiG2tMVrTOcVOs+jFwRwe
+gLb5AiAMedM5xhPfZsk2UQ+SPQU0sfrxMn502Lp/FNtSAC5ZhA==
+-----END CERTIFICATE-----

+ 12 - 0
RISE-V2G-Certificates/signature-creation-testdata/v2gRootCA.pem

@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIB0jCCAXmgAwIBAgIBATAKBggqhkjOPQQDAjBRMRIwEAYDVQQDDAlWMkdSb290
+Q0ExGTAXBgNVBAoMEFJJU0UgVjJHIFByb2plY3QxCzAJBgNVBAYTAkRFMRMwEQYK
+CZImiZPyLGQBGRYDVjJHMB4XDTE3MDgyNDE1NDczM1oXDTI3MDgyMjE1NDczM1ow
+UTESMBAGA1UEAwwJVjJHUm9vdENBMRkwFwYDVQQKDBBSSVNFIFYyRyBQcm9qZWN0
+MQswCQYDVQQGEwJERTETMBEGCgmSJomT8ixkARkWA1YyRzBZMBMGByqGSM49AgEG
+CCqGSM49AwEHA0IABLE/MafHkojlTbVfaMAjt7/i4C6/HS389tsQziW2mR7AR9qN
+mmGPiK4RZJhA1FNjCQ6DUik5SHOO5bjNpzvAvhCjQjBAMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBT04/k6DUSvK3QJCG1jqlaLBrAr
+2DAKBggqhkjOPQQDAgNHADBEAiBi7kagjATT8B1CSt78apcFeAdYO1XO9d97sTHz
+j2Ql9QIgEhmGC5nwUF82Ko/Adru0l9lggWZUTo+06RB9MKZtH78=
+-----END CERTIFICATE-----

+ 1 - 1
RISE-V2G-SECC/src/main/java/org/v2gclarity/risev2g/secc/states/WaitForChargingStatusReq.java

@@ -66,7 +66,7 @@ public class WaitForChargingStatusReq extends ServerState {
 				chargingStatusRes.setReceiptRequired(false);
 			} else {
 				// Only in PnC mode according to [V2G2-691]
-				chargingStatusRes.setReceiptRequired(true);
+				chargingStatusRes.setReceiptRequired(false);
 			}
 			
 			// Optionally set EVSEMaxCurrent (if NOT in AC PnC mode) -> check with AC station

+ 1 - 1
RISE-V2G-SECC/src/main/java/org/v2gclarity/risev2g/secc/states/WaitForPaymentDetailsReq.java

@@ -109,7 +109,7 @@ public class WaitForPaymentDetailsReq extends ServerState {
 		
 		// Check for FAILED_ContractCancelled
 		// TODO how to check if the EMAID provided by EVCC is not accepted by secondary actor?
-		if (!SecurityUtils.isEMAIDSynstaxValid(
+		if (!SecurityUtils.isEMAIDSyntaxValid(
 				SecurityUtils.getCertificate(
 						paymentDetailsReq.getContractSignatureCertChain().getCertificate())
 						)

+ 10 - 4
RISE-V2G-Shared/src/main/java/org/v2gclarity/risev2g/shared/messageHandling/MessageHandler.java

@@ -290,23 +290,29 @@ public class MessageHandler {
 			 * We need to set the localPart of the QName object for the CertificateInstallationRes/CertificateUpdateRes parameters
 			 * correctly. The messageOrField object's class name cannot be taken directly as it differs from what should be the 
 			 * XML element name.
+			 * 
+			 * In principle, there are two ways of setting the namespace for the XML elements of the parameters of a 
+			 * CertificateInstallationRes/CertificateUpdatenRes. Annex J of ISO 15118-2 is not clear about that. Standard rules of
+			 * XSD would require to always set a so-called target namespace, in this case GlobalValues.V2G_CI_MSG_BODY_NAMESPACE.
+			 * But you could also use the empty namespace "" and would still be conform to the standard.
+			 * The choice of the namespace heavily influences interoperability as the resulting digest values will be different.
 			 */
 			switch (messageName) {
 			case "CertificateChain":
 				messageName = "ContractSignatureCertChain";
-				namespace = "";
+//				namespace = "";
 				break;
 			case "DiffieHellmanPublickey":
 				messageName = "DHpublickey";
-				namespace = "";
+//				namespace = "";
 				break;
 			case "EMAID":
 				messageName = "eMAID";
-				namespace = "";
+//				namespace = "";
 				break;
 			case "ContractSignatureEncryptedPrivateKey":
 				messageName = "ContractSignatureEncryptedPrivateKey";
-				namespace = "";
+//				namespace = "";
 				break;
 			default:
 				break;

+ 15 - 7
RISE-V2G-Shared/src/main/java/org/v2gclarity/risev2g/shared/utils/SecurityUtils.java

@@ -453,7 +453,7 @@ public final class SecurityUtils {
 			}
 			break;
 		case MO:
-			if (!isEMAIDSynstaxValid(leafCertificate)) {
+			if (!isEMAIDSyntaxValid(leafCertificate)) {
 				return ResponseCodeType.FAILED_CERT_CHAIN_ERROR;
 			}
 			break;
@@ -716,8 +716,11 @@ public final class SecurityUtils {
 		 * 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(getUncompressedSubjectPublicKey((ECPublicKey) ecdhKeyPair.getPublic()));
+		dhPublicKey.setId("id1"); 
+		
+		byte[] uncompressedDHpublicKey = getUncompressedSubjectPublicKey((ECPublicKey) ecdhKeyPair.getPublic());
+		getLogger().debug("Created DHpublickey: " + ByteUtils.toHexString(uncompressedDHpublicKey));
+		dhPublicKey.setValue(uncompressedDHpublicKey);
 		
 		return dhPublicKey;
 	}
@@ -826,8 +829,6 @@ public final class SecurityUtils {
 			privateKey = (ECPrivateKey) keyStore.getKey(
 						alias, 
 						GlobalValues.PASSPHRASE_FOR_CERTIFICATES_AND_KEYS.toString().toCharArray());
-			
-			getLogger().debug("Private key used for creating signature: " + ByteUtils.toHexString(privateKey.getEncoded()));
 		} catch (KeyStoreException | UnrecoverableKeyException | NoSuchAlgorithmException e) {
 			getLogger().error("The private key from keystore with alias '" + alias + 
 							  "' could not be retrieved (" + e.getClass().getSimpleName() + ")", e);
@@ -1715,6 +1716,8 @@ public final class SecurityUtils {
 			encoded = getExiCodec().encodeEXI(jaxbMessageOrField, GlobalValues.SCHEMA_PATH_XMLDSIG.toString());
 		} else encoded = getExiCodec().encodeEXI(jaxbMessageOrField, GlobalValues.SCHEMA_PATH_MSG_DEF.toString());
 		
+		getLogger().debug("EXI encoded " + jaxbMessageOrField.getName().getLocalPart() + ": " + ByteUtils.toHexString(encoded));
+		
 		// Do not use the schema-informed fragment grammar option for other EXI encodings (message bodies)
 		getExiCodec().setFragment(false);
 		
@@ -1735,7 +1738,7 @@ public final class SecurityUtils {
 				 */
 				if ( !(jaxbMessageOrField.getValue() instanceof SignedInfoType) ) {
 					getLogger().debug("\n"
-									+ "\tDigest generated for reference element " + jaxbMessageOrField.getClass().getSimpleName() + ": " + ByteUtils.toHexString(digest) + "\n"
+									+ "\tDigest generated for XML reference element " + jaxbMessageOrField.getName().getLocalPart() + ": " + ByteUtils.toHexString(digest) + "\n"
 									+ "\tBase64 encoding of digest: " + Base64.getEncoder().encodeToString(digest));
 				}
 			}
@@ -1759,6 +1762,9 @@ public final class SecurityUtils {
 		try {
 			Signature ecdsa = Signature.getInstance("SHA256withECDSA", "SunEC");
 		
+			getLogger().debug("EXI encoded SignedInfo: " + ByteUtils.toHexString(signedInfoElementExi));
+			getLogger().debug("\n\tPrivate key used for creating signature: " + ByteUtils.toHexString(ecPrivateKey.getS().toByteArray()));
+			
 			ecdsa.initSign(ecPrivateKey);
 			ecdsa.update(signedInfoElementExi);
 			
@@ -1767,6 +1773,8 @@ public final class SecurityUtils {
 			// Java operates on DER encoded signatures, but we must send the raw r and s values as signature 
 			byte[] rawSignature = getRawSignatureFromDEREncoding(signature);
 			
+			getLogger().debug("Signature value: " + ByteUtils.toHexString(rawSignature));
+			
 			return rawSignature;
 		} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | NoSuchProviderException e) {
 			getLogger().error(e.getClass().getSimpleName() + " occurred while trying to create signature", e);
@@ -2132,7 +2140,7 @@ public final class SecurityUtils {
 	 * @param certChain The contract certificate chain. The EMAID is read from the contract certificate's common name
 	 * @return True, if the syntax is valid, false otherwise
 	 */
-	public static boolean isEMAIDSynstaxValid(X509Certificate contractCertificate) {
+	public static boolean isEMAIDSyntaxValid(X509Certificate contractCertificate) {
 		String emaid = getEMAID(contractCertificate).getValue().toUpperCase();
 		
 		if (emaid.length() < 14 || emaid.length() > 18) {

Some files were not shown because too many files changed in this diff