piv-tool: new action to print the key slots properties

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@5324 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
vtarasov 2011-04-11 12:02:47 +00:00
parent eb7bc552b1
commit b85e1a798f
2 changed files with 124 additions and 3 deletions

View File

@ -88,6 +88,12 @@
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--key-slots-discovery</option> file</term>
<listitem><para>Print properties of the key slots. Needs 'admin' authentication.
</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--send-apdu</option> apdu, <option>-s</option> apdu</term> <term><option>--send-apdu</option> apdu, <option>-s</option> apdu</term>
<listitem><para>Sends an arbitrary APDU to the card in the format AA:BB:CC:DD:EE:FF... <listitem><para>Sends an arbitrary APDU to the card in the format AA:BB:CC:DD:EE:FF...

View File

@ -60,6 +60,7 @@ static int verbose = 0;
enum { enum {
OPT_SERIAL = 0x100, OPT_SERIAL = 0x100,
OPT_KEY_SLOTS_DISCOVERY,
}; };
static const struct option options[] = { static const struct option options[] = {
@ -69,9 +70,10 @@ static const struct option options[] = {
{ "genkey", 1, NULL, 'G' }, { "genkey", 1, NULL, 'G' },
{ "object", 1, NULL, 'O' }, { "object", 1, NULL, 'O' },
{ "cert", 1, NULL, 'C' }, { "cert", 1, NULL, 'C' },
{ "compresscert", 1, NULL, 'Z' }, { "compresscert", 1, NULL, 'Z' },
{ "out", 1, NULL, 'o' }, { "out", 1, NULL, 'o' },
{ "in", 1, NULL, 'i' }, { "in", 1, NULL, 'i' },
{ "key-slots-discovery",0, NULL, OPT_KEY_SLOTS_DISCOVERY },
{ "send-apdu", 1, NULL, 's' }, { "send-apdu", 1, NULL, 's' },
{ "reader", 1, NULL, 'r' }, { "reader", 1, NULL, 'r' },
{ "card-driver", 1, NULL, 'c' }, { "card-driver", 1, NULL, 'c' },
@ -90,6 +92,7 @@ static const char *option_help[] = {
"Load a cert that has been gziped <ref>", "Load a cert that has been gziped <ref>",
"Output file for cert or key", "Output file for cert or key",
"Inout file for cert", "Inout file for cert",
"Key slots discovery (need admin authentication)",
"Sends an APDU in format AA:BB:CC:DD:EE:FF...", "Sends an APDU in format AA:BB:CC:DD:EE:FF...",
"Uses reader number <arg> [0]", "Uses reader number <arg> [0]",
"Forces the use of driver <arg> [auto-detect]", "Forces the use of driver <arg> [auto-detect]",
@ -102,6 +105,31 @@ static sc_card_t *card = NULL;
static BIO * bp = NULL; static BIO * bp = NULL;
static EVP_PKEY * evpkey = NULL; static EVP_PKEY * evpkey = NULL;
static char *algorithm_identifiers[] = {
"3DES ECB ",
"2DES ECB ",
"2DES CBC ",
"3DES ECB ",
"3DES CBC ",
NULL,
"RSA 1024 bits",
"RSA 2048 bits",
"AES-128 ECB",
"AES-128 CBC",
"AES-192 ECB",
"AES-192 CBC",
"AES-256 ECB",
"AES-256 CBC",
"ECC P-224 ",
NULL,
NULL,
"ECC P-256 ",
NULL,
NULL,
"ECC P-384 ",
NULL,
};
static int load_object(const char * object_id, const char * object_file) static int load_object(const char * object_id, const char * object_file)
{ {
FILE *fp; FILE *fp;
@ -368,6 +396,77 @@ static int gen_key(const char * key_info)
return r; return r;
} }
static int key_slots_discovery(void)
{
sc_apdu_t apdu;
u8 sbuf[4] = {0x5C, 0x02, 0x3F, 0xF7};
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 % 12) {
fprintf(stderr, "Invalid key discovery data length\n");
return 1;
}
for (i=0;i<data_len/12;i++) {
unsigned char *slot = data + 12*i;
if (*(slot + 1) > 20) {
fprintf(stderr, "Invalid algorithm identifier\n");
return 1;
}
printf("%02X(%s): %02X(%s)", *(slot + 0), *(slot + 7) ? "loaded" : "not loaded",
*(slot + 1), algorithm_identifiers[*(slot + 1)]);
if (*(slot + 2) == 0)
printf (", ");
else if (*(slot + 2) == 0x35)
printf (", PIV-ADMIN ");
else if (*(slot + 2) == 0x29)
printf (", MutualAuth");
else {
fprintf(stderr, "Invalid role\n");
return 1;
}
printf(", ACLs %02X:%02X %02X:%02X", *(slot + 8), *(slot + 9), *(slot + 10), *(slot + 11));
printf("\n");
}
return SC_SUCCESS;
}
static int send_apdu(void) static int send_apdu(void)
{ {
sc_apdu_t apdu; sc_apdu_t apdu;
@ -470,6 +569,7 @@ int main(int argc, char * const argv[])
int compress_cert = 0; int compress_cert = 0;
int do_print_serial = 0; int do_print_serial = 0;
int do_print_name = 0; int do_print_name = 0;
int do_key_slots_discovery = 0;
int action_count = 0; int action_count = 0;
const char *opt_driver = NULL; const char *opt_driver = NULL;
const char *out_file = NULL; const char *out_file = NULL;
@ -494,6 +594,10 @@ int main(int argc, char * const argv[])
do_print_serial = 1; do_print_serial = 1;
action_count++; action_count++;
break; break;
case OPT_KEY_SLOTS_DISCOVERY:
do_key_slots_discovery = 1;
action_count++;
break;
case 's': case 's':
opt_apdus = (char **) realloc(opt_apdus, opt_apdus = (char **) realloc(opt_apdus,
(opt_apdu_count + 1) * sizeof(char *)); (opt_apdu_count + 1) * sizeof(char *));
@ -633,6 +737,17 @@ int main(int argc, char * const argv[])
printf("%s\n", card->name); printf("%s\n", card->name);
action_count--; action_count--;
} }
if (do_key_slots_discovery) {
if (!do_admin_mode) {
fprintf(stderr, "Key slots discovery needs admin authentication\n");
err = 1;
goto end;
}
if (verbose)
printf("Key slots discovery: ");
if ((err = key_slots_discovery()))
goto end;
}
end: end:
if (bp) if (bp)