#!/usr/bin/perl
my
%options
;
my
$hContext
= new Chipcard::PCSC();
my
$hCard
;
my
$RecvData
;
my
$nRecordsLength
;
my
$PIN
;
die
(
"Could not create PCSC object: $Chipcard::PCSC::errno\n"
)
unless
defined
$hContext
;
sub
gsmrecord_to_ascii {
my
$gsmrecord
=
shift
;
my
$out_string
=
''
;
my
$delta
=
$#$gsmrecord
-27;
my
$i
;
if
(
$$gsmrecord
[0] != 0xFF) {
for
$i
(0..14+
$delta
-1) {
if
(
$$gsmrecord
[
$i
] != 0xFF) {
$out_string
.=
chr
(
$$gsmrecord
[
$i
])
}
else
{
$out_string
.=
' '
;
}
}
my
$phone_length
=
$$gsmrecord
[14] - 2;
if
(
$phone_length
> 0) {
my
$digit
;
$out_string
.=
'-> '
;
for
$i
(16+
$delta
..
$#$gsmrecord
) {
$digit
=
$$gsmrecord
[
$i
]&0x0F;
$out_string
.=
sprintf
(
"%01X"
,
$digit
)
if
(
$digit
!=0x0F);
$digit
= (
$$gsmrecord
[
$i
]&0xF0)>>4;
$out_string
.=
sprintf
(
"%01X"
,
$digit
)
if
(
$digit
!=0x0F);
}
}
else
{
$out_string
.=
"null or invalid phone"
;
}
}
return
$out_string
;
}
sub
pin_to_array {
my
$pin
=
shift
;
my
@array
;
confess (
"PIN code must not exceed 8 bytes."
)
unless
(
length
$pin
<= 8);
$pin
=~ s/(.)/$1 /g;
@array
=
split
/ /,
$pin
;
@array
=
map
(
ord
,
@array
);
while
(
$#array
< 7) {
push
@array
, 0xFF; }
return
@array
;
}
getopt (
'hvr:'
, \
%options
);
if
(
exists
$options
{h}) {
print
"TODO: usage -v verbose -r reader -h help"
;
}
if
(
exists
$options
{r}) {
$hCard
= new Chipcard::PCSC::Card (
$hContext
,
$options
{r});
die
(
"Can't allocate PCSCCard object: $Chipcard::PCSC::errno\n"
)
unless
defined
$hCard
;
print
STDERR
"Using given card reader: $options{r}\n"
if
exists
$options
{
'v'
};
}
else
{
my
@readers_list
=
$hContext
->ListReaders ();
die
(
"Can't get readers list: $Chipcard::PCSC::errno\n"
)
unless
defined
$readers_list
[0];
print
STDERR
"No reader given: using $readers_list[0]\n"
if
exists
$options
{v};
$hCard
= new Chipcard::PCSC::Card (
$hContext
,
$readers_list
[0]);
die
(
"Can't allocate PCSCCard object: $Chipcard::PCSC::errno\n"
)
unless
defined
$hCard
;
}
print
STDERR
"Selecting Master File (3F00)\n"
if
exists
$options
{v};
$RecvData
=
$hCard
->Transmit([0xA0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00]);
die
(
"Can't communicate: $Chipcard::PCSC::errno\n"
)
unless
defined
$RecvData
;
die
(
"Can't select MF: SW = [ "
.Chipcard::PCSC::array_to_ascii(
$RecvData
).
" ]"
)
unless
$$RecvData
[0] == 0x9F;
print
STDERR
"Selecting Telecom Directory (3F00/7F10)\n"
if
exists
$options
{v};
$RecvData
=
$hCard
->Transmit([0xA0, 0xA4, 0x00, 0x00, 0x02, 0x7F, 0x10]);
die
(
"Can't communicate: $Chipcard::PCSC::errno\n"
)
unless
defined
$RecvData
;
die
(
"Can't select DF Telecom: SW = [ "
.Chipcard::PCSC::array_to_ascii(
$RecvData
).
" ]"
)
unless
$$RecvData
[0] == 0x9F;
print
STDERR
"Selecting Abbreviated Dialing Numbers File (3F00/7F10/6F3A)\n"
if
exists
$options
{v};
$RecvData
=
$hCard
->Transmit([0xA0, 0xA4, 0x00, 0x00, 0x02, 0x6F, 0x3A]);
die
(
"Can't communicate: $Chipcard::PCSC::errno\n"
)
unless
defined
$RecvData
;
die
(
"Can't select EF_ADN: SW = [ "
.Chipcard::PCSC::array_to_ascii(
$RecvData
).
" ]"
)
unless
$$RecvData
[0] == 0x9F;
print
STDERR
"Getting ADN Records length\n"
if
exists
$options
{v};
$nRecordsLength
=
$$RecvData
[1];
$RecvData
=
$hCard
->Transmit([0xA0, 0xC0, 0x00, 0x00,
$nRecordsLength
]);
die
(
"Can't communicate: $Chipcard::PCSC::errno\n"
)
unless
defined
$RecvData
;
die
(
"Can't retrieve records length: SW = [ "
.Chipcard::PCSC::array_to_ascii(
$RecvData
).
" ]"
)
unless
$$RecvData
[
$nRecordsLength
] == 0x90;
$nRecordsLength
=
$$RecvData
[
$nRecordsLength
-1];
print
STDERR
"Records are $nRecordsLength bytes long\n"
if
exists
$options
{v};
print
STDOUT
"Please insert your PIN code:"
;
ReadMode
'noecho'
;
$PIN
= ReadLine 0;
ReadMode
'normal'
;
chomp
$PIN
;
print
STDOUT
"\n"
;
print
STDERR
"Submitting PIN code\n"
if
exists
$options
{v};
$RecvData
=
$hCard
->Transmit([0xA0, 0x20, 0x00, 0x01, 0x08, pin_to_array(
$PIN
)]);
die
(
"Can't communicate: $Chipcard::PCSC::errno\n"
)
unless
defined
$RecvData
;
die
(
"Can't access file (wrong PIN code ?): SW = [ "
.Chipcard::PCSC::array_to_ascii(
$RecvData
).
" ]"
)
unless
$$RecvData
[0] == 0x90;
my
$i
;
my
@SW
;
print
STDERR
"Getting records\n"
if
exists
$options
{v};
for
$i
(1..255) {
$RecvData
=
$hCard
->Transmit([0xA0, 0xB2,
$i
, 0x04,
$nRecordsLength
]);
die
(
"Can't communicate: $Chipcard::PCSC::errno\n"
)
unless
defined
$RecvData
;
$SW
[1] =
pop
@$RecvData
;
$SW
[0] =
pop
@$RecvData
;
die
(
"Can't read from EF_ADN: SW = [ "
.
sprintf
(
"%02X %02X"
,
$SW
[0],
$SW
[1]).
" ]\n"
)
if
(
$SW
[0] != 0x94 &&
$SW
[0] != 0x90);
last
if
$SW
[0] != 0x90;
print
"SLOT $i: "
.gsmrecord_to_ascii(
$RecvData
).
"\n"
;
}
print
STDERR
"Reseting the card\n"
if
exists
$options
{v};
$hCard
->Disconnect(
$Chipcard::PCSC::SCARD_RESET
);