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:
parent
eb7bc552b1
commit
b85e1a798f
|
@ -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...
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue