summaryrefslogtreecommitdiff
path: root/smcc/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'smcc/src/main/java')
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java62
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java11
2 files changed, 67 insertions, 6 deletions
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java b/smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java
index f8ba8643..b5ffa267 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java
@@ -36,6 +36,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import at.gv.egiz.smcc.util.SMCCHelper;
+import iaik.me.asn1.ASN1;
+import java.util.Arrays;
import javax.smartcardio.Card;
import javax.smartcardio.CardTerminal;
@@ -54,7 +56,7 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur
(byte) 0x50, (byte) 0x4B, (byte) 0x43, (byte) 0x53, (byte) 0x2D,
(byte) 0x31, (byte) 0x35 };
- public static final byte[] EF_QCERT = new byte[] { (byte) 0x0c, (byte) 0x02};
+ public static final byte[] EF_CD = new byte[] { (byte) 0x44, (byte) 0x04};
public static final byte[] CRT_AT = new byte[] {
// key 0x81??? (EF.PrKD defines 0x84 and 0x85)
@@ -103,8 +105,13 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur
CardChannel channel = getCardChannel();
// SELECT DF.CIA
execSELECT_AID(channel, AID_SIG);
+ byte[] ef_qcert = getFID_QCERT(channel);
+ if (ef_qcert == null) {
+ throw new NotActivatedException();
+ }
+
// SELECT CERT
- execSELECT_EF(channel, EF_QCERT);
+ execSELECT_EF(channel, ef_qcert);
// READ BINARY
byte[] certificate = ISO7816Utils.readTransparentFileTLV(channel, -1, (byte) 0x30);
@@ -288,11 +295,58 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur
}
- protected byte[] execSELECT_EF(CardChannel channel, byte[] fid)
+ protected byte[] getFID_QCERT(CardChannel channel)
throws SignatureCardException, CardException {
+ execSELECT_EF(channel, EF_CD);
+ byte[] cio_cd = ISO7816Utils.readTransparentFile(channel, -1);
+
+ //assume first 'record' is qcert
+ int length = 0;
+ if ((cio_cd[1] & 0xf0) == 0x80) {
+ int ll = cio_cd[1] & 0x7f;
+ for (int i= 0; i < ll; i++) {
+ length = (length << 8) + (cio_cd[2+i] & 0xff);
+ }
+ length += ll + 2;
+ } else {
+ length = (cio_cd[1] & 0xff) + 2;
+ }
+
+ log.trace("reading CIO.CD[0-{}]", length-1);
+
+ try {
+ ASN1 certificateObj = new ASN1(Arrays.copyOfRange(cio_cd, 0, length));
+ byte[] contextSpecific = certificateObj.getElementAt(2).getEncoded();
+ if ((contextSpecific[0] & 0xff) != 0xa1) {
+ log.warn("expected X509CertificateAttributes (CONTEXTSPECIFIC 0xa1), got {}",
+ (contextSpecific[0] & 0xff));
+ }
+ int ll = ((contextSpecific[1] & 0xf0) == 0x80)
+ ? (contextSpecific[1] & 0x7f) + 2 : 2;
+
+ ASN1 x509CertificateAttributes = new ASN1(
+ Arrays.copyOfRange(contextSpecific, ll, contextSpecific.length));
+
+ byte[] fid = x509CertificateAttributes.getElementAt(0).getElementAt(0)
+ .gvByteArray();
+
+ log.debug("reading certificate {} from file {}",
+ certificateObj.getElementAt(0).getElementAt(0).gvString(),
+ toString(fid));
+
+ return fid;
+ } catch (IOException ex) {
+ log.error("failed to get certificate path: " + ex.getMessage(), ex);
+ return null;
+ }
+ }
+
+ protected byte[] execSELECT_EF(CardChannel channel, byte[] fid)
+ throws SignatureCardException, CardException {
+
ResponseAPDU resp = channel.transmit(
- new CommandAPDU(0x00, 0xA4, 0x02, 0x00, fid, 256));
+ new CommandAPDU(0x00, 0xA4, 0x02, 0x00, fid, 256));
if (resp.getSW() == 0x6A82) {
String msg = "File or application not found FID="
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java b/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java
index 2979bd03..3f5343a6 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java
@@ -59,7 +59,8 @@ public class PinpadCardReader extends DefaultCardReader {
protected byte bTimeOut2 = 0x00; // default (attention with SCM)
protected byte wPINMaxExtraDigitMin = 0x00; // min pin length zero digits
protected byte wPINMaxExtraDigitMax = 0x0c; // max pin length 12 digits
-
+ protected byte bNumberMessage = 0x01;
+
/**
* supported features and respective control codes
*/
@@ -99,6 +100,12 @@ public class PinpadCardReader extends DefaultCardReader {
//Snow Leopard: Reiner-SCT cyberJack pinpad(a) 00 00
//display: REINER SCT CyberJack 00 00
if(name.startsWith("gemplus gempc pinpad") || name.startsWith("gemalto gempc pinpad")) {
+ // win7(microsoft driver) GemPlus USB GemPC Pinpad Smartcardreader 0 -> no pinpad
+ // win7(gemalto4.0.7.5) Gemalto GemPC Pinpad USB Smart Card Read 0 -> transmitContorlCommand failed (0x7a)
+ // (same with timeouts set to 0000 and 3c0f)
+ // winXP (verify failed, sw=d2(ecard) sw=92(acos), cf. wiki):
+ // winXP (without setting wPINMax: sw=6b:80)
+ // linux (ok): Gemplus GemPC Pinpad 00 00
log.trace("Setting custom wPINMaxExtraDigitH (0x04) for {}.", name);
wPINMaxExtraDigitMin = 0x04;
log.trace("Setting custom wPINMaxExtraDigitL (0x08) for {}.", name);
@@ -539,7 +546,7 @@ public class PinpadCardReader extends DefaultCardReader {
// bEntryValidationCondition
s.write(bEntryValidationCondition);
// bNumberMessage
- s.write(0x01);
+ s.write(bNumberMessage);
// wLangId (little endian)
s.write(0x09);
s.write(0x04);