Merge pull request #1896 from marschap/explorer-card-drivers

opensc-explorer: make '--card-driver ?' list all available drivers
This commit is contained in:
Frank Morgner 2020-01-22 09:20:29 +01:00 committed by GitHub
commit 61c20cf83d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 139 additions and 145 deletions

View File

@ -33,13 +33,6 @@ smart cards and similar security tokens based on Siemens Card/OS M4.
<title>Options</title>
<para>
<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>
<term>
<option>--format</option>,

View File

@ -95,14 +95,6 @@
</para>
</listitem>
</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>
<term>
<option>--wait</option>,

View File

@ -55,8 +55,11 @@
<option>-c</option> <replaceable>driver</replaceable>
</term>
<listitem><para>
Use the given card driver. The default is
auto-detected.
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 and terminates
<command>opensc-explorer</command>.
</para></listitem>
</varlistentry>
<varlistentry>

View File

@ -52,8 +52,12 @@
<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>
<listitem><para>
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>
<term>

View File

@ -163,14 +163,6 @@
</para>
</listitem>
</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>
<term>
<option>--wait</option>,

View File

@ -39,6 +39,7 @@
#endif
#include "libopensc/opensc.h"
#include "libopensc/cards.h"
#include "util.h"
static const char *app_name = "cardos-tool";
@ -54,7 +55,6 @@ static const struct option options[] = {
{"startkey", 1, NULL, 's'},
{"change-startkey", 1, NULL, 'S'},
{"reader", 1, NULL, 'r'},
{"card-driver", 1, NULL, 'c'},
{"wait", 0, NULL, 'w'},
{"verbose", 0, NULL, 'v'},
{NULL, 0, NULL, 0}
@ -67,7 +67,6 @@ static const char *option_help[] = {
"Specify startkey for format",
"Change Startkey with given APDU command",
"Uses reader number <arg> [0]",
"Forces the use of driver <arg> [auto-detect]",
"Wait for a card to be inserted",
"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 err = 0, r, c, long_optind = 0;
int err = 0, r, c;
int do_info = 0;
int do_format = 0;
int do_change_startkey = 0;
int action_count = 0;
const char *opt_driver = NULL;
const char *opt_startkey = NULL;
const char *opt_change_startkey = NULL;
sc_context_param_t ctx_param;
while (1) {
c = getopt_long(argc, argv, "hifs:r:vdc:wS:", options,
&long_optind);
if (c == -1)
break;
while ((c = getopt_long(argc, argv, "hifs:r:vdwS:", options, (int *) 0)) != -1) {
switch (c) {
case 'h':
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':
verbose++;
break;
case 'c':
opt_driver = optarg;
break;
case 'w':
opt_wait = 1;
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;
}
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;
goto end;
}
/* force CardOS card driver */
err = sc_set_card_driver(ctx, "cardos");
if (err) {
fprintf(stderr, "CardOS card driver not found!\n");
err = 1;
goto end;
}
err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
if (err)
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 ((err = cardos_info())) {
goto end;

View File

@ -36,6 +36,7 @@
#include "libopensc/opensc.h"
#include "libopensc/errors.h"
#include "libopensc/cardctl.h"
#include "libopensc/cards.h"
#include "libopensc/pkcs15.h"
#include "util.h"
@ -54,7 +55,6 @@ static const char *app_name = "dnie-tool";
static const struct option options[] = {
{"reader", 1, NULL, 'r'},
{"driver", 1, NULL, 'c'},
{"wait", 0, NULL, 'w'},
{"pin", 1, NULL, 'p'},
{"idesp", 0, NULL, 'i'},
@ -68,7 +68,6 @@ static const struct option options[] = {
static const char *option_help[] = {
"Uses reader number <arg> [0]",
"Uses card driver <arg> [auto-detect]",
"Wait for a card to be inserted",
"Specify PIN",
"Retrieve IDESP",
@ -86,7 +85,6 @@ int main(int argc, char* argv[])
int opt_wait = 0;
const char *opt_pin = NULL;
const char *opt_reader = NULL;
const char *opt_driver = NULL;
int opt_operation = OP_NONE;
int verbose = 0;
@ -94,25 +92,16 @@ int main(int argc, char* argv[])
sc_context_t *ctx = NULL;
sc_context_param_t ctx_param;
sc_card_t *card = NULL;
int c, long_optind, r, tries_left;
int c, r;
char *data[] = { NULL, NULL, NULL, NULL, NULL };
sc_serial_number_t serial;
while (1) {
c = getopt_long(argc, argv, "r:c:wp:iVdsav",
options, &long_optind);
if (c == -1)
break;
while ((c = getopt_long(argc, argv, "r:wp:iVdsav", options, (int *) 0)) != -1) {
switch (c) {
case '?':
util_print_usage_and_die(app_name, options, option_help, NULL);
case 'r':
opt_reader = optarg;
break;
case 'c':
opt_driver = optarg;
break;
case 'w':
opt_wait = 1;
break;
@ -137,6 +126,8 @@ int main(int argc, char* argv[])
case 'v':
verbose++;
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) {
fprintf(stderr, "Error: Failed to establish context: %s\n",
sc_strerror(r));
err = -1;
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;
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) ) {
@ -165,13 +155,16 @@ int main(int argc, char* argv[])
goto dnie_tool_end;
}
if ( strcmp(card->name,"dnie") ) {
fprintf(stderr, "Error: Card seems not to be a DNIe\n");
err=-1;
/* fail if card is not a DNIe card */
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;
goto dnie_tool_end;
}
if ( opt_pin ) {
int tries_left;
/* verify */
r = sc_verify(card, SC_AC_CHV, 0,
(u8*)opt_pin, strlen(opt_pin), &tries_left);
@ -186,44 +179,44 @@ int main(int argc, char* argv[])
}
}
if (opt_operation==0) {
fprintf(stderr,"Error: No operation specified");
err = -1;
goto dnie_tool_end;
}
if (opt_operation & 0x0f) {
if (opt_operation & (OP_GET_DATA | OP_GET_IDESP | OP_GET_VERSION | OP_GET_SERIALNR)) {
r = sc_card_ctl(card, SC_CARDCTL_DNIE_GET_INFO, data);
if ( r != SC_SUCCESS ) {
fprintf(stderr, "Error: Get info failed: %s\n", sc_strerror(r));
err = -1;
goto dnie_tool_end;
}
}
if (opt_operation & OP_GET_DATA) {
printf("DNIe Number: %s\n",data[0]);
printf("SurName: %s\n",data[1]);
printf("Name: %s\n",data[2]);
}
if (opt_operation & OP_GET_IDESP) {
if (data[3]==NULL)
printf("IDESP: (Not available)\n");
else printf("IDESP: %s\n",data[3]);
}
if (opt_operation & OP_GET_VERSION) {
if (data[4]==NULL)
printf("DNIe Version: (Not available)\n");
else printf("DNIe Version: %s\n",data[4]);
}
if (opt_operation & OP_GET_SERIALNR) {
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
if ( r != SC_SUCCESS ) {
fprintf(stderr,"Error: Get serial failed: %s\n",sc_strerror(r));
err = -1;
goto dnie_tool_end;
if (opt_operation & OP_GET_DATA) {
printf("DNIe Number: %s\n",data[0]);
printf("Surname: %s\n",data[1]);
printf("Name: %s\n",data[2]);
}
printf("Serial number: ");
util_hex_dump(stdout, serial.value, serial.len, NULL);
putchar('\n');
if (opt_operation & OP_GET_IDESP) {
if (data[3]==NULL)
printf("IDESP: (Not available)\n");
else printf("IDESP: %s\n",data[3]);
}
if (opt_operation & OP_GET_VERSION) {
if (data[4]==NULL)
printf("DNIe Version: (Not available)\n");
else printf("DNIe Version: %s\n",data[4]);
}
if (opt_operation & OP_GET_SERIALNR) {
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
if ( r != SC_SUCCESS ) {
fprintf(stderr,"Error: Get serial failed: %s\n",sc_strerror(r));
err = -1;
goto dnie_tool_end;
}
printf("Serial number: ");
util_hex_dump(stdout, serial.value, serial.len, NULL);
putchar('\n');
}
}
else {
fprintf(stderr,"Error: No operation specified");
err = -1;
}
dnie_tool_end:

View File

@ -105,7 +105,7 @@ static void decode_options(int argc, char **argv)
{
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) {
case 'r':

View File

@ -446,7 +446,8 @@ int main(
int r, oerr=0, reader=0, debug=0, pin_nr=-1, cert_nr=-1;
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 'v': ++debug; break;
case 'r': reader=atoi(optarg); break;
@ -455,6 +456,7 @@ int main(
case '0': set_pin(pinlist[2].value, &pinlist[2].len, optarg); break;
case '1': set_pin(pinlist[3].value, &pinlist[3].len, optarg); break;
default: ++oerr;
}
}
if(do_help){
fprintf(stderr,"This is netkey-tool V1.0, May 15 2005, Copyright Peter Koch <pk_opensc@web.de>\n");

View File

@ -461,7 +461,7 @@ static int decode_options(int argc, char **argv)
char *endptr;
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) {
case 'r':
opt_reader = optarg;

View File

@ -76,7 +76,7 @@ static const struct option options[] = {
};
static const char *option_help[] = {
"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]",
"Wait for card insertion",
"Verbose operation. Use several times to enable debug output.",
@ -2152,6 +2152,12 @@ int main(int argc, char *argv[])
}
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);
if (err) {
fprintf(stderr, "Driver '%s' not found!\n", opt_driver);

View File

@ -90,7 +90,7 @@ static const char *option_help[] = {
"Sends an APDU in format AA:BB:CC:DD:EE:FF...",
"Uses reader number <arg> [0]",
"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",
"Wait for a card to be inserted",
"Verbose operation. Use several times to enable debug output.",
@ -300,22 +300,6 @@ static int list_readers(void)
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,
const sc_path_t *path, int depth)
{
@ -784,6 +768,13 @@ int main(int argc, char *argv[])
break;
case 'c':
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;
case 'w':
opt_wait = 1;
@ -844,7 +835,7 @@ int main(int argc, char *argv[])
action_count--;
}
if (do_list_drivers) {
if ((err = list_drivers()))
if ((err = util_list_card_drivers(ctx)))
goto end;
action_count--;
}

View File

@ -52,6 +52,7 @@
#include "libopensc/opensc.h"
#include "libopensc/cardctl.h"
#include "libopensc/cards.h"
#include "libopensc/asn1.h"
#include "util.h"
#include "libopensc/sc-ossl-compat.h"
@ -80,7 +81,6 @@ static const struct option options[] = {
{ "in", 1, NULL, 'i' },
{ "send-apdu", 1, NULL, 's' },
{ "reader", 1, NULL, 'r' },
{ "card-driver", 1, NULL, 'c' },
{ "wait", 0, NULL, 'w' },
{ "verbose", 0, NULL, 'v' },
{ NULL, 0, NULL, 0 }
@ -98,7 +98,6 @@ static const char *option_help[] = {
"Input file for cert",
"Sends an APDU in format AA:BB:CC:DD:EE:FF...",
"Uses reader number <arg> [0]",
"Forces the use of driver <arg> [auto-detect]",
"Wait for a card to be inserted",
"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 err = 0, r, c, long_optind = 0;
int err = 0, r, c;
int do_send_apdu = 0;
int do_admin_mode = 0;
int do_gen_key = 0;
@ -479,7 +478,6 @@ int main(int argc, char *argv[])
int do_print_serial = 0;
int do_print_name = 0;
int action_count = 0;
const char *opt_driver = NULL;
const char *out_file = NULL;
const char *in_file = NULL;
const char *cert_id = NULL;
@ -489,12 +487,7 @@ int main(int argc, char *argv[])
sc_context_param_t ctx_param;
char **old_apdus = NULL;
while (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);
while ((c = getopt_long(argc, argv, "nA:G:O:Z:C:i:o:r:fvs:c:w", options, (int *) 0)) != -1) {
switch (c) {
case OPT_SERIAL:
do_print_serial = 1;
@ -554,14 +547,14 @@ int main(int argc, char *argv[])
case 'v':
verbose++;
break;
case 'c':
opt_driver = optarg;
break;
case 'w':
opt_wait = 1;
break;
default:
util_print_usage_and_die(app_name, options, option_help, NULL);
}
}
if (action_count == 0)
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)
goto 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;
goto end;
}
/* force PIV card driver */
err = sc_set_card_driver(ctx, "PIV-II");
if (err) {
fprintf(stderr, "PIV card driver not found!\n");
err = 1;
goto end;
}
err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
if (err)
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 ((err = admin_mode(admin_info)))
goto end;

View File

@ -305,6 +305,26 @@ util_print_usage_and_die(const char *app_name, const struct option options[],
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)
{
static char line[80], buf[20];

View File

@ -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);
NORETURN void util_print_usage_and_die(const char *app_name, const struct option options[],
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);
void util_warn(const char *fmt, ...);
void util_error(const char *fmt, ...);