3
votes

I am trying to send data files from JC 2.2.2 card to a host app. All the files are less than 256 bytes. But the data needs to be encrypted and signed (for secure messaging) as shown below. After adding the MAC to the encrypted data the length of some of the files gets greater than 256 bytes. But I am using Extended Length so I thought there would be no problem with sending more than 256 bytes at once. The program works fine if the resulted cryptogram plus MAC is less than 256 bytes. Below is a piece of code that sends response apdu to the host.

Util.arrayCopyNonAtomic(file, offset, buffer, (short)0, file.length);                            
respLength = secureCrypto.wrapResponseAPDU(ssc, apdu, buffOfset, file.length);
apdu.setOutgoing();  
apdu.setOutgoingLength(respLength);          // 0x6F00 error occurs during the execution of this line
apdu.sendBytesLong(buffer, (short)0, respLength);

Card Details:

Terminal found : 2
PC/SC terminal OMNIKEY CardMan 5x21 0
PC/SC terminal OMNIKEY CardMan 5x21-CL 0
ATR: 13 bytes
Card Info : PC/SC card in OMNIKEY CardMan 5x21-CL 0, protocol T=1, state OK

At the host side I get 0x6F00 error code. And I have traced the program and found that the error occurs during the execution of apdu.setOutgoingLenght(respLength). In addition my applet class implements ExtendedLength interfcace. Any helpful information please

1
Are you sure the card supports extended length APDUs? Are you sending the command, which is implemented by your code in extended length APDU format?guidot
For your first question, I would say yes because I am using JC 2.2.2 and T=1 protocol. For the second question, I am not sure and I didn't know if I had to do such a thing. Would you be more helpful please by given me an example of extended length formatted APDU.ally
I can only refer you to ISO 7816 part 4, which describes the byte format. A 3-byte specification for LC with a first byte of zero indicates an extended length LC field, which also requires the LE field to be in extended format 2 bytes). In case of no LC, the LE specification has the additional leading zero byte, followed by two bytes length. If you give your application language and used API may be someone else may help you further.guidot

1 Answers

3
votes

Did you maybe forget to implement the javacardx.apdu.ExtendedLength "tagging" interface for your class that extends the Applet class? Note that the card should support this feature (it is in the javacardx name space, not javacard). Furthermore, for correct operation with readers, the card should indicate extended length support to readers (using the ATR or EF.ATR for the ISO 14443 type B contactless interface).

Even if the card supports extended length it may be that you will have to call sendBytesLong() multiple times. Extended length goes up to 64KiB (Java Card only goes up to 32KiB which is outside of the specification, at least for command APDU's), but there will be precious few cards - if they exist at all - that sport 64KiB of RAM for the APDU buffer.

Finally, APDU's can be extended length or not. This means that both the APDU command as well as the APDU response must be either be normal or extended length APDU's. Only ISO type 1 APDU's are exempt from this, as they don't contain either command or response data. Otherwise both the encoding of Nc (called Lc in ISO 7816-4) and Ne (called Le in the ISO standard) must use extended length encoding. In other words, the first encoding must be 3 bytes long, with the first set to 00 and the second (if present, for ISO type 4 APDU's) must be two bytes in size.

Note that javax.smartcardio handles extended length APDU's pretty gracefully. Unfortunately not all extended functionality in card readers is that well programmed. As you are using an Omnikey reader, you should be relatively safe from extended length bugs from the reader .dll's though.