Merge pull request #1896 from marschap/explorer-card-drivers
opensc-explorer: make '--card-driver ?' list all available drivers
This commit is contained in:
commit
61c20cf83d
|
@ -33,13 +33,6 @@ smart cards and similar security tokens based on Siemens Card/OS M4.
|
||||||
<title>Options</title>
|
<title>Options</title>
|
||||||
<para>
|
<para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<option>--card-driver</option> <replaceable>name</replaceable>,
|
|
||||||
<option>-c</option> <replaceable>name</replaceable></term>
|
|
||||||
<listitem><para>Use the card driver specified by <replaceable>name</replaceable>.
|
|
||||||
The default is to auto-detect the correct card driver.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<option>--format</option>,
|
<option>--format</option>,
|
||||||
|
|
|
@ -95,14 +95,6 @@
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<option>--driver</option> <replaceable>driver</replaceable>,
|
|
||||||
<option>-c</option> <replaceable>driver</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem><para>Specify the card driver <replaceable>driver</replaceable> to use.
|
|
||||||
Default is use driver from configuration file, or auto-detect if absent</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<option>--wait</option>,
|
<option>--wait</option>,
|
||||||
|
|
|
@ -55,8 +55,11 @@
|
||||||
<option>-c</option> <replaceable>driver</replaceable>
|
<option>-c</option> <replaceable>driver</replaceable>
|
||||||
</term>
|
</term>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
Use the given card driver. The default is
|
Use the given card driver.
|
||||||
auto-detected.
|
The default is to auto-detect the correct card driver.
|
||||||
|
The literal value <literal>?</literal> lists
|
||||||
|
all available card drivers and terminates
|
||||||
|
<command>opensc-explorer</command>.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
|
|
@ -52,8 +52,12 @@
|
||||||
<option>--card-driver</option> <replaceable>driver</replaceable>,
|
<option>--card-driver</option> <replaceable>driver</replaceable>,
|
||||||
<option>-c</option> <replaceable>driver</replaceable>
|
<option>-c</option> <replaceable>driver</replaceable>
|
||||||
</term>
|
</term>
|
||||||
<listitem><para>Use the given card driver.
|
<listitem><para>
|
||||||
The default is auto-detected.</para></listitem>
|
Use the given card driver.
|
||||||
|
The default is to auto-detect the correct card driver.
|
||||||
|
The literal value <literal>?</literal> lists
|
||||||
|
all available card drivers.
|
||||||
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
|
|
|
@ -163,14 +163,6 @@
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<option>--card-driver</option> <replaceable>driver</replaceable>,
|
|
||||||
<option>-c</option> <replaceable>driver</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem><para>Use the given card driver.
|
|
||||||
The default is auto-detected.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<option>--wait</option>,
|
<option>--wait</option>,
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libopensc/opensc.h"
|
#include "libopensc/opensc.h"
|
||||||
|
#include "libopensc/cards.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
static const char *app_name = "cardos-tool";
|
static const char *app_name = "cardos-tool";
|
||||||
|
@ -54,7 +55,6 @@ static const struct option options[] = {
|
||||||
{"startkey", 1, NULL, 's'},
|
{"startkey", 1, NULL, 's'},
|
||||||
{"change-startkey", 1, NULL, 'S'},
|
{"change-startkey", 1, NULL, 'S'},
|
||||||
{"reader", 1, NULL, 'r'},
|
{"reader", 1, NULL, 'r'},
|
||||||
{"card-driver", 1, NULL, 'c'},
|
|
||||||
{"wait", 0, NULL, 'w'},
|
{"wait", 0, NULL, 'w'},
|
||||||
{"verbose", 0, NULL, 'v'},
|
{"verbose", 0, NULL, 'v'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
|
@ -67,7 +67,6 @@ static const char *option_help[] = {
|
||||||
"Specify startkey for format",
|
"Specify startkey for format",
|
||||||
"Change Startkey with given APDU command",
|
"Change Startkey with given APDU command",
|
||||||
"Uses reader number <arg> [0]",
|
"Uses reader number <arg> [0]",
|
||||||
"Forces the use of driver <arg> [auto-detect]",
|
|
||||||
"Wait for a card to be inserted",
|
"Wait for a card to be inserted",
|
||||||
"Verbose operation. Use several times to enable debug output.",
|
"Verbose operation. Use several times to enable debug output.",
|
||||||
};
|
};
|
||||||
|
@ -1034,21 +1033,16 @@ static int cardos_change_startkey(const char *change_startkey_apdu) {
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int err = 0, r, c, long_optind = 0;
|
int err = 0, r, c;
|
||||||
int do_info = 0;
|
int do_info = 0;
|
||||||
int do_format = 0;
|
int do_format = 0;
|
||||||
int do_change_startkey = 0;
|
int do_change_startkey = 0;
|
||||||
int action_count = 0;
|
int action_count = 0;
|
||||||
const char *opt_driver = NULL;
|
|
||||||
const char *opt_startkey = NULL;
|
const char *opt_startkey = NULL;
|
||||||
const char *opt_change_startkey = NULL;
|
const char *opt_change_startkey = NULL;
|
||||||
sc_context_param_t ctx_param;
|
sc_context_param_t ctx_param;
|
||||||
|
|
||||||
while (1) {
|
while ((c = getopt_long(argc, argv, "hifs:r:vdwS:", options, (int *) 0)) != -1) {
|
||||||
c = getopt_long(argc, argv, "hifs:r:vdc:wS:", options,
|
|
||||||
&long_optind);
|
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h':
|
case 'h':
|
||||||
printf("NB! This tool is only for Siemens CardOS based cards!\n\n");
|
printf("NB! This tool is only for Siemens CardOS based cards!\n\n");
|
||||||
|
@ -1075,12 +1069,11 @@ int main(int argc, char *argv[])
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose++;
|
verbose++;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
|
||||||
opt_driver = optarg;
|
|
||||||
break;
|
|
||||||
case 'w':
|
case 'w':
|
||||||
opt_wait = 1;
|
opt_wait = 1;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1095,20 +1088,25 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_driver != NULL) {
|
/* force CardOS card driver */
|
||||||
err = sc_set_card_driver(ctx, opt_driver);
|
err = sc_set_card_driver(ctx, "cardos");
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "Driver '%s' not found!\n",
|
fprintf(stderr, "CardOS card driver not found!\n");
|
||||||
opt_driver);
|
|
||||||
err = 1;
|
err = 1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
|
err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
|
||||||
if (err)
|
if (err)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
/* fail if card is not a CardOS card */
|
||||||
|
if (card->type < SC_CARD_TYPE_CARDOS_BASE || card->type >= SC_CARD_TYPE_CARDOS_BASE+1000) {
|
||||||
|
fprintf(stderr, "Card type %X: not a CardOS card\n", card->type);
|
||||||
|
err = 1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (do_info) {
|
if (do_info) {
|
||||||
if ((err = cardos_info())) {
|
if ((err = cardos_info())) {
|
||||||
goto end;
|
goto end;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "libopensc/opensc.h"
|
#include "libopensc/opensc.h"
|
||||||
#include "libopensc/errors.h"
|
#include "libopensc/errors.h"
|
||||||
#include "libopensc/cardctl.h"
|
#include "libopensc/cardctl.h"
|
||||||
|
#include "libopensc/cards.h"
|
||||||
#include "libopensc/pkcs15.h"
|
#include "libopensc/pkcs15.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -54,7 +55,6 @@ static const char *app_name = "dnie-tool";
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
{"reader", 1, NULL, 'r'},
|
{"reader", 1, NULL, 'r'},
|
||||||
{"driver", 1, NULL, 'c'},
|
|
||||||
{"wait", 0, NULL, 'w'},
|
{"wait", 0, NULL, 'w'},
|
||||||
{"pin", 1, NULL, 'p'},
|
{"pin", 1, NULL, 'p'},
|
||||||
{"idesp", 0, NULL, 'i'},
|
{"idesp", 0, NULL, 'i'},
|
||||||
|
@ -68,7 +68,6 @@ static const struct option options[] = {
|
||||||
|
|
||||||
static const char *option_help[] = {
|
static const char *option_help[] = {
|
||||||
"Uses reader number <arg> [0]",
|
"Uses reader number <arg> [0]",
|
||||||
"Uses card driver <arg> [auto-detect]",
|
|
||||||
"Wait for a card to be inserted",
|
"Wait for a card to be inserted",
|
||||||
"Specify PIN",
|
"Specify PIN",
|
||||||
"Retrieve IDESP",
|
"Retrieve IDESP",
|
||||||
|
@ -86,7 +85,6 @@ int main(int argc, char* argv[])
|
||||||
int opt_wait = 0;
|
int opt_wait = 0;
|
||||||
const char *opt_pin = NULL;
|
const char *opt_pin = NULL;
|
||||||
const char *opt_reader = NULL;
|
const char *opt_reader = NULL;
|
||||||
const char *opt_driver = NULL;
|
|
||||||
int opt_operation = OP_NONE;
|
int opt_operation = OP_NONE;
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
|
||||||
|
@ -94,25 +92,16 @@ int main(int argc, char* argv[])
|
||||||
sc_context_t *ctx = NULL;
|
sc_context_t *ctx = NULL;
|
||||||
sc_context_param_t ctx_param;
|
sc_context_param_t ctx_param;
|
||||||
sc_card_t *card = NULL;
|
sc_card_t *card = NULL;
|
||||||
int c, long_optind, r, tries_left;
|
int c, r;
|
||||||
|
|
||||||
char *data[] = { NULL, NULL, NULL, NULL, NULL };
|
char *data[] = { NULL, NULL, NULL, NULL, NULL };
|
||||||
sc_serial_number_t serial;
|
sc_serial_number_t serial;
|
||||||
|
|
||||||
while (1) {
|
while ((c = getopt_long(argc, argv, "r:wp:iVdsav", options, (int *) 0)) != -1) {
|
||||||
c = getopt_long(argc, argv, "r:c:wp:iVdsav",
|
|
||||||
options, &long_optind);
|
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '?':
|
|
||||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
|
||||||
case 'r':
|
case 'r':
|
||||||
opt_reader = optarg;
|
opt_reader = optarg;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
|
||||||
opt_driver = optarg;
|
|
||||||
break;
|
|
||||||
case 'w':
|
case 'w':
|
||||||
opt_wait = 1;
|
opt_wait = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -137,6 +126,8 @@ int main(int argc, char* argv[])
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose++;
|
verbose++;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,17 +137,16 @@ int main(int argc, char* argv[])
|
||||||
if (r) {
|
if (r) {
|
||||||
fprintf(stderr, "Error: Failed to establish context: %s\n",
|
fprintf(stderr, "Error: Failed to establish context: %s\n",
|
||||||
sc_strerror(r));
|
sc_strerror(r));
|
||||||
goto dnie_tool_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt_driver != NULL) {
|
|
||||||
err = sc_set_card_driver(ctx, opt_driver);
|
|
||||||
if (err) {
|
|
||||||
fprintf(stderr, "Driver '%s' not found!\n",
|
|
||||||
opt_driver);
|
|
||||||
err = -1;
|
err = -1;
|
||||||
goto dnie_tool_end;
|
goto dnie_tool_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* force DNIe card driver */
|
||||||
|
err = sc_set_card_driver(ctx, "dnie");
|
||||||
|
if (err) {
|
||||||
|
fprintf(stderr, "DNIe card driver not found!\n");
|
||||||
|
err = -1;
|
||||||
|
goto dnie_tool_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (util_connect_card(ctx, &card, opt_reader, opt_wait, verbose) ) {
|
if (util_connect_card(ctx, &card, opt_reader, opt_wait, verbose) ) {
|
||||||
|
@ -165,13 +155,16 @@ int main(int argc, char* argv[])
|
||||||
goto dnie_tool_end;
|
goto dnie_tool_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( strcmp(card->name,"dnie") ) {
|
/* fail if card is not a DNIe card */
|
||||||
fprintf(stderr, "Error: Card seems not to be a DNIe\n");
|
if (card->type < SC_CARD_TYPE_DNIE_BASE || card->type >= SC_CARD_TYPE_DNIE_BASE+1000) {
|
||||||
|
fprintf(stderr, "Card type %X: not a DNIe card\n", card->type);
|
||||||
err = -1;
|
err = -1;
|
||||||
goto dnie_tool_end;
|
goto dnie_tool_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( opt_pin ) {
|
if ( opt_pin ) {
|
||||||
|
int tries_left;
|
||||||
|
|
||||||
/* verify */
|
/* verify */
|
||||||
r = sc_verify(card, SC_AC_CHV, 0,
|
r = sc_verify(card, SC_AC_CHV, 0,
|
||||||
(u8*)opt_pin, strlen(opt_pin), &tries_left);
|
(u8*)opt_pin, strlen(opt_pin), &tries_left);
|
||||||
|
@ -186,22 +179,17 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_operation==0) {
|
if (opt_operation & (OP_GET_DATA | OP_GET_IDESP | OP_GET_VERSION | OP_GET_SERIALNR)) {
|
||||||
fprintf(stderr,"Error: No operation specified");
|
|
||||||
err = -1;
|
|
||||||
goto dnie_tool_end;
|
|
||||||
}
|
|
||||||
if (opt_operation & 0x0f) {
|
|
||||||
r = sc_card_ctl(card, SC_CARDCTL_DNIE_GET_INFO, data);
|
r = sc_card_ctl(card, SC_CARDCTL_DNIE_GET_INFO, data);
|
||||||
if ( r != SC_SUCCESS ) {
|
if ( r != SC_SUCCESS ) {
|
||||||
fprintf(stderr, "Error: Get info failed: %s\n", sc_strerror(r));
|
fprintf(stderr, "Error: Get info failed: %s\n", sc_strerror(r));
|
||||||
err = -1;
|
err = -1;
|
||||||
goto dnie_tool_end;
|
goto dnie_tool_end;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (opt_operation & OP_GET_DATA) {
|
if (opt_operation & OP_GET_DATA) {
|
||||||
printf("DNIe Number: %s\n",data[0]);
|
printf("DNIe Number: %s\n",data[0]);
|
||||||
printf("SurName: %s\n",data[1]);
|
printf("Surname: %s\n",data[1]);
|
||||||
printf("Name: %s\n",data[2]);
|
printf("Name: %s\n",data[2]);
|
||||||
}
|
}
|
||||||
if (opt_operation & OP_GET_IDESP) {
|
if (opt_operation & OP_GET_IDESP) {
|
||||||
|
@ -225,6 +213,11 @@ int main(int argc, char* argv[])
|
||||||
util_hex_dump(stdout, serial.value, serial.len, NULL);
|
util_hex_dump(stdout, serial.value, serial.len, NULL);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"Error: No operation specified");
|
||||||
|
err = -1;
|
||||||
|
}
|
||||||
|
|
||||||
dnie_tool_end:
|
dnie_tool_end:
|
||||||
if (card) {
|
if (card) {
|
||||||
|
|
|
@ -105,7 +105,7 @@ static void decode_options(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv,"pwtr:x:hV", options, (int *) 0)) != EOF) {
|
while ((c = getopt_long(argc, argv,"pwtr:x:hV", options, (int *) 0)) != -1) {
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'r':
|
case 'r':
|
||||||
|
|
|
@ -446,7 +446,8 @@ int main(
|
||||||
int r, oerr=0, reader=0, debug=0, pin_nr=-1, cert_nr=-1;
|
int r, oerr=0, reader=0, debug=0, pin_nr=-1, cert_nr=-1;
|
||||||
size_t i, newlen=0;
|
size_t i, newlen=0;
|
||||||
|
|
||||||
while((r=getopt_long(argc,argv,"hvr:p:u:0:1:",options,NULL))!=EOF) switch(r){
|
while ((r = getopt_long(argc, argv, "hvr:p:u:0:1:", options, NULL)) != -1) {
|
||||||
|
switch (r) {
|
||||||
case 'h': ++do_help; break;
|
case 'h': ++do_help; break;
|
||||||
case 'v': ++debug; break;
|
case 'v': ++debug; break;
|
||||||
case 'r': reader=atoi(optarg); break;
|
case 'r': reader=atoi(optarg); break;
|
||||||
|
@ -456,6 +457,7 @@ int main(
|
||||||
case '1': set_pin(pinlist[3].value, &pinlist[3].len, optarg); break;
|
case '1': set_pin(pinlist[3].value, &pinlist[3].len, optarg); break;
|
||||||
default: ++oerr;
|
default: ++oerr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(do_help){
|
if(do_help){
|
||||||
fprintf(stderr,"This is netkey-tool V1.0, May 15 2005, Copyright Peter Koch <pk_opensc@web.de>\n");
|
fprintf(stderr,"This is netkey-tool V1.0, May 15 2005, Copyright Peter Koch <pk_opensc@web.de>\n");
|
||||||
fprintf(stderr,"usage: %s <options> command\n", argv[0]);
|
fprintf(stderr,"usage: %s <options> command\n", argv[0]);
|
||||||
|
|
|
@ -461,7 +461,7 @@ static int decode_options(int argc, char **argv)
|
||||||
char *endptr;
|
char *endptr;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv,"r:x:CUG:KEht:wvVd:", options, (int *) 0)) != EOF) {
|
while ((c = getopt_long(argc, argv,"r:x:CUG:KEht:wvVd:", options, (int *) 0)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'r':
|
case 'r':
|
||||||
opt_reader = optarg;
|
opt_reader = optarg;
|
||||||
|
|
|
@ -76,7 +76,7 @@ static const struct option options[] = {
|
||||||
};
|
};
|
||||||
static const char *option_help[] = {
|
static const char *option_help[] = {
|
||||||
"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; '?' for list]",
|
||||||
"Selects path <arg> on start-up, or none if empty [3F00]",
|
"Selects path <arg> on start-up, or none if empty [3F00]",
|
||||||
"Wait for card insertion",
|
"Wait for card insertion",
|
||||||
"Verbose operation. Use several times to enable debug output.",
|
"Verbose operation. Use several times to enable debug output.",
|
||||||
|
@ -2152,6 +2152,12 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_driver != NULL) {
|
if (opt_driver != NULL) {
|
||||||
|
/* special card driver value "?" means: list available drivers */
|
||||||
|
if (strncmp("?", opt_driver, sizeof("?")) == 0) {
|
||||||
|
err = util_list_card_drivers(ctx);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
err = sc_set_card_driver(ctx, opt_driver);
|
err = sc_set_card_driver(ctx, opt_driver);
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "Driver '%s' not found!\n", opt_driver);
|
fprintf(stderr, "Driver '%s' not found!\n", opt_driver);
|
||||||
|
|
|
@ -90,7 +90,7 @@ static const char *option_help[] = {
|
||||||
"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]",
|
||||||
"Does card reset of type <cold|warm> [cold]",
|
"Does card reset of type <cold|warm> [cold]",
|
||||||
"Forces the use of driver <arg> [auto-detect]",
|
"Forces the use of driver <arg> [auto-detect; '?' for list]",
|
||||||
"Lists algorithms supported by card",
|
"Lists algorithms supported by card",
|
||||||
"Wait for a card to be inserted",
|
"Wait for a card to be inserted",
|
||||||
"Verbose operation. Use several times to enable debug output.",
|
"Verbose operation. Use several times to enable debug output.",
|
||||||
|
@ -300,22 +300,6 @@ static int list_readers(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int list_drivers(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (ctx->card_drivers[0] == NULL) {
|
|
||||||
printf("No card drivers installed!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
printf("Configured card drivers:\n");
|
|
||||||
for (i = 0; ctx->card_drivers[i] != NULL; i++) {
|
|
||||||
printf(" %-16s %s\n", ctx->card_drivers[i]->short_name,
|
|
||||||
ctx->card_drivers[i]->name);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int print_file(sc_card_t *in_card, const sc_file_t *file,
|
static int print_file(sc_card_t *in_card, const sc_file_t *file,
|
||||||
const sc_path_t *path, int depth)
|
const sc_path_t *path, int depth)
|
||||||
{
|
{
|
||||||
|
@ -784,6 +768,13 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
opt_driver = optarg;
|
opt_driver = optarg;
|
||||||
|
|
||||||
|
/* treat argument "?" as request to list drivers */
|
||||||
|
if (opt_driver && strncmp("?", opt_driver, sizeof("?")) == 0) {
|
||||||
|
opt_driver = NULL;
|
||||||
|
do_list_drivers = 1;
|
||||||
|
action_count++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
opt_wait = 1;
|
opt_wait = 1;
|
||||||
|
@ -844,7 +835,7 @@ int main(int argc, char *argv[])
|
||||||
action_count--;
|
action_count--;
|
||||||
}
|
}
|
||||||
if (do_list_drivers) {
|
if (do_list_drivers) {
|
||||||
if ((err = list_drivers()))
|
if ((err = util_list_card_drivers(ctx)))
|
||||||
goto end;
|
goto end;
|
||||||
action_count--;
|
action_count--;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
|
|
||||||
#include "libopensc/opensc.h"
|
#include "libopensc/opensc.h"
|
||||||
#include "libopensc/cardctl.h"
|
#include "libopensc/cardctl.h"
|
||||||
|
#include "libopensc/cards.h"
|
||||||
#include "libopensc/asn1.h"
|
#include "libopensc/asn1.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "libopensc/sc-ossl-compat.h"
|
#include "libopensc/sc-ossl-compat.h"
|
||||||
|
@ -80,7 +81,6 @@ static const struct option options[] = {
|
||||||
{ "in", 1, NULL, 'i' },
|
{ "in", 1, NULL, 'i' },
|
||||||
{ "send-apdu", 1, NULL, 's' },
|
{ "send-apdu", 1, NULL, 's' },
|
||||||
{ "reader", 1, NULL, 'r' },
|
{ "reader", 1, NULL, 'r' },
|
||||||
{ "card-driver", 1, NULL, 'c' },
|
|
||||||
{ "wait", 0, NULL, 'w' },
|
{ "wait", 0, NULL, 'w' },
|
||||||
{ "verbose", 0, NULL, 'v' },
|
{ "verbose", 0, NULL, 'v' },
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
|
@ -98,7 +98,6 @@ static const char *option_help[] = {
|
||||||
"Input file for cert",
|
"Input file for cert",
|
||||||
"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]",
|
|
||||||
"Wait for a card to be inserted",
|
"Wait for a card to be inserted",
|
||||||
"Verbose operation. Use several times to enable debug output.",
|
"Verbose operation. Use several times to enable debug output.",
|
||||||
};
|
};
|
||||||
|
@ -469,7 +468,7 @@ static void print_serial(sc_card_t *in_card)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int err = 0, r, c, long_optind = 0;
|
int err = 0, r, c;
|
||||||
int do_send_apdu = 0;
|
int do_send_apdu = 0;
|
||||||
int do_admin_mode = 0;
|
int do_admin_mode = 0;
|
||||||
int do_gen_key = 0;
|
int do_gen_key = 0;
|
||||||
|
@ -479,7 +478,6 @@ int main(int argc, char *argv[])
|
||||||
int do_print_serial = 0;
|
int do_print_serial = 0;
|
||||||
int do_print_name = 0;
|
int do_print_name = 0;
|
||||||
int action_count = 0;
|
int action_count = 0;
|
||||||
const char *opt_driver = NULL;
|
|
||||||
const char *out_file = NULL;
|
const char *out_file = NULL;
|
||||||
const char *in_file = NULL;
|
const char *in_file = NULL;
|
||||||
const char *cert_id = NULL;
|
const char *cert_id = NULL;
|
||||||
|
@ -489,12 +487,7 @@ int main(int argc, char *argv[])
|
||||||
sc_context_param_t ctx_param;
|
sc_context_param_t ctx_param;
|
||||||
char **old_apdus = NULL;
|
char **old_apdus = NULL;
|
||||||
|
|
||||||
while (1) {
|
while ((c = getopt_long(argc, argv, "nA:G:O:Z:C:i:o:r:fvs:c:w", options, (int *) 0)) != -1) {
|
||||||
c = getopt_long(argc, argv, "nA:G:O:Z:C:i:o:fvs:c:w", options, &long_optind);
|
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
if (c == '?')
|
|
||||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case OPT_SERIAL:
|
case OPT_SERIAL:
|
||||||
do_print_serial = 1;
|
do_print_serial = 1;
|
||||||
|
@ -554,14 +547,14 @@ int main(int argc, char *argv[])
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose++;
|
verbose++;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
|
||||||
opt_driver = optarg;
|
|
||||||
break;
|
|
||||||
case 'w':
|
case 'w':
|
||||||
opt_wait = 1;
|
opt_wait = 1;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action_count == 0)
|
if (action_count == 0)
|
||||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||||
|
|
||||||
|
@ -603,19 +596,25 @@ int main(int argc, char *argv[])
|
||||||
if (action_count <= 0)
|
if (action_count <= 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (opt_driver != NULL) {
|
/* force PIV card driver */
|
||||||
err = sc_set_card_driver(ctx, opt_driver);
|
err = sc_set_card_driver(ctx, "PIV-II");
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "Driver '%s' not found!\n", opt_driver);
|
fprintf(stderr, "PIV card driver not found!\n");
|
||||||
err = 1;
|
err = 1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
|
err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
|
||||||
if (err)
|
if (err)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
/* fail if card is not a PIV card */
|
||||||
|
if (card->type < SC_CARD_TYPE_PIV_II_BASE || card->type >= SC_CARD_TYPE_PIV_II_BASE+1000) {
|
||||||
|
fprintf(stderr, "Card type %X: not a PIV card\n", card->type);
|
||||||
|
err = 1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (do_admin_mode) {
|
if (do_admin_mode) {
|
||||||
if ((err = admin_mode(admin_info)))
|
if ((err = admin_mode(admin_info)))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
|
@ -305,6 +305,26 @@ util_print_usage_and_die(const char *app_name, const struct option options[],
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int util_list_card_drivers(const sc_context_t *ctx)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (ctx == NULL) {
|
||||||
|
fprintf(stderr, "Unable to get card drivers!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (ctx->card_drivers[0] == NULL) {
|
||||||
|
fprintf(stderr, "No card drivers installed!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Available card drivers:\n");
|
||||||
|
for (i = 0; ctx->card_drivers[i] != NULL; i++) {
|
||||||
|
printf(" %-16s %s\n", ctx->card_drivers[i]->short_name,
|
||||||
|
ctx->card_drivers[i]->name);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const char * util_acl_to_str(const sc_acl_entry_t *e)
|
const char * util_acl_to_str(const sc_acl_entry_t *e)
|
||||||
{
|
{
|
||||||
static char line[80], buf[20];
|
static char line[80], buf[20];
|
||||||
|
|
|
@ -41,6 +41,7 @@ void util_hex_dump(FILE *f, const u8 *in, int len, const char *sep);
|
||||||
void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr);
|
void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr);
|
||||||
NORETURN void util_print_usage_and_die(const char *app_name, const struct option options[],
|
NORETURN void util_print_usage_and_die(const char *app_name, const struct option options[],
|
||||||
const char *option_help[], const char *args);
|
const char *option_help[], const char *args);
|
||||||
|
int util_list_card_drivers(const sc_context_t *ctx);
|
||||||
const char * util_acl_to_str(const struct sc_acl_entry *e);
|
const char * util_acl_to_str(const struct sc_acl_entry *e);
|
||||||
void util_warn(const char *fmt, ...);
|
void util_warn(const char *fmt, ...);
|
||||||
void util_error(const char *fmt, ...);
|
void util_error(const char *fmt, ...);
|
||||||
|
|
Loading…
Reference in New Issue