Search code examples
chexapducontactless-smartcardtlv

searching Tags (TLV) with C function


I' m working on Mastercard Paypass transactions, I Have sent a READ RECORD command and got the result:

70 81 AB 57 11 54 13 33 00 89 60 10 83 D2 51 22 
20 01 23 40 91 72 5A 08 54 13 33 00 89 60 10 83 
5F 24 03 25 12 31 5F 25 03 04 01 01 5F 28 02 00 
56 5F 34 01 01 8C 21 9F 02 06 9F 03 06 9F 1A 02 
95 05 5F 2A 02 9A 03 9C 01 9F 37 04 9F 35 01 9F 
45 02 9F 4C 08 9F 34 03 8D 0C 91 0A 8A 02 95 05 
9F 37 04 9F 4C 08 8E 0E 00 00 00 00 00 00 00 00 
42 03 5E 03 1F 03 9F 07 02 FF 00 9F 08 02 00 02 
9F 0D 05 00 00 00 00 00 9F 0E 05 00 08 00 60 00 
9F 0F 05 00 00 00 00 00 9F 42 02 09 78 9F 4A 01 
82 9F 14 01 00 9F 23 01 00 9F 13 02 00 00 

This response contains TLV data objects (without spaces). I have converted the response as described in the following:

// Read Record 1 with SFI2
//---------------------------------SEND READ RECORD-------------------
inCtlsSendVAPDU(0x2C,0x03,(unsigned char *)"\x00\xB2\x01\x14\x00",5);
clrscr();

inRet = inCTLSRecv2(Response, 269);
LOG_HEX_PRINTF("Essai EMV4 Read record 1 EMV Paypass:",Response,inRet);


if(Response[14]==0x70)
{
    sprintf(Response_PPSE,"%02X%02X",Response[12],Response[13]);//To retrieve  length of received data 
    t1=hexToInt(Response_PPSE);// Convert length to integer
    t11=t1-2;
    i=14; 
    k=0;

    //--------------------------- Converting data to be used later---------
    while(i<t11+14)// 14 to escape  the header+ command+ status+ length 
    {
        sprintf(READ1+(2*k),"%02X",Response[i]);
        i++;
        k++;
    }

Now I should check if this Response contains the Mandatory Tags:

  • 5A - Application Primary Account Number (PAN)
  • 5F24 - Application Expiration Date
  • 8C - Card Risk Management Data Object List 1 (CDOL1)
  • 8D - Card Risk Management Data Object List 2 (CDOL2)

So I tried the following to check for the 5A tag (Application Primary Account Number (PAN)):

i=0;
t11=2*t11;

while(i<=t11)
{
    strncpy(Response_PPSE,READ1+i,2);

    if(strncmp(Response_PPSE,"\x05\x0A")==0)
    {
        write_at("true",4,1,1);// Just to test on the terminal display 
        goto end;
    }
    else 
        i=i+2;
}  
goto end;

I don't know why nothing is displayed on the terminal, The if block is not executed!

I tried to print the 5A tag manually by:

strncpy(Response_PPSE,READ1+44,2);
write_at(Response_PPSE,strlen(Response_PPSE),1,1);

And it display the right value!!

Can someone helps to resolve this issue?


Solution

  • You don't find that tag because you are not searching for the string "5A" but for the string "\x05\x0A" (ENQ character + line feed character). Moreover, I wonder if the above code actually compiles as you did not specify the mandatory length argument to strncmp(). You could try something like

    if(strncmp(Response_PPSE,"5A", 2)==0)
    

    instead.

    However, you should understand that you are scanning the whole response data for the value 5A. Therefore, finding this value could also mean that it was part of some other TLV tag's data field, length field or even part of a multi-byte tag field. It would therefore make sense to implement (or use an existing) TLV parser for the BER (Basic Encoding Rules) format.