diff --git a/scd/app-common.h b/scd/app-common.h index cdb941283..d3d8869fa 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -43,7 +43,34 @@ #define APP_DECIPHER_INFO_NOPAD 1 /* Padding has been removed. */ +/* List of supported card types. Generic is the usual ISO7817-4 + * compliant card. More specific card or token versions can be given + * here. Use strcardtype() to map them to a string. */ +typedef enum + { + CARDTYPE_GENERIC = 0, + CARDTYPE_YUBIKEY + } cardtype_t; + +/* List of supported card applications. The source code for each + * application can usually be found in an app-NAME.c file. Use + * strapptype() to map them to a string. */ +typedef enum + { + APPTYPE_NONE = 0, + APPTYPE_UNDEFINED, + APPTYPE_OPENPGP, + APPTYPE_PIV, + APPTYPE_NKS, + APPTYPE_P15, + APPTYPE_GELDKARTE, + APPTYPE_DINSIG, + APPTYPE_SC_HSM + } apptype_t; + + +/* Formeard declararion. */ struct app_local_s; /* Defined by all app-*.c. */ @@ -59,7 +86,7 @@ struct card_ctx_s { /* Used reader slot. */ int slot; - const char *cardtype; /* NULL or string with the token's type. */ + cardtype_t cardtype; /* The token's type. */ unsigned int cardversion;/* Firmware version of the token or 0. */ unsigned int card_status; @@ -91,7 +118,7 @@ struct app_ctx_s { card_t card; /* Link back to the card. */ - const char *apptype; + apptype_t apptype; /* The type of the application. */ unsigned int appversion; /* Version of the application or 0. */ unsigned int did_chv1:1; unsigned int force_chv1:1; /* True if the card does not cache CHV1. */ @@ -186,6 +213,9 @@ size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff); /*-- app.c --*/ +const char *strcardtype (cardtype_t t); +const char *strapptype (apptype_t t); + void app_update_priority_list (const char *arg); void app_send_card_list (ctrl_t ctrl); char *card_get_serialno (card_t card); diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c index 74de30cc5..d02938cb1 100644 --- a/scd/app-dinsig.c +++ b/scd/app-dinsig.c @@ -556,7 +556,7 @@ app_select_dinsig (app_t app) rc = iso7816_select_application (slot, aid, sizeof aid, 0); if (!rc) { - app->apptype = "DINSIG"; + app->apptype = APPTYPE_DINSIG; app->fnc.learn_status = do_learn_status; app->fnc.readcert = do_readcert; diff --git a/scd/app-geldkarte.c b/scd/app-geldkarte.c index e126f2adb..4589f3da6 100644 --- a/scd/app-geldkarte.c +++ b/scd/app-geldkarte.c @@ -312,7 +312,7 @@ app_select_geldkarte (app_t app) goto leave; /* Probably not a Geldkarte. */ } - app->apptype = "GELDKARTE"; + app->apptype = APPTYPE_GELDKARTE; app->fnc.deinit = do_deinit; /* If we don't have a serialno yet construct it from the EF_ID. */ diff --git a/scd/app-nks.c b/scd/app-nks.c index bc54c016e..3f985c24a 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -1411,7 +1411,7 @@ app_select_nks (app_t app) rc = iso7816_select_application (slot, aid_nks, sizeof aid_nks, 0); if (!rc) { - app->apptype = "NKS"; + app->apptype = APPTYPE_NKS; app->app_local = xtrycalloc (1, sizeof *app->app_local); if (!app->app_local) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 4f17a3c44..b93b7b557 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -5224,7 +5224,7 @@ app_select_openpgp (app_t app) { unsigned int manufacturer; - app->apptype = "OPENPGP"; + app->apptype = APPTYPE_OPENPGP; app->did_chv1 = 0; app->did_chv2 = 0; diff --git a/scd/app-p15.c b/scd/app-p15.c index 59cc195fb..3b7233926 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -3360,7 +3360,7 @@ app_select_p15 (app_t app) } if (!rc) { - app->apptype = "P15"; + app->apptype = APPTYPE_P15; app->app_local = xtrycalloc (1, sizeof *app->app_local); if (!app->app_local) diff --git a/scd/app-piv.c b/scd/app-piv.c index 4b3868729..331f914bb 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -3413,7 +3413,7 @@ app_select_piv (app_t app) if (err) goto leave; - app->apptype = "PIV"; + app->apptype = APPTYPE_PIV; app->did_chv1 = 0; app->did_chv2 = 0; app->did_chv3 = 0; @@ -3466,7 +3466,7 @@ app_select_piv (app_t app) goto leave; } - if (app->card->cardtype && !strcmp (app->card->cardtype, "yubikey")) + if (app->card->cardtype == CARDTYPE_YUBIKEY) app->app_local->flags.yubikey = 1; diff --git a/scd/app-sc-hsm.c b/scd/app-sc-hsm.c index a8a792369..d18a1a737 100644 --- a/scd/app-sc-hsm.c +++ b/scd/app-sc-hsm.c @@ -2056,7 +2056,7 @@ app_select_sc_hsm (app_t app) rc = iso7816_select_application (slot, sc_hsm_aid, sizeof sc_hsm_aid, 0); if (!rc) { - app->apptype = "SC-HSM"; + app->apptype = APPTYPE_SC_HSM; app->app_local = xtrycalloc (1, sizeof *app->app_local); if (!app->app_local) diff --git a/scd/app.c b/scd/app.c index aa26443f6..ef9e993d3 100644 --- a/scd/app.c +++ b/scd/app.c @@ -40,30 +40,58 @@ static npth_mutex_t card_list_lock; static card_t card_top; -/* The list of application names and there select function. Of no - * specfic application is selected the first available application on +/* The list of application names and their select function. If no + * specific application is selected the first available application on * a card is selected. */ struct app_priority_list_s { + apptype_t apptype; char const *name; gpg_error_t (*select_func)(app_t); }; static struct app_priority_list_s app_priority_list[] = - {{ "openpgp", app_select_openpgp }, - { "piv", app_select_piv }, - { "nks", app_select_nks }, - { "p15", app_select_p15 }, - { "geldkarte", app_select_geldkarte }, - { "dinsig", app_select_dinsig }, - { "sc-hsm", app_select_sc_hsm }, - { NULL, NULL } + {{ APPTYPE_OPENPGP , "openpgp", app_select_openpgp }, + { APPTYPE_PIV , "piv", app_select_piv }, + { APPTYPE_NKS , "nks", app_select_nks }, + { APPTYPE_P15 , "p15", app_select_p15 }, + { APPTYPE_GELDKARTE, "geldkarte", app_select_geldkarte }, + { APPTYPE_DINSIG , "dinsig", app_select_dinsig }, + { APPTYPE_SC_HSM , "sc-hsm", app_select_sc_hsm }, + { APPTYPE_NONE , NULL, NULL } + /* APPTYPE_UNDEFINED is special and not listed here. */ }; +/* Map a cardtype to a string. Never returns NULL. */ +const char * +strcardtype (cardtype_t t) +{ + switch (t) + { + case CARDTYPE_GENERIC: return "generic"; + case CARDTYPE_YUBIKEY: return "yubikey"; + } + return "?"; +} + + +/* Map an application type to a string. Never returns NULL. */ +const char * +strapptype (apptype_t t) +{ + int i; + + for (i=0; app_priority_list[i].apptype; i++) + if (app_priority_list[i].apptype == t) + return app_priority_list[i].name; + return t == APPTYPE_UNDEFINED? "undefined" : t? "?" : "none"; +} + + /* Initialization function to change the default app_priority_list. * LIST is a list of comma or space separated strings with application * names. Unknown names will only result in warning message. @@ -185,9 +213,10 @@ app_dump_state (void) for (c = card_top; c; c = c->next) { log_info ("app_dump_state: card=%p slot=%d type=%s\n", - c, c->slot, c->cardtype? c->cardtype:"unknown"); + c, c->slot, strcardtype (c->cardtype)); for (a=c->app; a; a = a->next) - log_info ("app_dump_state: app=%p type='%s'\n", a, a->apptype); + log_info ("app_dump_state: app=%p type='%s'\n", + a, strapptype (a->apptype)); } npth_mutex_unlock (&card_list_lock); } @@ -216,14 +245,15 @@ check_conflict (card_t card, const char *name) return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); /* Should not happen. */ /* FIXME: Needs changes for app switching. */ - if (card->app->apptype && !ascii_strcasecmp (card->app->apptype, name)) + if (!card->app->apptype + || !ascii_strcasecmp (strapptype (card->app->apptype), name)) return 0; - if (card->app->apptype && !strcmp (card->app->apptype, "UNDEFINED")) + if (card->app->apptype == APPTYPE_UNDEFINED) return 0; log_info ("application '%s' in use - can't switch\n", - card->app->apptype? card->app->apptype : ""); + strapptype (card->app->apptype)); return gpg_error (GPG_ERR_CONFLICT); } @@ -335,7 +365,7 @@ app_new_register (int slot, ctrl_t ctrl, const char *name, && !iso7816_apdu_direct (slot, "\x00\x1d\x00\x00\x00", 5, 0, NULL, &buf, &buflen)) { - card->cardtype = "yubikey"; + card->cardtype = CARDTYPE_YUBIKEY; if (opt.verbose) { log_info ("Yubico: config="); @@ -446,7 +476,7 @@ app_new_register (int slot, ctrl_t ctrl, const char *name, { /* We switch to the "undefined" application only if explicitly requested. */ - app->apptype = "UNDEFINED"; + app->apptype = APPTYPE_UNDEFINED; /* Clear the error so that we don't run through the application * selection chain. */ err = 0; @@ -804,14 +834,14 @@ app_write_learn_status (card_t card, ctrl_t ctrl, unsigned int flags) if (!(flags &1)) { if (card->cardtype) - send_status_direct (ctrl, "CARDTYPE", card->cardtype); + send_status_direct (ctrl, "CARDTYPE", strcardtype (card->cardtype)); if (card->cardversion) send_status_printf (ctrl, "CARDVERSION", "%X", card->cardversion); if (app->apptype) - send_status_direct (ctrl, "APPTYPE", app->apptype); + send_status_direct (ctrl, "APPTYPE", strapptype (app->apptype)); if (app->appversion) send_status_printf (ctrl, "APPVERSION", "%X", app->appversion); - /* FIXME: Send infor for the otehr active apps of the card? */ + /* FIXME: Send info for the other active apps of the card? */ } err = lock_card (card, ctrl); @@ -893,14 +923,14 @@ app_getattr (card_t card, ctrl_t ctrl, const char *name) if (!card->ref_count || !card->app) return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (card->cardtype && name && !strcmp (name, "CARDTYPE")) + if (name && !strcmp (name, "CARDTYPE")) { - send_status_direct (ctrl, "CARDTYPE", card->cardtype); + send_status_direct (ctrl, "CARDTYPE", strcardtype (card->cardtype)); return 0; } - if (card->app->apptype && name && !strcmp (name, "APPTYPE")) + if (name && !strcmp (name, "APPTYPE")) { - send_status_direct (ctrl, "APPTYPE", card->app->apptype); + send_status_direct (ctrl, "APPTYPE", strapptype (card->app->apptype)); return 0; } if (name && !strcmp (name, "SERIALNO"))