Sara Sara
Sara Sara

Reputation: 319

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:

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?

Upvotes: 1

Views: 1527

Answers (2)

Alex D
Alex D

Reputation: 989

It's not a good approach to search a specific byte in a raw byte-stream data using strings functions at first place.

The generic TLV parser is a very easy algorithm and you will do it in 30 minutes or so.

In general a pseudo-code for TLV parser that look for a specific Tag would be something like this:

index = 0
while (byte[i] != 0x5A or EOF)
{
     length = DecodeLength(byte[i+1])
     i += length + 2 // + 1 for L (length) byte itself, it might be encoded with
                     // 2 bytes so the function DecodeLength can return the number 
                     // of bytes lenght has been encoded
                     // +1 for T (tag) byte
}

if(EOF) return tag_not_found

return byte[i + 2], length // pointer to data for Tag '5A'and length of data

Upvotes: 0

Michael Roland
Michael Roland

Reputation: 40831

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.

Upvotes: 3

Related Questions