summaryrefslogtreecommitdiff
path: root/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
diff options
context:
space:
mode:
authormcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2008-12-12 11:48:47 +0000
committermcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2008-12-12 11:48:47 +0000
commit887f6727479f3ae3d89a08ba619f9382b450e4c1 (patch)
tree32c1bba4893851f6ecb4fc92e3514138dc3a0a47 /smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
parent713a7ba94b7815bbd71fab152702306ca53c3eb2 (diff)
downloadmocca-887f6727479f3ae3d89a08ba619f9382b450e4c1.tar.gz
mocca-887f6727479f3ae3d89a08ba619f9382b450e4c1.tar.bz2
mocca-887f6727479f3ae3d89a08ba619f9382b450e4c1.zip
Updated SMCC to support non-blocking PIN entry. Added SV-Personendaten infobox implementation.
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@248 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
Diffstat (limited to 'smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java')
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java214
1 files changed, 124 insertions, 90 deletions
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
index e34c4899..633cc90d 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
@@ -28,6 +28,8 @@
//
package at.gv.egiz.smcc;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Locale;
import java.util.ResourceBundle;
@@ -79,45 +81,56 @@ public abstract class AbstractSignatureCard implements SignatureCard {
return sb.toString();
}
- protected abstract byte[] selectFileAID(byte[] fid) throws CardException,
- SignatureCardException;
-
- protected abstract ResponseAPDU selectFileFID(byte[] fid) throws CardException,
- SignatureCardException;
-
/**
- * VERIFY PIN
+ * Select an application using AID as DF name according to ISO/IEC 7816-4
+ * section 8.2.2.2.
*
- * <p>
- * Implementations of this method should call
- * {@link PINProvider#providePIN(PINSpec, int)} to retrieve the PIN entered by
- * the user and VERIFY PIN on the smart card until the PIN has been
- * successfully verified.
- * </p>
+ * @param dfName
+ * AID of the application to be selected
*
- * @param pinProvider
- * the PINProvider
- * @param spec
- * the PINSpec
- * @param kid
- * the key ID (KID) of the PIN to verify
+ * @return the response data of the response APDU if SW=0x9000
*
* @throws CardException
- * if smart card communication fails
- *
- * @throws CancelledException
- * if the PINProvider indicated that the user canceled the PIN entry
- * @throws NotActivatedException
- * if the card application has not been activated
- * @throws LockedException
- * if the card application is locked
+ * if card communication fails
*
* @throws SignatureCardException
- * if VERIFY PIN fails
+ * if application selection fails (e.g. an application with the
+ * given AID is not present on the card)
*/
- protected abstract void verifyPIN(PINProvider pinProvider, PINSpec spec,
- byte kid) throws CardException, SignatureCardException, InterruptedException;
+ protected byte[] selectFileAID(byte[] dfName) throws CardException, SignatureCardException {
+ CardChannel channel = getCardChannel();
+ ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xA4, 0x04,
+ 0x00, dfName, 256));
+ if (resp.getSW() != 0x9000) {
+ throw new SignatureCardException("Failed to select application AID="
+ + toString(dfName) + ": SW=" + Integer.toHexString(resp.getSW()) + ".");
+ } else {
+ return resp.getBytes();
+ }
+ }
+
+ protected abstract ResponseAPDU selectFileFID(byte[] fid) throws CardException,
+ SignatureCardException;
+ protected abstract int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException;
+
+
+ protected byte[] readRecord(int recordNumber) throws SignatureCardException, CardException {
+ return readRecord(getCardChannel(), recordNumber);
+ }
+
+ protected byte[] readRecord(CardChannel channel, int recordNumber) throws SignatureCardException, CardException {
+
+ ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xB2,
+ recordNumber, 0x04, 256));
+ if (resp.getSW() == 0x9000) {
+ return resp.getData();
+ } else {
+ throw new SignatureCardException("Failed to read records. SW=" + Integer.toHexString(resp.getSW()));
+ }
+
+ }
+
protected byte[] readBinary(CardChannel channel, int offset, int len)
throws CardException, SignatureCardException {
@@ -125,6 +138,8 @@ public abstract class AbstractSignatureCard implements SignatureCard {
0x7F & (offset >> 8), offset & 0xFF, len));
if (resp.getSW() == 0x9000) {
return resp.getData();
+ } else if (resp.getSW() == 0x6982) {
+ throw new SecurityStatusNotSatisfiedException();
} else {
throw new SignatureCardException("Failed to read bytes (" + offset + "+"
+ len + "): SW=" + Integer.toHexString(resp.getSW()));
@@ -188,43 +203,10 @@ public abstract class AbstractSignatureCard implements SignatureCard {
}
- /**
- * Read the content of a TLV file.
- *
- * @param aid the application ID (AID)
- * @param ef the elementary file (EF)
- * @param maxLength the maximum length of the file
- *
- * @return the content of the file
- *
- * @throws SignatureCardException
- */
- protected byte[] readTLVFile(byte[] aid, byte[] ef, int maxLength)
- throws SignatureCardException, InterruptedException {
- return readTLVFilePIN(aid, ef, (byte) 0, null, null, maxLength);
- }
-
-
- /**
- * Read the content of a TLV file wich may require a PIN.
- *
- * @param aid the application ID (AID)
- * @param ef the elementary file (EF)
- * @param kid the key ID (KID) of the corresponding PIN
- * @param provider the PINProvider
- * @param spec the PINSpec
- * @param maxLength the maximum length of the file
- *
- * @return the content of the file
- *
- * @throws SignatureCardException
- */
- protected byte[] readTLVFilePIN(byte[] aid, byte[] ef, byte kid,
- PINProvider provider, PINSpec spec, int maxLength)
- throws SignatureCardException, InterruptedException {
-
+ protected byte[] readRecords(byte[] aid, byte[] ef, int start, int end) throws SignatureCardException, InterruptedException {
+
try {
-
+
// SELECT FILE (AID)
byte[] rb = selectFileAID(aid);
if (rb[rb.length - 2] != (byte) 0x90 || rb[rb.length - 1] != (byte) 0x00) {
@@ -256,38 +238,90 @@ public abstract class AbstractSignatureCard implements SignatureCard {
+ Integer.toHexString(resp.getSW()) + ").");
}
-
- // try to READ BINARY
- byte[] b = new byte[1];
- int sw = readBinary(0, 1, b);
- if (provider != null && sw == 0x6982) {
-
- // VERIFY
- verifyPIN(provider, spec, kid);
-
- } else if (sw == 0x9000) {
- // not expected type
- if (b[0] != 0x30) {
- throw new NotActivatedException();
- }
- } else {
- throw new SignatureCardException("READ BINARY failed (SW="
- + Integer.toHexString(sw) + ").");
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+
+ for (int i = start; i <= end; i++) {
+ bytes.write(readRecord(i));
}
-
- // READ BINARY
- byte[] data = readBinaryTLV(maxLength, (byte) 0x30);
-
- return data;
-
+
+ return bytes.toByteArray();
+
} catch (CardException e) {
throw new SignatureCardException("Failed to acces card.", e);
+ } catch (IOException e) {
+ throw new SignatureCardException("Failed to read records.", e);
}
-
+
+ }
+
+ /**
+ * Read the content of a TLV file.
+ *
+ * @param aid the application ID (AID)
+ * @param ef the elementary file (EF)
+ * @param maxLength the maximum length of the file
+ *
+ * @return the content of the file
+ *
+ * @throws SignatureCardException
+ * @throws CardException
+ */
+ protected byte[] readTLVFile(byte[] aid, byte[] ef, int maxLength)
+ throws SignatureCardException, InterruptedException, CardException {
+ return readTLVFile(aid, ef, null, (byte) 0, maxLength);
}
/**
+ * Read the content of a TLV file wich may require a PIN.
+ *
+ * @param aid the application ID (AID)
+ * @param ef the elementary file (EF)
+ * @param kid the key ID (KID) of the corresponding PIN
+ * @param provider the PINProvider
+ * @param spec the PINSpec
+ * @param maxLength the maximum length of the file
+ *
+ * @return the content of the file
+ *
+ * @throws SignatureCardException
+ * @throws CardException
+ */
+ protected byte[] readTLVFile(byte[] aid, byte[] ef, String pin, byte kid, int maxLength)
+ throws SignatureCardException, InterruptedException, CardException {
+
+
+ // SELECT FILE (AID)
+ selectFileAID(aid);
+
+ // SELECT FILE (EF)
+ ResponseAPDU resp = selectFileFID(ef);
+ if (resp.getSW() == 0x6a82) {
+ // EF not found
+ throw new FileNotFoundException("EF " + toString(ef) + " not found.");
+ } else if (resp.getSW() != 0x9000) {
+ throw new SignatureCardException("SELECT FILE with "
+ + "FID="
+ + toString(ef)
+ + " failed ("
+ + "SW="
+ + Integer.toHexString(resp.getSW()) + ").");
+ }
+
+ // VERIFY
+ if (pin != null) {
+ int retries = verifyPIN(pin, kid);
+ if (retries != -1) {
+ throw new VerificationFailedException(retries);
+ }
+ }
+
+ return readBinaryTLV(maxLength, (byte) 0x30);
+
+
+ }
+
+ /**
* Transmit the given command APDU using the given card channel.
*
* @param channel