Im trying to use the GlobalPlatform library from Karsten Ohme (kaoh) in Delphi. Thanks to the help of some people here on stackoverflow i got it parially working and i am able to setup a connection to the cardreader. Now i am trying to select an AID, and therefore i need to pass the AID as array of Bytes to the function.
I use the GPShell (the commandline tool that uses the same library) source code as a reference to help me translate the functions. There i found the convertStringToByteArray function, which takes a string and converts it to a array of Bytes.
The original C function:
static int convertStringToByteArray(TCHAR *src, int destLength, BYTE *dest)
{
TCHAR *dummy;
unsigned int temp, i = 0;
dummy = malloc(destLength*2*sizeof(TCHAR) sizeof(TCHAR));
_tcsncpy(dummy, src, destLength*2 1);
dummy[destLength*2] = _T('\0');
while (_stscanf(&(dummy[i*2]), _T("x"), &temp) > 0)
{
dest[i] = (BYTE)temp;
i ;
}
free(dummy);
return i;
}
and i tried to write a similar procedure in Delphi, i tried to convert the string in two ways - the first (Literally) converts every character (treated as HEX) to integer. The second way uses Move:
procedure StrToByteArray(Input: AnsiString; var Bytes: array of Byte; Literally: Boolean = false);
var
I, B : Integer;
begin
if Literally then
begin
for I := 0 to Length(Input) -1 do
if TryStrToInt('$' Input[I 1], B) then
Bytes[I] := Byte(B)
else
Bytes[I] := Byte(0);
end else
Move(Input[1], Bytes[0], Length(Input));
end;
But i keep getting a
(6A82: The application to be selected could not be found.)
error, when i try to select AID
A000000003000000
I know i am trying to select the right AID, because when i use this same AID with GPShell - i get a successful response. So i am not sure if the problem is in my String to Byte array procedure, or maybe somewhere else.
When i use breakpoints, and i try to convert the string to bytes literally i get
(10, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0)
in the debugger. But when i try with Move (or ORD) i get
(65, 48, 48, 48, 48, 48, 48, 48, 48, 51, 48, 48, 48, 48, 48, 48)
I also tried to convert the string to bytes online with various websites, and these give me another result
(41, 30, 30, 30, 30, 30, 30, 30, 30, 33, 30, 30, 30, 30, 30, 30)
So i am a bit lost in trying to find out what im doing wrong, is the problem in my string to bytes conversion - or do i need to look somewhere else?
CodePudding user response:
The original C code parses pairs of hex digits into bytes:
A000000003000000
-> A0 00 00 00 03 00 00 00
But your Delphi code is parsing individual hex digits into bytes instead:
A000000003000000
-> A 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0
Try this instead:
procedure StrToByteArray(Input: AnsiString; var Bytes: TBytes; Literally: Boolean = false);
var
I, B : Integer;
begin
if Literally then
begin
SetLength(Bytes, Length(Input) div 2);
for I := 0 to Length(Bytes)-1 do
begin
if not TryStrToInt('$' Copy(Input, (I*2) 1, 2), B) then
B := 0;
Bytes[I] := Byte(B);
end;
end else
begin
SetLength(Bytes, Length(Input));
Move(Input[1], Bytes[0], Length(Input));
end:
end;
That being said, Delphi has its own HexToBin()
functions for parsing hex strings into byte arrays. You don't need to write your own parser, eg:
procedure StrToByteArray(Input: AnsiString; var Bytes: TBytes; Literally: Boolean = false);
begin
if Literally then
begin
SetLength(Bytes, Length(Input) div 2);
HexToBin(PAnsiChar(Input), PByte(Bytes), Length(Bytes));
end else
begin
SetLength(Bytes, Length(Input));
Move(Input[1], Bytes[0], Length(Input));
end:
end;