piv-tool: add containers discovery

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@5334 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
vtarasov 2011-04-12 17:51:08 +00:00
parent 6705e2506b
commit d611dcc9ed
1 changed files with 75 additions and 1 deletions

View File

@ -61,6 +61,7 @@ static int verbose = 0;
enum {
OPT_SERIAL = 0x100,
OPT_KEY_SLOTS_DISCOVERY,
OPT_CONTAINERS_DISCOVERY,
};
static const struct option options[] = {
@ -74,6 +75,7 @@ static const struct option options[] = {
{ "out", 1, NULL, 'o' },
{ "in", 1, NULL, 'i' },
{ "key-slots-discovery",0, NULL, OPT_KEY_SLOTS_DISCOVERY },
{ "containers-discovery",0, NULL, OPT_CONTAINERS_DISCOVERY},
{ "send-apdu", 1, NULL, 's' },
{ "reader", 1, NULL, 'r' },
{ "card-driver", 1, NULL, 'c' },
@ -93,6 +95,7 @@ static const char *option_help[] = {
"Output file for cert or key",
"Inout file for cert",
"Key slots discovery (need admin authentication)",
"Containers discovery (need admin authentication)",
"Sends an APDU in format AA:BB:CC:DD:EE:FF...",
"Uses reader number <arg> [0]",
"Forces the use of driver <arg> [auto-detect]",
@ -467,6 +470,62 @@ static int key_slots_discovery(void)
return SC_SUCCESS;
}
static int containers_discovery(void)
{
sc_apdu_t apdu;
u8 sbuf[4] = {0x5C, 0x02, 0x3F, 0xF6};
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE*3], *data = NULL;
unsigned int cla_out, tag_out;
size_t r, i, data_len;
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xCB, 0x3F, 0xFF);
apdu.lc = sizeof(sbuf);
apdu.le = 256;
apdu.data = sbuf;
apdu.datalen = sizeof(sbuf);
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
r = sc_transmit_apdu(card, &apdu);
if (r) {
fprintf(stderr, "APDU transmit failed: %s\n", sc_strerror(r));
return 1;
}
data = rbuf;
if (*data != 0x53) {
fprintf(stderr, "Invalid 'GET DATA' response\n");
return 1;
}
if (*(data + 1) & 0x80) {
for (i=0, data_len=0; i < (*(data + 1) & 0x7F); i++)
data_len = data_len * 0x100 + *(data + 2 + i);
data += 2 + i;
}
else {
data_len = *(data + 1);
data += 2;
}
if (data_len % 9) {
fprintf(stderr, "Invalid containers discovery data length\n");
return 1;
}
for (i=0;i<data_len/9;i++) {
unsigned char *slot = data + 9*i;
printf("%02X%02X%02X", *(slot + 0), *(slot + 1), *(slot + 2));
printf(", size %02X%02X", *(slot + 3), *(slot + 4));
printf(", ACLs %02X:%02X %02X:%02X", *(slot + 5), *(slot + 6), *(slot + 7), *(slot + 8));
printf("\n");
}
return SC_SUCCESS;
}
static int send_apdu(void)
{
sc_apdu_t apdu;
@ -570,6 +629,7 @@ int main(int argc, char * const argv[])
int do_print_serial = 0;
int do_print_name = 0;
int do_key_slots_discovery = 0;
int do_containers_discovery = 0;
int action_count = 0;
const char *opt_driver = NULL;
const char *out_file = NULL;
@ -598,6 +658,10 @@ int main(int argc, char * const argv[])
do_key_slots_discovery = 1;
action_count++;
break;
case OPT_CONTAINERS_DISCOVERY:
do_containers_discovery = 1;
action_count++;
break;
case 's':
opt_apdus = (char **) realloc(opt_apdus,
(opt_apdu_count + 1) * sizeof(char *));
@ -748,7 +812,17 @@ int main(int argc, char * const argv[])
if ((err = key_slots_discovery()))
goto end;
}
if (do_containers_discovery) {
if (!do_admin_mode) {
fprintf(stderr, "Containers discovery needs admin authentication\n");
err = 1;
goto end;
}
if (verbose)
printf("Containers discovery: ");
if ((err = containers_discovery()))
goto end;
}
end:
if (bp)
BIO_free(bp);