From 50512519e5dea2405ceaead5ad111e3e827888b2 Mon Sep 17 00:00:00 2001 From: tzefferer Date: Mon, 29 Nov 2010 10:02:31 +0000 Subject: Bugfix DNIE FINEID Support git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@848 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../java/at/gv/egiz/smcc/DNIeSecuredChannel.java | 247 ++++++++++++--------- 1 file changed, 146 insertions(+), 101 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/DNIeSecuredChannel.java') diff --git a/smcc/src/main/java/at/gv/egiz/smcc/DNIeSecuredChannel.java b/smcc/src/main/java/at/gv/egiz/smcc/DNIeSecuredChannel.java index 92ef7f11..858a6cc5 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/DNIeSecuredChannel.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/DNIeSecuredChannel.java @@ -186,11 +186,13 @@ public class DNIeSecuredChannel extends T0CardChannel { super(channel); this.established = false; - + try { + this.establish(); + } catch (CardException e) { - + log.error("Error establishing secure channel with card.", e); } } @@ -199,6 +201,9 @@ public class DNIeSecuredChannel extends T0CardChannel { log.trace("Try to set up secure channel to card.."); + // select master file + executeSelectMasterFile(); + // get chip info this.snIcc = executeGetChipInfo(); @@ -230,42 +235,43 @@ public class DNIeSecuredChannel extends T0CardChannel { @Override public int transmit(ByteBuffer command, ByteBuffer response) throws CardException { - + byte[] commandAPDU = new byte[command.remaining()]; - for(int i=0; i 5) { - - log.error("Error securing APDU - invalid APDU length: " + apdu.length); + + if (apdu.length < 4 || apdu.length > 5) { + + log.error("Error securing APDU - invalid APDU length: " + + apdu.length); throw new CardException("Invalid APDU length."); } - + boolean leAvailable = apdu.length == 5; byte encCLA = (byte) (apdu[0] | (byte) 0x0C); - byte[] encHeader = new byte[] { encCLA, apdu[1], apdu[2], - apdu[3] }; + byte[] encHeader = new byte[] { encCLA, apdu[1], apdu[2], apdu[3] }; byte[] paddedHeader = DNIeCryptoUtil.applyPadding(BLOCK_LENGTH, encHeader); int leFieldLen; byte[] leField = null; - if(leAvailable) { + if (leAvailable) { leField = new byte[3]; leField[0] = (byte) 0x97; leField[1] = (byte) 0x01; leField[2] = apdu[4]; leFieldLen = leField.length; } else { - + leFieldLen = 0; } byte[] macData = new byte[paddedHeader.length + leFieldLen]; - System.arraycopy(paddedHeader, 0, macData, 0, - paddedHeader.length); - - if(leAvailable) { + System.arraycopy(paddedHeader, 0, macData, 0, paddedHeader.length); + + if (leAvailable) { System.arraycopy(leField, 0, macData, paddedHeader.length, leField.length); - - macData = DNIeCryptoUtil.applyPadding( - BLOCK_LENGTH, macData); + + macData = DNIeCryptoUtil.applyPadding(BLOCK_LENGTH, macData); } incrementSSC(); - byte[] mac = DNIeCryptoUtil.calculateAPDUMAC(macData, - kMac, this.ssc, BLOCK_LENGTH); + byte[] mac = DNIeCryptoUtil.calculateAPDUMAC(macData, kMac, this.ssc, + BLOCK_LENGTH); byte[] encapsulatedMac = new byte[mac.length + 2]; encapsulatedMac[0] = (byte) 0x8E; @@ -852,28 +889,28 @@ public class DNIeSecuredChannel extends T0CardChannel { completeMessage[2] = apdu[2]; completeMessage[3] = apdu[3]; completeMessage[4] = (byte) (encapsulatedMac.length + leFieldLen); - - if(leAvailable) { - System - .arraycopy(leField, 0, completeMessage, 5, - leField.length); + + if (leAvailable) { + System.arraycopy(leField, 0, completeMessage, 5, leField.length); } - - System.arraycopy(encapsulatedMac, 0, completeMessage, - 5 + leFieldLen, encapsulatedMac.length); - return completeMessage; - + System.arraycopy(encapsulatedMac, 0, completeMessage, 5 + leFieldLen, + encapsulatedMac.length); + + return completeMessage; + } - + private byte[] secureAPDUWithData(byte[] apdu) throws CardException { - if(apdu.length < 6) { - - log.error("Error securing APDU - invalid APDU length: " + apdu.length); - throw new CardException("Error securing APDU - invalid APDU length: " + apdu.length); + if (apdu.length < 6) { + + log.error("Error securing APDU - invalid APDU length: " + + apdu.length); + throw new CardException( + "Error securing APDU - invalid APDU length: " + apdu.length); } - + byte cla = apdu[0]; byte ins = apdu[1]; byte p1 = apdu[2]; @@ -881,23 +918,24 @@ public class DNIeSecuredChannel extends T0CardChannel { byte lc = apdu[4]; boolean leAvailable; - if(apdu.length == lc + 5 + 1) { - + if (apdu.length == lc + 5 + 1) { + leAvailable = true; - } else if(apdu.length != lc + 5) { - - log.error("Error securing APDU - invalid APDU length: " + apdu.length); + } else if (apdu.length != lc + 5) { + + log.error("Error securing APDU - invalid APDU length: " + + apdu.length); throw new CardException("Invalid APDU length or format."); } else { - + leAvailable = false; } - + byte[] leField = null; - if(leAvailable) { - - byte le = apdu[apdu.length-1]; - + if (leAvailable) { + + byte le = apdu[apdu.length - 1]; + leField = new byte[3]; leField[0] = (byte) 0x97; leField[1] = (byte) 0x01; @@ -942,14 +980,17 @@ public class DNIeSecuredChannel extends T0CardChannel { System.arraycopy(encapsulated, 0, headerAndData, paddedHeader.length, encapsulated.length); - if(leAvailable) { + if (leAvailable) { byte[] macData = new byte[headerAndData.length + leField.length]; - System.arraycopy(headerAndData, 0, macData, 0, headerAndData.length); - System.arraycopy(leField, 0, macData, headerAndData.length, leField.length); - + System + .arraycopy(headerAndData, 0, macData, 0, + headerAndData.length); + System.arraycopy(leField, 0, macData, headerAndData.length, + leField.length); + headerAndData = macData; } - + byte[] paddedHeaderAndData = DNIeCryptoUtil.applyPadding(BLOCK_LENGTH, headerAndData); @@ -964,34 +1005,35 @@ public class DNIeSecuredChannel extends T0CardChannel { System.arraycopy(mac, 0, encapsulatedMac, 2, mac.length); int leFieldLen; - if(leAvailable) { + if (leAvailable) { leFieldLen = leField.length; } else { leFieldLen = 0; } - + byte[] completeMessage = new byte[5 + encapsulated.length + encapsulatedMac.length + leFieldLen]; completeMessage[0] = encCLA; completeMessage[1] = ins; completeMessage[2] = p1; completeMessage[3] = p2; - + completeMessage[4] = (byte) (encapsulated.length + leFieldLen + encapsulatedMac.length); System.arraycopy(encapsulated, 0, completeMessage, 5, encapsulated.length); - - if(leAvailable) { - System.arraycopy(leField, 0, completeMessage, 5 + encapsulated.length, leFieldLen); + + if (leAvailable) { + System.arraycopy(leField, 0, completeMessage, + 5 + encapsulated.length, leFieldLen); } - - System.arraycopy(encapsulatedMac, 0, completeMessage, - 5 + encapsulated.length + leFieldLen, encapsulatedMac.length); - return completeMessage; + System.arraycopy(encapsulatedMac, 0, completeMessage, 5 + + encapsulated.length + leFieldLen, encapsulatedMac.length); + + return completeMessage; } - + private byte[] secureAPDU(byte[] apdu) throws CardException { if (apdu == null || apdu.length < 4) { @@ -1005,12 +1047,12 @@ public class DNIeSecuredChannel extends T0CardChannel { return secureAPDUWithoutData(apdu); } - if(apdu.length > 5) { + if (apdu.length > 5) { return secureAPDUWithData(apdu); } - - throw new CardException("Error securing APDU - unexpected APDU length."); + + throw new CardException("Error securing APDU - unexpected APDU length."); } private byte[] verifyAndDecryptSecuredResponseAPDU(byte[] securedAPDU) @@ -1031,15 +1073,18 @@ public class DNIeSecuredChannel extends T0CardChannel { System.arraycopy(commandResponse, 0, macData, data.length, commandResponse.length); - byte[] paddedMacData = DNIeCryptoUtil.applyPadding(BLOCK_LENGTH, macData); + byte[] paddedMacData = DNIeCryptoUtil.applyPadding(BLOCK_LENGTH, + macData); incrementSSC(); - byte[] mac = DNIeCryptoUtil.calculateAPDUMAC(paddedMacData, this.kMac, this.ssc, BLOCK_LENGTH); + byte[] mac = DNIeCryptoUtil.calculateAPDUMAC(paddedMacData, this.kMac, + this.ssc, BLOCK_LENGTH); if (!Arrays.equals(mac, obtainedMac)) { - log.error("Error verifiying MAC of secured response. MAC values do not match."); + log + .error("Error verifiying MAC of secured response. MAC values do not match."); throw new CardException("Unable to verify MAC of Response APDU."); } @@ -1047,14 +1092,14 @@ public class DNIeSecuredChannel extends T0CardChannel { byte[] data2decrypt = new byte[data.length - DNIeCryptoUtil.getCutOffLength(data, BLOCK_LENGTH)]; - System.arraycopy(data, DNIeCryptoUtil.getCutOffLength(data, BLOCK_LENGTH), - data2decrypt, 0, data2decrypt.length); + System.arraycopy(data, DNIeCryptoUtil.getCutOffLength(data, + BLOCK_LENGTH), data2decrypt, 0, data2decrypt.length); byte[] plainData = null; try { - plainData = DNIeCryptoUtil.perform3DESCipherOperation(data2decrypt, this.kEnc, - Cipher.DECRYPT_MODE); + plainData = DNIeCryptoUtil.perform3DESCipherOperation( + data2decrypt, this.kEnc, Cipher.DECRYPT_MODE); } catch (Exception e) { log.error("Error decrypting data.", e); throw new CardException("Unable to decrypt data.", e); -- cgit v1.2.3