diff options
Diffstat (limited to 'smcc/src')
-rw-r--r-- | smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java | 62 | ||||
-rw-r--r-- | smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java | 11 |
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); |