summaryrefslogtreecommitdiff
path: root/smccTest
diff options
context:
space:
mode:
Diffstat (limited to 'smccTest')
-rw-r--r--smccTest/src/main/java/at/gv/egiz/smcc/activation/Activation.java58
1 files changed, 51 insertions, 7 deletions
diff --git a/smccTest/src/main/java/at/gv/egiz/smcc/activation/Activation.java b/smccTest/src/main/java/at/gv/egiz/smcc/activation/Activation.java
index 510b8b08..6dd3ccf6 100644
--- a/smccTest/src/main/java/at/gv/egiz/smcc/activation/Activation.java
+++ b/smccTest/src/main/java/at/gv/egiz/smcc/activation/Activation.java
@@ -16,6 +16,7 @@ import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
+import java.security.SignatureException;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
@@ -326,7 +327,7 @@ public class Activation {
}
}
- void openSecureChannel(SecretKeySpec k_appl, byte[] cin) throws NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, CardException, NoSuchProviderException, GeneralSecurityException {
+ void openSecureChannel(SecretKeySpec k_appl, byte[] cin) throws SignatureCardException, NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, CardException, NoSuchProviderException, GeneralSecurityException {
// function openSecureChannelG3(card, crypto, iccsn, kappl, kid, algo) {
// if (typeof(kid) == "undefined")
@@ -419,15 +420,10 @@ public class Activation {
byte[] sendData = new byte[4*8+64];
System.arraycopy(rnd_ifd, 0, sendData, 0, 8);
- System.out.println(toString(sendData));
System.arraycopy(ifd_id, 0, sendData, 8, 8);
- System.out.println(toString(sendData));
System.arraycopy(rnd_icc, 0, sendData, 16, 8);
- System.out.println(toString(sendData));
System.arraycopy(icc_id, 0, sendData, 24, 8);
- System.out.println(toString(sendData));
System.arraycopy(kd_ifd, 0, sendData, 32, 64);
- System.out.println(toString(sendData));
System.out.println("cryptogram input (" + sendData.length + "byte): "
+ toString(sendData));
@@ -466,16 +462,28 @@ public class Activation {
byte[] c = new byte[cryptogram.length + mac.length];
System.arraycopy(cryptogram, 0, c, 0, cryptogram.length);
System.arraycopy(mac, 0, c, cryptogram.length, mac.length);
- System.out.println("MUTUAL AUTHENTICATE " + c.length + "bytes :" + toString(c));
+ System.out.println("MUTUAL AUTHENTICATE (" + c.length + "bytes): " + toString(c));
cmdAPDU = new CommandAPDU(0x00, 0x82, 0x00, 0x81, c, 256); // 81->00
System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
resp = channel.transmit(cmdAPDU);
System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+
//
// if (!crypto.verify(kmac, Crypto.DES_MAC_EMV, cryptogram.pad(Crypto.ISO9797_METHOD_2), mac)) {
// throw new GPError("MutualAuthentication", GPError.CRYPTO_FAILED, 0, "Card MAC did not verify correctly");
// }
+ System.out.println("ICC Response: " + resp.getData().length + " Bytes");
+ System.arraycopy(resp.getData(), 0, cryptogram, 0, 96);
+ System.arraycopy(resp.getData(), 96, mac, 0, 8);
+
+ byte[] mac_ = RetailCBCMac.retailMac(cryptogram, "DES", "DESede", k_mac, 8, 8);
+
+ if (!Arrays.equals(mac, mac_)) {
+ throw new SignatureCardException("Failed to authenticate card, invalid MAC " + toString(mac));
+ }
+ System.out.println("icc MAC verified");
+
//
// plain = crypto.decrypt(kenc, Crypto.DES_CBC, cryptogram, new ByteString("0000000000000000", HEX));
@@ -488,10 +496,46 @@ public class Activation {
// if (!plain.bytes(16, 8).equals(rndifd)) {
// throw new GPError("MutualAuthentication", GPError.CRYPTO_FAILED, 0, "Card response does not contain matching RND.IFD");
// }
+
+ tDES = Cipher.getInstance("3DES/CBC/NoPadding");
+ tDES.init(Cipher.DECRYPT_MODE, k_enc, new IvParameterSpec(ZEROS));
+
+ System.out.println("Decrypt cryptogram ("
+ + cryptogram.length + " Bytes) " + toString(cryptogram));
+
+ byte[] plain = tDES.doFinal(cryptogram);
+
+ if (!Arrays.equals(Arrays.copyOfRange(plain, 0, 8), rnd_icc)) {
+ throw new SignatureCardException("Failed to authenticate ICC, wrong RND.ICC "
+ + toString(Arrays.copyOfRange(plain, 0, 8)));
+ } else if (!Arrays.equals(Arrays.copyOfRange(plain, 16, 24), rnd_ifd)) {
+ throw new SignatureCardException("Failed to authenticate ICC, wrong RND.IFD "
+ + toString(Arrays.copyOfRange(plain, 16, 24)));
+ }
+
+ System.out.println("successfully verified RND.ICC/IFD");
+
+
//
// var kicc = plain.bytes(32, 64); // 32 -> 64
// keyinp = kicc.xor(kifd);
//
+
+ byte[] kd_icc = Arrays.copyOfRange(plain, 32, 96);
+ System.out.println("derive key input...");
+ byte[] kinp = new byte[kd_ifd.length];
+ for (int i = 0; i < kd_ifd.length; i++) {
+
+// System.out.println(Integer.toBinaryString(kd_icc[i]));
+// System.out.println(Integer.toBinaryString(kd_ifd[i]));
+
+ kinp[i] = (byte) (kd_icc[i] ^ kd_ifd[i]);
+
+// System.out.println(Integer.toBinaryString(kinp[i]) + "\n");
+
+ }
+
+
// var hashin = keyinp.concat(new ByteString("00000001", HEX));
// var hashres = crypto.digest(Crypto.SHA_256, hashin);
// var kencval = hashres.bytes(0, 24);