5

I have a Grabba smart card reader. I am trying to get card information with APDU commands. I have read a lot about EMV standards and related ISO 7816-4 standard but I am not able to execute simple select command with success. Here is some details:

I have successfully powered my VISA card and get its attributes:

NSError *error = nil;
GRGrabbaSmartcardSession *session = [GRGrabba.sharedGrabba.smartcard startSession:&error];
NSLog(@"EMV : smartCardInsertedEvent : Attribute : %@", [session getATR]);

Result: 3b690000 8072a445 6400ff00 10

When I parse this attribute on here I get this information for my card:

Attribute parser result

My contactless card is a credit card from Akbank from Turkey but it is listed as a Denizbank card from Turkey in this list.

Now I am tring to run a select command on card like this:

NSError *error = nil;
GRGrabbaSmartcardSession *session = [GRGrabba.sharedGrabba.smartcard startSession:&error];
NSLog(@"EMV : smartCardInsertedEvent : Attribute : %@", [session getATR]);
session.protocol = 1;
uint8_t aid[] = {'2', 'P', 'A', 'Y', '.', 'S', 'Y', 'S', '.', 'D', 'D', 'F', '0', '1'};
NSData *data = [NSData dataWithBytes:aid length:sizeof(aid)];
NSError *err = nil;
GRGrabbaCommandAPDU *apduCMD =
        [[GRGrabbaCommandAPDU alloc]
                initWithCLA:0x00
                        INS:0xA4
                         P1:0x04
                         P2:0x00
                       Data:data
                         Le:0x00
                      Error:&err];

GRGrabbaResponseAPDU *response = [[GRGrabbaResponseAPDU alloc] initWithData:nil SW1:0 SW2:0];
BOOL success = [session exchangeAPDUCommand:apduCMD withResponse:response error:&error];

if (!success) {
    NSLog(@"EMV : smartCardInsertedEvent : ERROR: Could not read ADF");
    return;
}

But it is failing with could not read ADF error. Can anyone show me what am I doing wrong?

UPDATE:

I have tried following combinations but still not able to run select command with success:

PROTOCOL DATA           CLA     LE   STATUS
0        1PAY.SYS.DDF01 0x00    -    unrecognised SW in response: SW1 = 61, SW2 = 52
0        1PAY.SYS.DDF01 0x00    0x00 Smartcard protocol error.
0        2PAY.SYS.DDF01 0x00    -    unrecognised SW in response: SW1 = 61, SW2 = 66
0        2PAY.SYS.DDF01 0x00    0x00 Smartcard protocol error.
0        1PAY.SYS.DDF01 0x80    -    card returned Incorrect application CLA - SW1 = 6E, SW2 = 00
0        1PAY.SYS.DDF01 0x80    0x00 card returned Incorrect application CLA - SW1 = 6E, SW2 = 00
0        2PAY.SYS.DDF01 0x80    -    card returned Incorrect application CLA - SW1 = 6E, SW2 = 00
0        2PAY.SYS.DDF01 0x80    0x00 card returned Incorrect application CLA - SW1 = 6E, SW2 = 00
1        1PAY.SYS.DDF01 0x00    -    unrecognised SW in response: SW1 = 00, SW2 = 00
1        1PAY.SYS.DDF01 0x00    0x00 unrecognised SW in response: SW1 = 00, SW2 = 00
1        2PAY.SYS.DDF01 0x00    -    unrecognised SW in response: SW1 = 00, SW2 = 00
1        2PAY.SYS.DDF01 0x00    0x00 unrecognised SW in response: SW1 = 00, SW2 = 00
1        1PAY.SYS.DDF01 0x80    -    unrecognised SW in response: SW1 = 00, SW2 = 00 
1        1PAY.SYS.DDF01 0x80    0x00 unrecognised SW in response: SW1 = 00, SW2 = 00
1        2PAY.SYS.DDF01 0x80    -    unrecognised SW in response: SW1 = 00, SW2 = 00
1        2PAY.SYS.DDF01 0x80    0x00 unrecognised SW in response: SW1 = 00, SW2 = 00
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
  • May be i did not understand the syntax. APDU format is CLA INS P1 P2 Lc Command and Le. In your case are you sending the command length? 00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00. are you passing Lc 0x0E ie; 14 – Adarsh Nanu Jul 05 '18 at 15:54

2 Answers2

2

The following two results look perfectly fine:

PROTOCOL DATA           CLA     LE   STATUS
0        1PAY.SYS.DDF01 0x00    -    unrecognised SW in response: SW1 = 61, SW2 = 52
0        2PAY.SYS.DDF01 0x00    -    unrecognised SW in response: SW1 = 61, SW2 = 66

The status word 61xx indicates that there are xx bytes of response data waiting and that you need issue a GET RESPONSE command to obtain the actual response data.

Consequently, you would need to set protocol to 0,

session.protocol = 0;

issue the SELECT command (for 2PAY.SYS.DDF01)

uint8_t aid[] = {'2', 'P', 'A', 'Y', '.', 'S', 'Y', 'S', '.', 'D', 'D', 'F', '0', '1'};
NSData *data = [NSData dataWithBytes:aid length:sizeof(aid)];
NSError *err = nil;
GRGrabbaCommandAPDU *apduCMD =
        [[GRGrabbaCommandAPDU alloc]
                initWithCLA:0x00
                        INS:0xA4
                         P1:0x04
                         P2:0x00
                       Data:data
                      Error:&err];
GRGrabbaResponseAPDU *response = [[GRGrabbaResponseAPDU alloc] initWithData:nil SW1:0 SW2:0];
BOOL success = [session exchangeAPDUCommand:apduCMD withResponse:response error:&error];

and evaluate the SW1. If SW1 equals 0x90 you are set and already have the response data. If it equals 0x61, then you will need to issue a GET RESPONSE command with Le set to the length indicated by SW2:

if (response.sw1 == 0x61) {
    GRGrabbaCommandAPDU *apduGETRESPCMD =
            [[GRGrabbaCommandAPDU alloc]
                    initWithCLA:0x00
                            INS:0xC0
                             P1:0x00
                             P2:0x00
                             Le:response.sw2
                      Error:&err];
    BOOL success = [session exchangeAPDUCommand:apduGETRESPCMD withResponse:response error:&error];
}

Note: I'm not too confident about syntax and field names in the above code...feel free to fix that once you got it to work.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
1

I haven't used Grabba and I'm not sure if you are using it in contact or contactless, but since you're dealing with T=0 card, you might try issuing the command without Le.

Michal Gluchowski
  • 1,197
  • 8
  • 16