From b85e1a798fe481903c4e8c8fd2134d8aa0d02e38 Mon Sep 17 00:00:00 2001 From: vtarasov Date: Mon, 11 Apr 2011 12:02:47 +0000 Subject: [PATCH] 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 --- doc/tools/piv-tool.xml | 6 ++ src/tools/piv-tool.c | 121 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 124 insertions(+), 3 deletions(-) diff --git a/doc/tools/piv-tool.xml b/doc/tools/piv-tool.xml index 94939f3c..f2d1a7b1 100644 --- a/doc/tools/piv-tool.xml +++ b/doc/tools/piv-tool.xml @@ -88,6 +88,12 @@ + + file + Print properties of the key slots. Needs 'admin' authentication. + + + apdu, apdu Sends an arbitrary APDU to the card in the format AA:BB:CC:DD:EE:FF... diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 01369154..f9166509 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -60,6 +60,7 @@ static int verbose = 0; enum { OPT_SERIAL = 0x100, + OPT_KEY_SLOTS_DISCOVERY, }; static const struct option options[] = { @@ -69,9 +70,10 @@ static const struct option options[] = { { "genkey", 1, NULL, 'G' }, { "object", 1, NULL, 'O' }, { "cert", 1, NULL, 'C' }, - { "compresscert", 1, NULL, 'Z' }, - { "out", 1, NULL, 'o' }, - { "in", 1, NULL, 'i' }, + { "compresscert", 1, NULL, 'Z' }, + { "out", 1, NULL, 'o' }, + { "in", 1, NULL, 'i' }, + { "key-slots-discovery",0, NULL, OPT_KEY_SLOTS_DISCOVERY }, { "send-apdu", 1, NULL, 's' }, { "reader", 1, NULL, 'r' }, { "card-driver", 1, NULL, 'c' }, @@ -90,6 +92,7 @@ static const char *option_help[] = { "Load a cert that has been gziped ", "Output file for cert or key", "Inout file for cert", + "Key slots discovery (need admin authentication)", "Sends an APDU in format AA:BB:CC:DD:EE:FF...", "Uses reader number [0]", "Forces the use of driver [auto-detect]", @@ -102,6 +105,31 @@ static sc_card_t *card = NULL; static BIO * bp = 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) { FILE *fp; @@ -368,6 +396,77 @@ static int gen_key(const char * key_info) 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 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) { sc_apdu_t apdu; @@ -470,6 +569,7 @@ int main(int argc, char * const argv[]) int compress_cert = 0; int do_print_serial = 0; int do_print_name = 0; + int do_key_slots_discovery = 0; int action_count = 0; const char *opt_driver = NULL; const char *out_file = NULL; @@ -494,6 +594,10 @@ int main(int argc, char * const argv[]) do_print_serial = 1; action_count++; break; + case OPT_KEY_SLOTS_DISCOVERY: + do_key_slots_discovery = 1; + action_count++; + break; case 's': opt_apdus = (char **) realloc(opt_apdus, (opt_apdu_count + 1) * sizeof(char *)); @@ -633,6 +737,17 @@ int main(int argc, char * const argv[]) printf("%s\n", card->name); 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: if (bp)