JavaCard T=0 handing of case 2 APDUs (0x61XX (GET RESPONSE) vs 0x6CXX) - javacard

I have tested several javacards (Feitian D11CR, Infineon JTOP, G&D Smart Cafe) over T=0 and here is what I have observed.
If applet returns some data in case 4 APDU, the JCRE signals with SW 0x61XX that there is data available which terminal should retrieve using GET RESPONSE APDU.
However, if applet returns some data in case 2 APDU and Le does not match number of bytes to be returned, JCRE signals with error SW 0x6CXX, instructing that the same C-APDU has to be resent with correct Le.
For legacy reasons there are terminals who know how to handle 0x61XX, but fail to handle 0x6CXX response. Is there a way how to force JCRE to handle case 2 APDUs using 0x61XX (GET RESPONSE) method?

This behavior is given by the T=0 protocol where the length of data bytes transmitted must be fixed from the beginning of the TPDU exchange (i.e. the interface device decides it) -- in contrast to T=1/T=CL where the response length is left open for the card to decide.
Which causes trouble when the interface device sends an unacceptable value as data bytes length for Case 2 command -- the card can not transmit a different number of data bytes and has to send a special status word instead.
In T=0 the command cases are transmitted this way (very simplified):
Case 1:
CLA INS P1 P2 00, card responds with: SW1 SW2
Case 2:
CLA INS P1 P2 P3,
card responds with:
[ P3 bytes of response data ] SW1 SW2 if the actual length of response data equals P3
6C XX if value of P3 is unacceptable
Case 3:
CLA INS P1 P2 P3 [P3 bytes of command data], card responds with: SW1 SW2
Case 4:
CLA INS P1 P2 P3 [P3 bytes of command data], card responds with: 61 YY
CLA C0 00 00 YY card responds with: [YY bytes of response data] SW1 SW2
See ISO 7816-3, section "Command-response pair transmission by T=0" for exact details.
(In theory,) to workaround that (i.e. to prevent JCRE from sending the 6C XX status word), you would have to implement all Case 2 commands as Case 1 commands (i.e. do not call the APDU.setOutgoing()), return 61 XX status word and implement the GET RESPONSE command yourself (JCRE should pass this command to your process() method if it does not have it's own response data).
This brings some unnecessary overhead for terminal supporting 6C XX.
Some additional (random) notes:
user-level processing of extra GET RESPONSE command in process() method just worked for me. I did not check the JC specifications regarding this, YMMV.
it is a pity you can't use T=1
the workaround proposed above is just a theory. I've never implemented that approach (but I am definitely interested in the results you might get)
Hope this answer makes some sense...good luck!

There is a trick for Feitian and Infinion cards how to force 0x61XX response in "case 2" APDUs where Le=0x00 - the trick is to call setIncomingAndReceive(). This, however, will not work with other Le values (calling setIncomingAndReceive() with positive Le will cause error).
For compatibility reasons I ended up implementing 0x61XX support in the applet. So if the Le received does not match the length to be returned, the applet buffers the response in RAM and returns SW 0x61XX. When the GET RESPONSE APDU is received by process(), the Le will match the length buffered and the data will be returned using setOutgoingAndSend().

Related

Advice Required response from EMV card?

I am trying to communicate with a SAM which apparently is implemented according to EMV specifications. The developer does only refer me to EMV books whenever I ask them a question. After limping through the EMV card and terminal specifications, I finally managed to send commands one after the other, and get to the GENERATE CRYPTOGRAM command with CDOL 1. My command looks like this (CDOL1):
80AE40001D0000000000010000000000000364000000000003640B300E001234567800
And here's the card's response:
802B08003280DBD8B5E81B4AF5065B0E038420000000000000000000000F000000000000000000000000000000
Now, am I correctly reading it? ADVICE REQUIRED bit to 1, correct? If that is the case, what happens now? This SAM is supposed to work off-line with only a PIN number and no online connectivity requirements.
Your gen ac command having p1 = 40 , here terminal is requesting an Transaction Certificate (offline transaction)
Your response is showing , card is returning with using format 1 - premitive data object with tag equal to 80.
Here response containing :-
1 - Cryptogram Information Data ( 1 byte)
08
2 - Application transaction counter ( 2 byte)
0032
3 - Application cryptogram ( 8 byte)
80DBD8B5E81B4AF5
4 - Issuer Application data ( 32 byte)
065B0E038420000000000000000000000F000000000000000000000000000000
the CID byte indicate which type of cryptogram is returned by the card and here value is 08 - Transaction declined
Actually The CID reveal what kind of Application Cryptogram is returned. It can optionally contain an advice message if the transaction will rejected.
for more about advice message , how it process between card and terminal, look EMV book 2 and 3 (6.3.7 -card action analysis)
this is what your command response is indicating. hope it helps, if you have any other query , please share.

What exactly is the class byte in JavaCard?

I've started to work with the JavaCards and trying to grasp the sense of CLA byte.
If to read RFC 5.4.1 Class byte
5.4.1 Class byte
According to table 8 used in conjunction with table 9, the class byte
CLA of a command is used to indicate to what extent the command and the response comply with this part of ISO/IEC 7816 and when applicable (see table 9), the format of secure messaging and the logical channel number.
So... CLA flag is used for the indication, but what exact? Because, the table and description as for the beginner is rather difficult, I understand that usually are used the next CLA bytes: 0x00, 0x80, 0x84.
For e.g. if to read the content from table:
0X' Structure and coding of command and response according to this part of ISO/IEC 7816 (for coding of 'X' see table 9)
10 to 7F RFU
Reserved for PTS
I understand that for the fine developing - I should read GlobalPlatform specification, the specification about the exact card (mine is NXP one) and other related materials, but I want to admit, that it's difficult to understand the content.
I've expected the following (pseudo-table):
0x00 -> for reading streams from file system
0x01 -> for writing byte buffer to memory blocks
0x02 -> call AES/RSA methods
The CLASS byte is defined in ISO 7816-4. The first bit indicates the interindustry class. Java Card applets shall operate in this interindustry standard. Global Platform is another specification to manage and maintain the card and all commands will have class byte 0x80 - 0x8F. Class byte 0xFF is used for communication with the card reader in some cases and is otherwise invalid for a card.
The interindustry meaning for the CLA serves 3 major functions:
Function 1: Chaining
bit5 = 1 signalizes that the current command is not the last command of a chain, meaning that multiple APDUs all belong together and the card may therefore do additional things
Function 2: Secure Messaging
bit4+3 serve to signalize the secure messaging status of the current command. This means that the APDU is authenticated(e.g. MACed) and the data is encrypted(e.g. block cipher). The command header is never encrypted.
Function 3: Logical Channel
bit2+1 serve to identify the logical channel number. Logical channels are parallel communication interfaces through the card, therefore an applet A can be selected on Channel 0 and an applet B can be selected on Channel 1 while both applets remain in their internal state(no RAM is reset). Most cards do not support logical channels or you have to enable them explicitly.
CLA byte is a typical trap for Java Card beginners and its usually best that you leave at 0x00 for the start.

Talking to ACR1252U NFC Card Reader via Node.js

I am trying to communicate with an ACR1252U NFC card reader (http://www.acs.com.hk/en/products/342/acr1252u-usb-nfc-reader-iii-nfc-forum-certified-reader/) using Node.js and the https://github.com/nonolith/node-usb NPM module.
I have created a simple script to get the reader USB device and listen for events.
When an NFC card comes in contact with the reader I receive a buffer:
<Buffer 50 03>
When the NFC card is taken away from the read I receive a buffer:
<Buffer 50 02>
This indicates that I am at least able to get some basic communication with the reader working.
My problem now is I am trying to get information about the NFC card when it comes in contact with the reader. I have tried to send data to the reader but cannot get a consistent response (sometimes I get a buffer response and sometimes I don't, running the same command over and over).
I decided to simplify the command I was sending to just turn on and off the reader's internal buzzer so I looked at the API documentation (http://www.acs.com.hk/download-manual/6402/API-ACR1252U-A1-1.07.pdf) which says that to activate the buzzer you send through:
E0h 00h 00h 28h 01h + 1 byte to determine duration of buzzer activation
With that in mind I created a buffer:
var buf = new Buffer(6);
buf.write('e00000280108', 'hex');
Then used the USB module's out endpoint to send the data:
outEndpoint.transfer(buf, function (err) {
console.log('out transfer', err);
});
The console logs "out transfer" with no error but nothing is received from the "in" endpoint.
If I create a 64 byte buffer instead:
var buf = new Buffer(64);
buf.write('e00000280108', 'hex');
outEndpoint.transfer(buf, function (err) {
console.log('out transfer', err);
});
I receive a response from the "in" endpoint:
<Buffer e0 00 00 00 00 01 00 42 ff 00>
This doesn't seem to correspond to what is expect from the manual and doesn't activate the buzzer at all.
I'm very new to directly communicating with USB devices like this and my last experience of this type was sending AT commands to modems back in the day :)
Could anyone shed any light on what I am doing wrong? I figure that sending 64 bytes instead of 6 has something to do with the USB standard requiring a set length or something like that?!? Has anyone else had experience communicating with an NFC reader (non-HID) with Node.js? Ultimately all I want to do is be able to write some data to an NFC tag and read it back later on when the tag is presented.
I thought it would be a pretty simple process but I'm stumped! Maybe I should be encoded the data differently? Maybe I'm not terminating the data properly? I just don't know!
I tried increasing the buffer size by 1 and adding a \0 terminator to the buffer via:
buf.write('\0', 6, 'utf-8');
But that didn't make any difference at all.
Thanks!
The commands described in the API specification are (pseudo) APDU commands to be exchange with the reader over PC/SC. When you access the reader directly through USB without a PS/SC abstraction layer (see http://www.pcscworkgroup.com/specifications/overview.php), you have to implement that abstraction yourself. Therefore, you have to implement the USB CCID (chip card interface device) class interface yourself. Essentially, this means that you have to encapsulate APDU commands in the CCID protocol. You can fin the specification here: http://www.usb.org/developers/docs/devclass_docs/

SELECT PPSE GIVES 6700,( VISA Paywave)

I have two different smartcard chips with Visa Paywave inside (one is native, and other is Java Card).
I am trying to run select PPSE or select Application command, one card is giving the expected result while another card is giving status word 6700.
Command ---->CMD 00A404000E325041592E5359532E4444463031
Sw1-sw2 <----67 00
Command ---->CMD 00A4040007A0000000031010
Sw1-sw2 <----67 00
We have some other proprietary test tool that is receiving a good result for both cards. That means that both cards have a PPSE and application in it. I wonder why my tool is sending the same command but getting a different result.
Any advice would be helpful here.
As we know that there are 4 cases defined in ISO7816-4 like,
As per my experience maximum card does not worry about Le field in apdu command, card O.S just process the command and return data if require.
Here i am getting error -6700 because here my card is expecting Le byte too.( card expecting case 4 instead of case 3)
Send command like below solve my problem,
00 A4 04 00 0E 325041592E5359532E4444463031 00 ( adding Le = 0x00 at last)

APDU GET response Samsung S4

I am testing sending APDU commands on S3's and S4's.
On my S3 I send out the APDU and get back 9000.
Knowing that my response also has 8 bytes of data i do:
80C0000010
On my S4 I send out the same APDU as above and get 6108 (61 data available - 08 , 8 bytes of data)
Sending out 80C0000010 or 80C0000000 both return 6F00 (internal error).
The S4 is up to date running 4.3.
My suspicion is that something is going wrong in the version of SEEK my S4 is running as I have this working on other devices.
Has anyone else experienced this issue and have any resolution or any suggestions of things for me to try?
It would be nice to have the exact APDU, but what you're seen is caused by a more strict implementation of ISO7816 on the S4 than on the S3. When you expect data in return (case 2, case 4 APDUs), then the ISO7816-4 mandates the use of the Le byte, which you set to 00.
Try adding 0x00 as Le byte at the end of your APDU, it should work on both the S3 and the S4.

Resources