diff --git a/g10/ChangeLog b/g10/ChangeLog index 0501c69b5..8fca7e7b0 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,13 @@ +2005-04-07 Werner Koch + + * ccid-driver.c (ccid_slot_status): Fixed debug messages. + + * card-util.c (card_edit): Add command "verify". Enhanced admin + command to allow optional arguments "on", "off" and "verify". + (card_status): Print private DOs in colon mode. + * app-openpgp.c (do_check_pin): Add hack to allow verification of + CHV3. + 2005-04-01 Werner Koch * keygen.c (keygen_set_std_prefs): Explain the chosen order of diff --git a/g10/app-openpgp.c b/g10/app-openpgp.c index 5948edde5..27fc0585c 100644 --- a/g10/app-openpgp.c +++ b/g10/app-openpgp.c @@ -1545,7 +1545,12 @@ do_decipher (app_t app, const char *keyidstr, cheap check on the PIN: If there is something wrong with the PIN entry system, only the regular CHV will get blocked and not the dangerous CHV3. KEYIDSTR is the usual card's serial number; an - optional fingerprint part will be ignored. */ + optional fingerprint part will be ignored. + + There is a special mode if the keyidstr is "[CHV3]" with + the "[CHV3]" being a literal string: The Admin Pin is checked if + and only if the retry counter is still at 3. +*/ static int do_check_pin (app_t app, const char *keyidstr, int (pincb)(void*, const char *, char **), @@ -1554,6 +1559,7 @@ do_check_pin (app_t app, const char *keyidstr, unsigned char tmp_sn[20]; const char *s; int n; + int admin_pin = 0; if (!keyidstr || !*keyidstr) return gpg_error (GPG_ERR_INV_VALUE); @@ -1570,6 +1576,8 @@ do_check_pin (app_t app, const char *keyidstr, ; /* No fingerprint given: we allow this for now. */ else if (*s == '/') ; /* We ignore a fingerprint. */ + else if (!strcmp (s, "[CHV3]") ) + admin_pin = 1; else return gpg_error (GPG_ERR_INV_ID); @@ -1585,7 +1593,40 @@ do_check_pin (app_t app, const char *keyidstr, problem and the check above is merely for a graceful failure between operations. */ - return verify_chv2 (app, pincb, pincb_arg); + if (admin_pin) + { + void *relptr; + unsigned char *value; + size_t valuelen; + int count; + + relptr = get_one_do (app, 0x00C4, &value, &valuelen); + if (!relptr || valuelen < 7) + { + log_error (_("error retrieving CHV status from card\n")); + xfree (relptr); + return gpg_error (GPG_ERR_CARD); + } + count = value[6]; + xfree (relptr); + + if (!count) + { + log_info (_("card is permanently locked!\n")); + return gpg_error (GPG_ERR_BAD_PIN); + } + else if (value[6] < 3) + { + log_info (_("verification of Admin PIN is currently prohibited " + "through this command\n")); + return gpg_error (GPG_ERR_GENERAL); + } + + app->did_chv3 = 0; /* Force verification. */ + return verify_chv3 (app, pincb, pincb_arg); + } + else + return verify_chv2 (app, pincb, pincb_arg); } diff --git a/g10/card-util.c b/g10/card-util.c index da786f7a8..ecb80f08a 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -287,6 +287,7 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen) int rc; unsigned int uval; const unsigned char *thefpr; + int i; if (serialno && serialnobuflen) *serialno = 0; @@ -363,6 +364,17 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen) info.chvretry[0], info.chvretry[1], info.chvretry[2]); fprintf (fp, "sigcount:%lu:::\n", info.sig_counter); + for (i=0; i < 4; i++) + { + if (info.private_do[i]) + { + fprintf (fp, "private_do:%d:", i+1); + print_string (fp, info.private_do[i], + strlen (info.private_do[i]), ':'); + fputs (":\n", fp); + } + } + fputs ("cafpr:", fp); print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL); print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL); @@ -1282,7 +1294,7 @@ card_store_subkey (KBNODE node, int use) enum cmdids { cmdNOP = 0, - cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, + cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY, cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR, cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdINVCMD @@ -1314,6 +1326,7 @@ static struct { "forcesig", cmdFORCESIG, 1, N_("toggle the signature force PIN flag")}, { "generate", cmdGENERATE, 1, N_("generate new keys")}, { "passwd" , cmdPASSWD, 0, N_("menu to change or unblock the PIN")}, + { "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")}, /* Note, that we do not announce this command yet. */ { "privatedo", cmdPRIVATEDO, 0, NULL }, { NULL, cmdINVCMD, 0, NULL } @@ -1485,13 +1498,33 @@ card_edit (STRLIST commands) break; case cmdADMIN: - allow_admin=!allow_admin; + if ( !strcmp (arg_string, "on") ) + allow_admin = 1; + else if ( !strcmp (arg_string, "off") ) + allow_admin = 0; + else if ( !strcmp (arg_string, "verify") ) + { + /* Force verification of the Admin Command. However, + this is only done if the retry counter is at initial + state. */ + char *tmp = xmalloc (strlen (serialnobuf) + 6 + 1); + strcpy (stpcpy (tmp, serialnobuf), "[CHV3]"); + allow_admin = !agent_scd_checkpin (tmp); + xfree (tmp); + } + else /* Toggle. */ + allow_admin=!allow_admin; if(allow_admin) tty_printf(_("Admin commands are allowed\n")); else tty_printf(_("Admin commands are not allowed\n")); break; + case cmdVERIFY: + agent_scd_checkpin (serialnobuf); + redisplay = 1; + break; + case cmdLIST: redisplay = 1; break; diff --git a/g10/ccid-driver.c b/g10/ccid-driver.c index 13e11e4bc..9fd983fe4 100644 --- a/g10/ccid-driver.c +++ b/g10/ccid-driver.c @@ -1303,12 +1303,12 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits) { if (!retries) { - fprintf (stderr, "CALLING USB_CLEAR_HALT\n"); + DEBUGOUT ("USB: CALLING USB_CLEAR_HALT\n"); usb_clear_halt (handle->idev, handle->ep_bulk_in); usb_clear_halt (handle->idev, handle->ep_bulk_out); } else - fprintf (stderr, "RETRYING AGIAN\n"); + DEBUGOUT ("USB: RETRYING bulk_in AGAIN\n"); retries++; goto retry; }