summaryrefslogtreecommitdiff
path: root/smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java
diff options
context:
space:
mode:
Diffstat (limited to 'smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java')
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java62
1 files changed, 58 insertions, 4 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="