I have a smart card and am trying to read the X509 certificate (chain) that is on it. I am struggling to find the right APDU commands that give any successful APDU responses; I haven’t yet even been able to get it to verify the pin. (I have this card to login to some other applications, so I can verify that I have the right pin.)
I started out with this question, which has been a great start. I have been trying to read and understand what I can from CardWerks: here and here. I am using the javax Smart Card IO package, so the documentation has helped with a few things. And I’ve been using this site as a reference of the APDU response meanings.
Right now, the basic code structure (some pseudocode) I am using is:
try {
// get all terminals
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
logger.error("Terminals: " + terminals);
// get the first terminal
CardTerminal cdTerminal = terminals.get(0);
if (cdTerminal.isCardPresent()) {
// establish a connection with the card
Card card = cdTerminal.connect("*"); // or "T=0"?
logger.error("card: " + card);
CardChannel channel = card.openLogicalChannel(); // or "getBasicChannel();"
// create APDU commands...
CommandAPDU COMMAND = new CommandAPDU(new byte[] {
(byte) 0x80, // CLA
(byte) 0x20, // INS
(byte) 0x00, // P1
(byte) 0x81, // P2
(byte) 0x06, // Lc
(byte) 0x00, // data fields...
(byte) 0x00,
(byte) 0x00,
(byte) 0x00,
(byte) 0x00,
(byte) 0x00,
});
ResponseAPDU apduRes = channel.transmit(COMMAND);
byte[] resData = apduRes.getBytes();
print("COMMAND: " + toHexCodes(resData));
card.disconnect(false);
} else {
print("No card inserted!");
}
} catch (Exception e) {
print("Failed in smart card io.", e);
}
Is this structure okay? Should I be converting everything to bytes
?
I tried the verify pin:
CommandAPDU(new byte[] {
(byte) 0x80, // 0x00 gives 6E 00
(byte) 0x20,
(byte) 0x00,
(byte) 0x01,
(byte) 0x06,
(byte) 0x31, // pin changed
(byte) 0x31,
(byte) 0x31,
(byte) 0x31,
(byte) 0x31,
(byte) 0x31
});
Results with 6D 00
.
And tried checking the tries:
CommandAPDU(new byte[] {
(byte) 0x80, // CLA
(byte) 0x20, // INS: verify command
(byte) 0x00, //
(byte) 0x81, //
//(byte) 0x00
});
Results with 6D 00
.
I feel like my card is somehow different enough from others that most commands don’t work the same. What could I ask (in the way of developer’s documentation) from those who gave me the card that would be most useful?
I’ll be updating this tomorrow with some more info…