2
votes

I have implemented an Andoid app - server side application. The server communicates with the smart card reader. When the user touches the button in the Android app, a connenction is being built to the server to get the user authenticated. The exchanged messages between the app and server have the following format:

<type> 0x00 0x00 0x00 <length> 0x00 0x00 0x00 <[data]>
  • If the message has the type value 06 that indicates an error in the smart card reader.
  • If the message has the type value 07 that indicates an error in the smart card.

I am using code like below for the communication with the smart card reader:

// show the list of available terminals
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
// get the first terminal
CardTerminal terminal = terminals.get(0);
// establish a connection with the card
Card card = terminal.connect("T=0");
System.out.println("card: " + card);
CardChannel channel = card.getBasicChannel();
ResponseAPDU r = channel.transmit(new CommandAPDU(c1));
System.out.println("response: " + toString(r.getBytes()));
// disconnect
card.disconnect(false);

The Smart Card IO API has the CardException class for exceptions. My problem is that I do not know when to send the message of type 06 or 07 because I can not differentiate between errors that are generated by the card and errors that are generated by the reader when the CardException is thrown. How can I manage that?

1

1 Answers

1
votes

The transmit() method, as used in

ResponseAPDU r = channel.transmit(new CommandAPDU(c1));

will only throw exceptions in situations related to smartcard reader errors and problems with the communication between the reader and the smartcard. It will not throw exceptions when the card itself indicates an error.

So you can catch all reader related errors by catching exceptions:

try {
    ResponseAPDU r = channel.transmit(new CommandAPDU(c1));
} catch (IllegalStateException e) {
    // channel has been closed or if the corresponding card has been disconnected
} catch (CardException e) {
    // errors occured during communication with the smartcard stack or the card itself (e.g. no card present)
}

Errors generated by the card are, instead, indicated as error codes encoded in the response status word. These errors do not generate Java exceptions. You can test for those errors by inspecting the status word (method getSW() of ResponseAPDU):

if (r.getSW() == 0x09000) {
    // success indicated by the card
} else {
    // error or warning condition generated by the card
}