summaryrefslogtreecommitdiff
path: root/smcc/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'smcc/src/main')
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/CIOCertificateDirectory.java33
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/EFObjectDirectory.java190
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ESDNIeCard.java10
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/FINEIDCIOCertificateDirectory.java9
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/FINEIDCard.java9
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/FINEIDEFObjectDirectory.java22
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java203
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/cio/CIO.java (renamed from smcc/src/main/java/at/gv/egiz/smcc/CIOCertificate.java)76
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/cio/CIOCertificate.java118
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/cio/CIOCertificateDirectory.java57
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/cio/CIODirectoryFile.java128
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/cio/LIEZertifikatCertificateDirectory.java48
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/cio/ObjectDirectory.java208
13 files changed, 663 insertions, 448 deletions
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/CIOCertificateDirectory.java b/smcc/src/main/java/at/gv/egiz/smcc/CIOCertificateDirectory.java
index a9886e80..122c4e7d 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/CIOCertificateDirectory.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/CIOCertificateDirectory.java
@@ -17,6 +17,7 @@
package at.gv.egiz.smcc;
+import at.gv.egiz.smcc.cio.CIOCertificate;
import at.gv.egiz.smcc.util.ISO7816Utils;
import at.gv.egiz.smcc.util.TLVSequence;
import iaik.me.asn1.ASN1;
@@ -32,13 +33,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- *
+ * TODO To be replaced by at.gv.egiz.smcc.cio.CIOCertificateDirectory
+ *
* @author clemens
*/
public class CIOCertificateDirectory {
- protected static final boolean RETRIEVE_AUTH_ID_FROM_ASN1 = Boolean.TRUE;
-
protected static final Logger log = LoggerFactory.getLogger(CIOCertificateDirectory.class);
protected byte[] fid;
protected List<CIOCertificate> cios;
@@ -127,29 +127,8 @@ public class CIOCertificateDirectory {
}
protected void addCIOCertificate(byte[] cio) throws IOException {
-
- ASN1 x509Certificate = new ASN1(cio);
-
- CIOCertificate cioCert = new CIOCertificate();
- cioCert.setLabel(x509Certificate.getElementAt(0).getElementAt(0).gvString());
- if(retrieveAuthIdFromASN1()) {
- cioCert.setAuthId(x509Certificate.getElementAt(0).getElementAt(2).gvByteArray());
- }
- cioCert.setiD(x509Certificate.getElementAt(1).getElementAt(0).gvByteArray());
- //read CONTEXTSPECIFIC manually
- byte[] ctxSpecific = x509Certificate.getElementAt(x509Certificate.getSize()-1).getEncoded();
- if ((ctxSpecific[0] & 0xff) == 0xa1) {
- int ll = ((ctxSpecific[1] & 0xf0) == 0x80)
- ? (ctxSpecific[1] & 0x0f) + 2 : 2;
- ASN1 x509CertificateAttributes = new ASN1(Arrays.copyOfRange(ctxSpecific, ll, ctxSpecific.length));
-
- cioCert.setEfidOrPath(x509CertificateAttributes.getElementAt(0).getElementAt(0).gvByteArray());
-
- } else {
- log.warn("expected CONTEXTSPECIFIC, got 0x{}",
- Integer.toHexString(ctxSpecific[0]));
- }
+ CIOCertificate cioCert = new CIOCertificate(cio);
log.debug("adding {}", cioCert);
cios.add(cioCert);
@@ -160,8 +139,4 @@ public class CIOCertificateDirectory {
return cios;
}
- protected boolean retrieveAuthIdFromASN1() {
-
- return RETRIEVE_AUTH_ID_FROM_ASN1;
- }
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/EFObjectDirectory.java b/smcc/src/main/java/at/gv/egiz/smcc/EFObjectDirectory.java
deleted file mode 100644
index dfa70d91..00000000
--- a/smcc/src/main/java/at/gv/egiz/smcc/EFObjectDirectory.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright 2008 Federal Chancellery Austria and
- * Graz University of Technology
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package at.gv.egiz.smcc;
-
-import at.gv.egiz.smcc.util.ISO7816Utils;
-import at.gv.egiz.smcc.util.TLV;
-import at.gv.egiz.smcc.util.TLVSequence;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.smartcardio.CardChannel;
-import javax.smartcardio.CardException;
-import javax.smartcardio.CommandAPDU;
-import javax.smartcardio.ResponseAPDU;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * @author clemens
- */
-public class EFObjectDirectory {
-
- protected static final Logger log = LoggerFactory
- .getLogger(EFObjectDirectory.class);
-
- protected byte[] fid;
- private byte[] ef_prkd;
- private byte[] ef_pukd;
- private byte[] ef_aod;
-
- private List<byte[]> ef_cd_list = new ArrayList<byte[]>();;
-
- private Integer padding;
-
- public EFObjectDirectory() {
- fid = new byte[] { (byte) 0x50, (byte) 0x31 };
- }
-
- public EFObjectDirectory(byte[] fid) {
- this.fid = fid;
- }
-
- public EFObjectDirectory(int padding) {
-
- fid = new byte[] { (byte) 0x50, (byte) 0x31 };
- this.padding = padding;
-
- }
-
- /**
- * assume DF.CIA selected EF.OD selected afterwards
- *
- * @param channel
- * @throws CardException
- * @throws SignatureCardException
- */
- public void selectAndRead(CardChannel channel) throws CardException,
- SignatureCardException {
-
- executeSelect(channel);
-
- byte[] efod = ISO7816Utils.readTransparentFile(channel, -1);
-
- for (TLV cio : new TLVSequence(efod)) {
- int tag = cio.getTag();
-
- if (padding != null && tag == padding) {
- // reached padding - quit record extraction
- break;
- }
-
- byte[] seq = cio.getValue();
-
- if ((tag & 0xf0) == 0xa0 && seq.length >= 4) {
-
- byte[] path = Arrays.copyOfRange(seq, 4, 4 + seq[3]);
-
- switch (cio.getTag() & 0x0f) {
- case 0:
- setEf_prkd(path);
- break;
- case 1:
- setEf_pukd(path);
- break;
- case 4:
- addCdToEf_cd_list(path);
- break;
- case 8:
- setEf_aod(path);
- break;
- default:
- log.warn("CIOChoice 0x{} not supported: ",
- (cio.getTag() & 0x0f));
- }
- } else {
- log.trace("ignoring invalid CIO reference entry: {}", seq);
- }
- }
- }
-
- protected void executeSelect(CardChannel channel)
- throws SignatureCardException, CardException {
-
- CommandAPDU cmd = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, fid, 256);
- ResponseAPDU resp = channel.transmit(cmd);
-
- if (resp.getSW() != 0x9000) {
- throw new SignatureCardException("SELECT EF.OD failed: SW=0x"
- + Integer.toHexString(resp.getSW()));
- }
-
- }
-
- /**
- * @return the ef_prkd
- */
- public byte[] getEf_prkd() {
- return ef_prkd;
- }
-
- /**
- * @param ef_prkd
- * the ef_prkd to set
- */
- public void setEf_prkd(byte[] ef_prkd) {
- this.ef_prkd = ef_prkd;
- }
-
- /**
- * @return the ef_pukd
- */
- public byte[] getEf_pukd() {
- return ef_pukd;
- }
-
- /**
- * @param ef_pukd
- * the ef_pukd to set
- */
- public void setEf_pukd(byte[] ef_pukd) {
- this.ef_pukd = ef_pukd;
- }
-
- /**
- * @return the ef_aod
- */
- public byte[] getEf_aod() {
- return ef_aod;
- }
-
- public List<byte[]> getEf_cd_list() {
- return ef_cd_list;
- }
-
- public void setEf_cd_list(List<byte[]> ef_cd_list) {
- this.ef_cd_list = ef_cd_list;
- }
-
- public void addCdToEf_cd_list(byte[] ef_cd) {
-
- this.ef_cd_list.add(ef_cd);
- }
-
- /**
- * @param ef_aod
- * the ef_aod to set
- */
- public void setEf_aod(byte[] ef_aod) {
- this.ef_aod = ef_aod;
- }
-
-}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ESDNIeCard.java b/smcc/src/main/java/at/gv/egiz/smcc/ESDNIeCard.java
index a0d426c7..4f1c7610 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ESDNIeCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ESDNIeCard.java
@@ -1,5 +1,7 @@
package at.gv.egiz.smcc;
+import at.gv.egiz.smcc.cio.CIOCertificate;
+import at.gv.egiz.smcc.cio.ObjectDirectory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -66,11 +68,11 @@ public class ESDNIeCard extends AbstractSignatureCard implements SignatureCard {
// Select DF.CIA
executeSelectDFCIA(channel);
- EFObjectDirectory efOd = new EFObjectDirectory();
+ ObjectDirectory efOd = new ObjectDirectory();
efOd.selectAndRead(channel);
DNIeCIOCertificateDirectory efPrkd = new DNIeCIOCertificateDirectory(
- efOd.getEf_prkd());
+ efOd.getPrKDReferences().get(0));
efPrkd.selectAndRead(channel);
byte[] efKey = null;
@@ -155,11 +157,11 @@ public class ESDNIeCard extends AbstractSignatureCard implements SignatureCard {
byte[] efQcert = null;
- EFObjectDirectory efOd = new EFObjectDirectory();
+ ObjectDirectory efOd = new ObjectDirectory();
efOd.selectAndRead(channel);
DNIeCIOCertificateDirectory efCd = new DNIeCIOCertificateDirectory(
- efOd.getEf_cd_list().get(0));
+ efOd.getCDReferences().get(0));
try {
efCd.selectAndRead(channel);
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/FINEIDCIOCertificateDirectory.java b/smcc/src/main/java/at/gv/egiz/smcc/FINEIDCIOCertificateDirectory.java
index 0de2b3c1..537154c7 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/FINEIDCIOCertificateDirectory.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/FINEIDCIOCertificateDirectory.java
@@ -27,8 +27,6 @@ import at.gv.egiz.smcc.util.TLVSequence;
public class FINEIDCIOCertificateDirectory extends CIOCertificateDirectory {
- protected static final boolean RETRIEVE_AUTH_ID_FROM_ASN1 = Boolean.FALSE;
-
public FINEIDCIOCertificateDirectory(byte[] fid) {
super(fid);
@@ -46,11 +44,4 @@ public class FINEIDCIOCertificateDirectory extends CIOCertificateDirectory {
return fd;
}
-
- @Override
- protected boolean retrieveAuthIdFromASN1() {
-
- return RETRIEVE_AUTH_ID_FROM_ASN1;
- }
-
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/FINEIDCard.java b/smcc/src/main/java/at/gv/egiz/smcc/FINEIDCard.java
index 32272af8..92371d8e 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/FINEIDCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/FINEIDCard.java
@@ -17,6 +17,7 @@
package at.gv.egiz.smcc;
+import at.gv.egiz.smcc.cio.CIOCertificate;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
@@ -63,7 +64,7 @@ public class FINEIDCard extends AbstractSignatureCard implements SignatureCard {
// read PRKD to find correct key
FINEIDCIOKeyDirectory ef_prkd = new FINEIDCIOKeyDirectory(ef_od
- .getEf_prkd());
+ .getPrKDReferences().get(0));
ef_prkd.selectAndRead(channel);
byte[] efKey = null;
@@ -93,7 +94,7 @@ public class FINEIDCard extends AbstractSignatureCard implements SignatureCard {
}
// read AOD to find the associated PIN (authId must match)
- FINEIDAODirectory ef_aod = new FINEIDAODirectory(ef_od.getEf_aod());
+ FINEIDAODirectory ef_aod = new FINEIDAODirectory(ef_od.getAODReferences().get(0));
ef_aod.selectAndRead(channel);
byte[] pinPath = null;
@@ -181,10 +182,10 @@ public class FINEIDCard extends AbstractSignatureCard implements SignatureCard {
byte[] certPath = null;
- for (int i = 0; i < ef_od.getEf_cd_list().size(); i++) {
+ for (int i = 0; i < ef_od.getCDReferences().size(); i++) {
FINEIDCIOCertificateDirectory ef_cd = new FINEIDCIOCertificateDirectory(
- ef_od.getEf_cd_list().get(i));
+ ef_od.getCDReferences().get(i));
try {
ef_cd.selectAndRead(channel);
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/FINEIDEFObjectDirectory.java b/smcc/src/main/java/at/gv/egiz/smcc/FINEIDEFObjectDirectory.java
index 2690d694..ce44a892 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/FINEIDEFObjectDirectory.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/FINEIDEFObjectDirectory.java
@@ -17,28 +17,12 @@
package at.gv.egiz.smcc;
-import javax.smartcardio.CardChannel;
-import javax.smartcardio.CardException;
-import javax.smartcardio.CommandAPDU;
-import javax.smartcardio.ResponseAPDU;
+import at.gv.egiz.smcc.cio.ObjectDirectory;
-public class FINEIDEFObjectDirectory extends EFObjectDirectory {
+public class FINEIDEFObjectDirectory extends ObjectDirectory {
public FINEIDEFObjectDirectory(int padding) {
- super(padding);
+ super(padding, 0x00);
}
-
- @Override
- protected void executeSelect(CardChannel channel)
- throws SignatureCardException, CardException {
-
- CommandAPDU cmd = new CommandAPDU(0x00, 0xA4, 0x00, 0x00, fid, 256);
- ResponseAPDU resp = channel.transmit(cmd);
-
- if (resp.getSW() != 0x9000) {
- throw new SignatureCardException("SELECT EF.OD failed: SW=0x"
- + Integer.toHexString(resp.getSW()));
- }
- }
}
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 434f35a1..d84b3228 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java
@@ -18,6 +18,8 @@
package at.gv.egiz.smcc;
+import at.gv.egiz.smcc.cio.CIOCertificate;
+import at.gv.egiz.smcc.cio.ObjectDirectory;
import at.gv.egiz.smcc.pin.gui.PINGUI;
import at.gv.egiz.smcc.util.ISO7816Utils;
@@ -26,6 +28,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.util.List;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
@@ -36,7 +39,6 @@ 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;
@@ -58,13 +60,6 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur
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)
- (byte) 0x84, (byte) 0x01, (byte) 0x81,
- //RSA Authentication
- (byte) 0x89, (byte) 0x02, (byte) 0x23, (byte) 0x13
- };
-
public static final byte[] PKCS1_PADDING = new byte[] {
(byte) 0x30, (byte) 0x21, (byte) 0x30, (byte) 0x09, (byte) 0x06,
(byte) 0x05, (byte) 0x2b, (byte) 0x0e, (byte) 0x03, (byte) 0x02,
@@ -80,6 +75,9 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur
"at/gv/egiz/smcc/LIEZertifikatCard", "pin", KID, AID_SIG, 3);
protected String name = "LIEZertifikat";
+ ObjectDirectory ef_od = new ObjectDirectory();
+ CIOCertificate cioQCert;
+
@Override
public void init(Card card, CardTerminal cardTerminal) {
super.init(card, cardTerminal);
@@ -106,41 +104,10 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur
// SELECT DF.CIA
execSELECT_AID(channel, AID_SIG);
- EFObjectDirectory ef_od = new EFObjectDirectory();
- ef_od.selectAndRead(channel);
-
- CIOCertificateDirectory ef_cd = new CIOCertificateDirectory(ef_od.getEf_cd_list().get(0));
- ef_cd.selectAndRead(channel);
-
- byte[] ef_qcert = null;
- for (CIOCertificate cioCertificate : ef_cd.getCIOs()) {
- String label = cioCertificate.getLabel();
- //"Name (qualified signature"
- if (label != null && label.toLowerCase()
- .contains("qualified signature")) {
- ef_qcert = cioCertificate.getEfidOrPath();
- log.debug("found certificate: {} (fid={})", label, ef_qcert);
- }
- }
-
- if (ef_qcert == null) {
- for (CIOCertificate cioCertificate : ef_cd.getCIOs()) {
- String label = cioCertificate.getLabel();
- //"TEST LLV APO 2s Liechtenstein Post Qualified CA ID"
- if (label != null && label.toLowerCase()
- .contains("liechtenstein post qualified ca id")) {
- ef_qcert = cioCertificate.getEfidOrPath();
- log.debug("found certificate: {} (fid={})", label, ef_qcert);
- }
- }
- }
-
- if (ef_qcert == null) {
- throw new NotActivatedException();
- }
+ ensureCIOQCertificate(channel);
// SELECT CERT, assume efid
- execSELECT_EF(channel, ef_qcert);
+ execSELECT_EF(channel, cioQCert.getEfidOrPath());
// READ BINARY
byte[] certificate = ISO7816Utils.readTransparentFileTLV(channel, -1, (byte) 0x30);
@@ -217,7 +184,7 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur
// VERIFY
verifyPINLoop(channel, pinInfo, provider);
// MANAGE SECURITY ENVIRONMENT : SET SE
- execMSE_SET(channel, CRT_AT);
+ execMSE_SET(channel, getCRT_AT(channel));
// PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE
return execINTERNAL_AUTHENTICATE(channel, data.toByteArray());
@@ -301,83 +268,6 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur
}
- protected byte[] execSELECT_MF(CardChannel channel)
- throws SignatureCardException, CardException {
-
- // don't add Ne, causes 67:00
- ResponseAPDU resp = channel.transmit(
- new CommandAPDU(0x00, 0xA4, 0x00, 0x0c, MF));
-
- if (resp.getSW() == 0x6A82) {
- String msg = "File or application not found FID="
- + SMCCHelper.toString(MF) + " SW="
- + Integer.toHexString(resp.getSW()) + ".";
- log.info(msg);
- throw new FileNotFoundException(msg);
- } else if (resp.getSW() != 0x9000) {
- String msg = "Failed to select FID="
- + SMCCHelper.toString(MF) + " SW="
- + Integer.toHexString(resp.getSW()) + ".";
- log.error(msg);
- throw new SignatureCardException(msg);
- } else {
- return resp.getBytes();
- }
-
- }
-
-
- /**
- *
- * @return null if not found
- */
- 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 {
@@ -415,16 +305,6 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur
}
}
- protected void execMSE_RESTORE(CardChannel channel, byte seid)
- throws CardException, SignatureCardException {
- ResponseAPDU resp = channel.transmit(
- new CommandAPDU(0x00, 0x22, 0xf3, seid));
- if (resp.getSW() != 0x9000) {
- throw new SignatureCardException("MSE:RESTORE failed: SW="
- + Integer.toHexString(resp.getSW()));
- }
- }
-
protected byte[] execINTERNAL_AUTHENTICATE(CardChannel channel, byte[] AI)
throws CardException, SignatureCardException {
ResponseAPDU resp;
@@ -443,4 +323,69 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur
}
}
+ private void ensureCIOQCertificate(CardChannel channel) throws IOException, CardException, NotActivatedException, SignatureCardException {
+
+ if (cioQCert != null) {
+ return;
+ }
+
+ List<CIOCertificate> certCIOs = ef_od.getCD(channel).getCIOs(channel);
+
+ for (CIOCertificate cio : certCIOs) {
+
+ String label = cio.getLabel();
+ //"Name (qualified signature"
+ if (label != null && label.toLowerCase().contains("qualified signature")) {
+ log.debug("found certificate: {} (fid={})", label,
+ toString(cio.getEfidOrPath()));
+ cioQCert = cio;
+ }
+ }
+ //fallback for old cards
+ if (cioQCert == null) {
+ for (CIOCertificate cio : certCIOs) {
+ String label = cio.getLabel();
+ //"TEST LLV APO 2s Liechtenstein Post Qualified CA ID"
+ if (label != null && label.toLowerCase().contains("liechtenstein post qualified ca id")) {
+ log.debug("found certificate: {} (fid={})", label,
+ toString(cio.getEfidOrPath()));
+ cioQCert = cio;
+ }
+ }
+ }
+
+ if (cioQCert == null) {
+ throw new NotActivatedException();
+ }
+ }
+
+ protected byte[] getCRT_AT(CardChannel channel) throws CardException, SignatureCardException, IOException {
+
+ ensureCIOQCertificate(channel);
+ List<CIOCertificate> keyCIOs = ef_od.getPrKD(channel).getCIOs(channel);
+
+ int i = 1;
+ for (CIOCertificate cio : keyCIOs) {
+ if (Arrays.equals(cio.getiD(), cioQCert.getiD())) {
+
+ byte[] CRT_AT = new byte[] {
+ // 1-byte keyReference
+ (byte) 0x84, (byte) 0x01, (byte) (0x80 | (0x7f & i)),
+ // 3-byte keyReference
+ // (byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) 0x01, (byte) 0xff,
+ //RSA Authentication
+ (byte) 0x89, (byte) 0x02, (byte) 0x23, (byte) 0x13
+ };
+
+ return CRT_AT;
+ }
+ i++;
+ }
+
+ log.error("no PrK CIO corresponding to QCert {} found", toString(cioQCert.getiD()));
+ throw new SignatureCardException("could not determine PrK for QCert " + toString(cioQCert.getiD()));
+
+ }
+
+
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/CIOCertificate.java b/smcc/src/main/java/at/gv/egiz/smcc/cio/CIO.java
index 6a778245..a7ffb9c7 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/CIOCertificate.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/cio/CIO.java
@@ -15,33 +15,31 @@
* limitations under the License.
*/
-package at.gv.egiz.smcc;
+package at.gv.egiz.smcc.cio;
/**
*
* @author clemens
*/
-public class CIOCertificate {
+public abstract class CIO {
/** CommonObjectAttributes */
- private String label;
- private byte[] authId;
-
- /** CommonCertificateAttributes */
- private byte[] iD;
-
- /** X509CertificateAttributes*/
- private byte[] efidOrPath;
- private int serialNumber;
+ protected String label;
+ protected byte[] authId;
/**
- * @return the label
+ * @return the authId
*/
+ public byte[] getAuthId() {
+ return authId;
+ }
+
public String getLabel() {
return label;
}
/**
+ * @deprecated
* @param label the label to set
*/
public void setLabel(String label) {
@@ -49,66 +47,16 @@ public class CIOCertificate {
}
/**
- * @return the authId
- */
- public byte[] getAuthId() {
- return authId;
- }
-
- /**
+ * @deprecated
* @param authId the authId to set
*/
public void setAuthId(byte[] authId) {
this.authId = authId;
}
- /**
- * @return the iD
- */
- public byte[] getiD() {
- return iD;
- }
-
- /**
- * @param iD the iD to set
- */
- public void setiD(byte[] iD) {
- this.iD = iD;
- }
-
- /**
- * @return the efidOrPath
- */
- public byte[] getEfidOrPath() {
- return efidOrPath;
- }
-
- /**
- * @param efidOrPath the efidOrPath to set
- */
- public void setEfidOrPath(byte[] efidOrPath) {
- this.efidOrPath = efidOrPath;
- }
-
- /**
- * @return the serialNumber
- */
- public int getSerialNumber() {
- return serialNumber;
- }
-
- /**
- * @param serialNumber the serialNumber to set
- */
- public void setSerialNumber(int serialNumber) {
- this.serialNumber = serialNumber;
- }
-
@Override
public String toString() {
- return "CIOCertificate " + label;
+ return "CIO " + label;
}
-
-
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/cio/CIOCertificate.java b/smcc/src/main/java/at/gv/egiz/smcc/cio/CIOCertificate.java
new file mode 100644
index 00000000..1a9090ad
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/cio/CIOCertificate.java
@@ -0,0 +1,118 @@
+/*
+* Copyright 2008 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.smcc.cio;
+
+import iaik.me.asn1.ASN1;
+import java.io.IOException;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author clemens
+ */
+public class CIOCertificate extends CIO {
+
+ protected static final Logger log = LoggerFactory.getLogger(CIOCertificate.class);
+
+ /** CommonCertificateAttributes */
+ private byte[] iD;
+
+ /** X509CertificateAttributes*/
+ private byte[] efidOrPath;
+ private int serialNumber;
+
+ public CIOCertificate(byte[] cio) throws IOException {
+
+ ASN1 x509Certificate = new ASN1(cio);
+ ASN1 commonObjAttrs = x509Certificate.getElementAt(0);
+ label = commonObjAttrs.getElementAt(0).gvString();
+ try {
+ // FINeID does not provide authId
+ authId = commonObjAttrs.getElementAt(2).gvByteArray();
+ } catch (IOException e) {
+ log.info("failed to get authId from CommonObjectAttributes: {}", e.getMessage());
+ }
+
+ iD = x509Certificate.getElementAt(1).getElementAt(0).gvByteArray();
+
+ //read CONTEXTSPECIFIC manually
+ byte[] ctxSpecific = x509Certificate.getElementAt(x509Certificate.getSize()-1).getEncoded();
+ if ((ctxSpecific[0] & 0xff) == 0xa1) {
+ int ll = ((ctxSpecific[1] & 0xf0) == 0x80)
+ ? (ctxSpecific[1] & 0x0f) + 2 : 2;
+ ASN1 x509CertificateAttributes = new ASN1(Arrays.copyOfRange(ctxSpecific, ll, ctxSpecific.length));
+
+ efidOrPath = x509CertificateAttributes.getElementAt(0).getElementAt(0).gvByteArray();
+
+ } else {
+ log.warn("expected CONTEXTSPECIFIC, got 0x{}",
+ Integer.toHexString(ctxSpecific[0]));
+ }
+
+ }
+
+ /**
+ * @return the iD
+ */
+ public byte[] getiD() {
+ return iD;
+ }
+
+ /**
+ * @param iD the iD to set
+ */
+ public void setiD(byte[] iD) {
+ this.iD = iD;
+ }
+
+ /**
+ * @return the efidOrPath
+ */
+ public byte[] getEfidOrPath() {
+ return efidOrPath;
+ }
+
+ /**
+ * @deprecated
+ * @param efidOrPath the efidOrPath to set
+ */
+ public void setEfidOrPath(byte[] efidOrPath) {
+ this.efidOrPath = efidOrPath;
+ }
+
+ /**
+ * @deprecated
+ * @return the serialNumber
+ */
+ public int getSerialNumber() {
+ return serialNumber;
+ }
+
+ /**
+ * @deprecated
+ * @param serialNumber the serialNumber to set
+ */
+ public void setSerialNumber(int serialNumber) {
+ this.serialNumber = serialNumber;
+ }
+
+
+
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/cio/CIOCertificateDirectory.java b/smcc/src/main/java/at/gv/egiz/smcc/cio/CIOCertificateDirectory.java
new file mode 100644
index 00000000..67e183fd
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/cio/CIOCertificateDirectory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package at.gv.egiz.smcc.cio;
+
+import at.gv.egiz.smcc.SignatureCardException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import javax.smartcardio.CardChannel;
+import javax.smartcardio.CardException;
+
+/**
+ *
+ * @author clemens
+ */
+public abstract class CIOCertificateDirectory extends CIODirectoryFile {
+
+ protected List<CIOCertificate> cios;
+
+ public CIOCertificateDirectory(List<byte[]> DF_FIDs) {
+ super(DF_FIDs);
+ }
+
+ @Override
+ protected void addCIO(byte[] cio) throws IOException {
+
+ CIOCertificate cioCert = new CIOCertificate(cio);
+
+ log.debug("adding {}", cioCert);
+ cios.add(cioCert);
+
+ }
+
+ @Override
+ public List<CIOCertificate> getCIOs(CardChannel channel) throws CardException, SignatureCardException, IOException {
+ if (cios == null) {
+ cios = new ArrayList<CIOCertificate>();
+ readCIOs(channel);
+ }
+ return cios;
+ }
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/cio/CIODirectoryFile.java b/smcc/src/main/java/at/gv/egiz/smcc/cio/CIODirectoryFile.java
new file mode 100644
index 00000000..2d2fd03d
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/cio/CIODirectoryFile.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package at.gv.egiz.smcc.cio;
+
+import at.gv.egiz.smcc.SignatureCardException;
+import at.gv.egiz.smcc.util.ISO7816Utils;
+import at.gv.egiz.smcc.util.TLVSequence;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import javax.smartcardio.CardChannel;
+import javax.smartcardio.CardException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author clemens
+ */
+public abstract class CIODirectoryFile {
+
+ protected static final Logger log = LoggerFactory.getLogger(CIODirectoryFile.class);
+
+ protected List<byte[]> DF_FIDs;
+
+ public CIODirectoryFile(List<byte[]> DF_FIDs) {
+ this.DF_FIDs = DF_FIDs;
+ }
+
+ /**
+ * assume DF.CIA selected
+ * (one of) CIO.CD selected afterwards
+ *
+ * TODO: make abstract, implementation knows how to read file. only provide utility methods
+ *
+ * @param channel
+ * @throws CardException
+ * @throws SignatureCardException
+ * @throws IOException if ASN.1 structure cannot be parsed
+ */
+ public void readCIOs(CardChannel channel)
+ throws CardException, SignatureCardException, IOException {
+
+ for (byte[] fid : DF_FIDs) {
+ byte[] fd = selectDirectoryFile(channel, fid);
+ if ((fd[0] & 0x04) > 0) {
+ readCIOsFromRecords(channel, fd);
+ } else if ((fd[0] & 0x05) == 0x01) {
+ readCIOsFromTransparentFile(channel);
+ }
+ }
+ }
+
+ /**
+ * card specific implementation to select a CIO DF file and return its file descriptor
+ * @param channel
+ * @param fid
+ * @return file descriptor
+ * @throws CardException
+ */
+ protected abstract byte[] selectDirectoryFile(CardChannel channel, byte[] fid) throws CardException;
+
+
+ protected void readCIOsFromRecords(CardChannel channel, byte[] fd) throws CardException, SignatureCardException, IOException {
+
+ for (int r = 1; r < fd[fd.length - 1]; r++) {
+ log.trace("read CIO record {}", r);
+ byte[] record = ISO7816Utils.readRecord(channel, r);
+ addCIO(record);
+ }
+ }
+
+
+ protected void readCIOsFromTransparentFile(CardChannel channel) throws CardException, SignatureCardException, IOException {
+
+ byte[] ef = ISO7816Utils.readTransparentFile(channel, -1);
+
+ int i = 0;
+ int j;
+
+ do {
+ int length = 0;
+ int ll = 0;
+ if ((ef[i + 1] & 0xf0) == 0x80) {
+ ll = ef[i + 1] & 0x7f;
+ for (int it = 0; it < ll; it++) {
+ length = (length << 8) + (ef[i + it + 2] & 0xff);
+ }
+ } else {
+ length = (ef[i + 1] & 0xff);
+ }
+
+ log.trace("read CIO transparent file entry: tag 0x{}, length 0x{}",
+ Integer.toHexString(ef[i]),
+ Integer.toHexString(length));
+
+ j = i + 2 + ll + length;
+ addCIO(Arrays.copyOfRange(ef, i, j));
+ i = j;
+ } while (i < ef.length && ef[i] > 0);
+
+ }
+
+
+
+ /**
+ * CIO specific (Cert/PrK/AO/... CIO)
+ * @param cio
+ */
+ protected abstract void addCIO(byte[] cio) throws IOException;
+
+ public abstract List<? extends CIO> getCIOs(CardChannel channel) throws CardException, SignatureCardException, IOException;
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/cio/LIEZertifikatCertificateDirectory.java b/smcc/src/main/java/at/gv/egiz/smcc/cio/LIEZertifikatCertificateDirectory.java
new file mode 100644
index 00000000..40d5c7b9
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/cio/LIEZertifikatCertificateDirectory.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.gv.egiz.smcc.cio;
+
+import at.gv.egiz.smcc.cio.CIOCertificateDirectory;
+import at.gv.egiz.smcc.util.ISO7816Utils;
+import at.gv.egiz.smcc.util.TLVSequence;
+import java.util.List;
+import javax.smartcardio.CardChannel;
+import javax.smartcardio.CardException;
+import javax.smartcardio.CommandAPDU;
+import javax.smartcardio.ResponseAPDU;
+
+/**
+ *
+ * @author clemens
+ */
+public class LIEZertifikatCertificateDirectory extends CIOCertificateDirectory {
+
+ public LIEZertifikatCertificateDirectory(List<byte[]> DF_FIDs) {
+ super(DF_FIDs);
+ }
+
+ @Override
+ protected byte[] selectDirectoryFile(CardChannel channel, byte[] fid) throws CardException {
+
+ CommandAPDU cmd = new CommandAPDU(0x00, 0xA4, 0x02, ISO7816Utils.P2_FCP, fid, 256);
+ ResponseAPDU resp = channel.transmit(cmd);
+
+ byte[] fcp = new TLVSequence(resp.getBytes()).getValue(ISO7816Utils.TAG_FCP);
+ return new TLVSequence(fcp).getValue(0x82);
+
+ }
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/cio/ObjectDirectory.java b/smcc/src/main/java/at/gv/egiz/smcc/cio/ObjectDirectory.java
new file mode 100644
index 00000000..3ab954ee
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/cio/ObjectDirectory.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package at.gv.egiz.smcc.cio;
+
+import at.gv.egiz.smcc.SignatureCardException;
+import at.gv.egiz.smcc.util.ISO7816Utils;
+import at.gv.egiz.smcc.util.TLV;
+import at.gv.egiz.smcc.util.TLVSequence;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.smartcardio.CardChannel;
+import javax.smartcardio.CardException;
+import javax.smartcardio.CommandAPDU;
+import javax.smartcardio.ResponseAPDU;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TODO ObjectDirectory has access to card filesystem (to readTransparentFile(fid))
+ *
+ * @author clemens
+ */
+public class ObjectDirectory {
+
+ protected static final Logger log = LoggerFactory
+ .getLogger(ObjectDirectory.class);
+
+ protected byte[] fid;
+
+ protected CIOCertificateDirectory efCD;
+ /** TODO */
+ protected CIOCertificateDirectory efPrKD;
+
+ /** References to CIO EFs */
+ private List<byte[]> PrKD_refs;
+ private List<byte[]> PuKD_refs;
+ private List<byte[]> AOD_refs;
+ private List<byte[]> CD_refs;
+
+ private Integer padding;
+ private int P1 = 0x02;
+
+ public ObjectDirectory() {
+ fid = new byte[] { (byte) 0x50, (byte) 0x31 };
+ }
+
+ public ObjectDirectory(byte[] fid) {
+ this.fid = fid;
+ }
+
+ /**
+ * @deprecated check while reading if tag is valid
+ * @param padding
+ */
+ public ObjectDirectory(int padding, int p1) {
+
+ fid = new byte[] { (byte) 0x50, (byte) 0x31 };
+ this.padding = padding;
+ this.P1 = p1;
+ }
+
+ /**
+ * assume DF.CIA selected EF.OD selected afterwards
+ *
+ * @deprecated will be made private, use getCD/... instead
+ *
+ * @param channel
+ * @throws CardException
+ * @throws SignatureCardException
+ */
+ public void selectAndRead(CardChannel channel) throws CardException,
+ SignatureCardException {
+
+ CommandAPDU cmd = new CommandAPDU(0x00, 0xA4, P1, 0x00, fid, 256);
+ ResponseAPDU resp = channel.transmit(cmd);
+
+ if (resp.getSW() != 0x9000) {
+ throw new SignatureCardException("SELECT EF.OD failed: SW=0x"
+ + Integer.toHexString(resp.getSW()));
+ }
+
+ byte[] efod = ISO7816Utils.readTransparentFile(channel, -1);
+
+ PrKD_refs = new ArrayList<byte[]>();
+ PuKD_refs = new ArrayList<byte[]>();
+ AOD_refs = new ArrayList<byte[]>();
+ CD_refs = new ArrayList<byte[]>();
+
+ for (TLV cio : new TLVSequence(efod)) {
+ int tag = cio.getTag();
+
+ //TODO FIN EID: check if unknown tag and tag length > array
+ if (padding != null && tag == padding) {
+ // reached padding - quit record extraction
+ break;
+ }
+
+ byte[] seq = cio.getValue();
+
+ if ((tag & 0xf0) == 0xa0 && seq.length >= 4) {
+
+ byte[] path = Arrays.copyOfRange(seq, 4, 4 + seq[3]);
+
+ switch (cio.getTag() & 0x0f) {
+ case 0:
+ PrKD_refs.add(path);
+ break;
+ case 1:
+ PuKD_refs.add(path);
+ break;
+ case 4:
+ CD_refs.add(path);
+ break;
+ case 8:
+ AOD_refs.add(path);
+ break;
+ default:
+ log.warn("CIOChoice 0x{} not supported: ",
+ (cio.getTag() & 0x0f));
+ }
+ } else {
+ log.trace("ignoring invalid CIO reference entry: {}", seq);
+ }
+ }
+ }
+
+ /**
+ *
+ * @return the CertificateDirectory CIO file referenced in this EF.OD.
+ * If multiple directory files are referenced, the returned CD covers
+ * all of them.
+ */
+ public CIOCertificateDirectory getCD(CardChannel channel) throws CardException, SignatureCardException {
+
+ if (efCD == null) {
+
+ if (CD_refs == null) {
+ selectAndRead(channel);
+ }
+ efCD = new LIEZertifikatCertificateDirectory(CD_refs);
+ }
+ return efCD;
+ }
+
+ public CIOCertificateDirectory getPrKD(CardChannel channel) throws CardException, SignatureCardException {
+
+ if (efPrKD == null) {
+
+ if (PrKD_refs == null) {
+ selectAndRead(channel);
+ }
+ efPrKD = new LIEZertifikatCertificateDirectory(PrKD_refs);
+ }
+ return efPrKD;
+ }
+
+
+
+ /**
+ * @deprecated use getPrKD instead
+ * @return the references (FIDs) of the CIO files
+ */
+ public List<byte[]> getPrKDReferences() {
+ return PrKD_refs;
+ }
+
+ /**
+ * @deprecated use getPuKD instead
+ * @return the references (FIDs) of the CIO files
+ */
+ public List<byte[]> getPuKDReferences() {
+ return PuKD_refs;
+ }
+
+ /**
+ * @deprecated use getAOD instead
+ * @return the references (FIDs) of the CIO files
+ */
+ public List<byte[]> getAODReferences() {
+ return AOD_refs;
+ }
+
+ /**
+ * @deprecated use getCD instead
+ * @return the references (FIDs) of the CIO files
+ */
+ public List<byte[]> getCDReferences() {
+ return CD_refs;
+ }
+}