diff --git a/agent/ChangeLog b/agent/ChangeLog index 8596a2bec..497083c54 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,7 @@ +2009-06-09 Werner Koch + + * learncard.c (send_cert_back): Ignore certain error codes. + 2009-06-05 Werner Koch * protect-tool.c (store_private_key): Fix last change by appending diff --git a/agent/learncard.c b/agent/learncard.c index b5b5bd77d..77f2bb09d 100644 --- a/agent/learncard.c +++ b/agent/learncard.c @@ -262,9 +262,23 @@ send_cert_back (ctrl_t ctrl, const char *id, void *assuan_context) rc = agent_card_readcert (ctrl, id, &derbuf, &derbuflen); if (rc) { - log_error ("error reading certificate: %s\n", - gpg_strerror (rc)); - return rc; + const char *action; + + switch (gpg_err_code (rc)) + { + case GPG_ERR_INV_ID: + case GPG_ERR_NOT_FOUND: + action = " - ignored"; + break; + default: + action = ""; + break; + } + if (opt.verbose || !*action) + log_info ("error reading certificate `%s': %s%s\n", + id? id:"?", gpg_strerror (rc), action); + + return *action? 0 : rc; } rc = assuan_send_data (assuan_context, derbuf, derbuflen); @@ -288,6 +302,7 @@ int agent_handle_learn (ctrl_t ctrl, void *assuan_context) { int rc; + struct kpinfo_cb_parm_s parm; struct certinfo_cb_parm_s cparm; struct sinfo_cb_parm_s sparm; diff --git a/g10/ChangeLog b/g10/ChangeLog index 5eb5d0c68..688ff14e4 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,11 @@ +2009-06-09 Werner Koch + + * card-util.c (write_sc_op_status): New. + (change_pin): Use it. + (change_url, change_login, change_private_do, change_cert) + (change_lang, change_sex, change_cafpr, toggle_forcesig) + (check_pin_for_key_operation): Ditto. + 2009-06-05 David Shaw * gpg.c (main), misc.c (openpgp_cipher_test_algo): Remove Camellia diff --git a/g10/call-agent.c b/g10/call-agent.c index c8a2013ac..63919dd1f 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -667,7 +667,7 @@ agent_scd_pksign (const char *serialno, int hashalgo, /* Send the serialno command to initialize the connection. We don't care about the data returned. If the card has already been initialized, this is a very fast command. We request the openpgp - card because that is waht we expect. */ + card because that is what we expect. */ rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp", NULL, NULL, NULL, NULL, NULL, NULL); if (rc) @@ -732,7 +732,7 @@ agent_scd_pkdecrypt (const char *serialno, /* Send the serialno command to initialize the connection. We don't care about the data returned. If the card has already been initialized, this is a very fast command. We request the openpgp - card because that is waht we expect. */ + card because that is what we expect. */ rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp", NULL, NULL, NULL, NULL, NULL, NULL); if (rc) diff --git a/g10/card-util.c b/g10/card-util.c index b696144b0..290e3b784 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -48,6 +48,29 @@ #define CONTROL_D ('D' - 'A' + 1) +static void +write_sc_op_status (gpg_error_t err) +{ + switch (gpg_err_code (err)) + { + case 0: + write_status (STATUS_SC_OP_SUCCESS); + break; +#if GNUPG_MAJOR_VERSION != 1 + case GPG_ERR_CANCELED: + write_status_text (STATUS_SC_OP_FAILURE, "1"); + break; + case GPG_ERR_BAD_PIN: + write_status_text (STATUS_SC_OP_FAILURE, "2"); + break; + default: + write_status (STATUS_SC_OP_FAILURE); + break; +#endif /* GNUPG_MAJOR_VERSION != 1 */ + } +} + + /* Change the PIN of a an OpenPGP card. This is an interactive function. */ void @@ -86,25 +109,21 @@ change_pin (int unblock_v2, int allow_admin) else { rc = agent_scd_change_pin (2, info.serialno); + write_sc_op_status (rc); if (rc) tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); else - { - write_status (STATUS_SC_OP_SUCCESS); - tty_printf ("PIN changed.\n"); - } + tty_printf ("PIN changed.\n"); } } else if (!allow_admin) { rc = agent_scd_change_pin (1, info.serialno); + write_sc_op_status (rc); if (rc) tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); else - { - write_status (STATUS_SC_OP_SUCCESS); - tty_printf ("PIN changed.\n"); - } + tty_printf ("PIN changed.\n"); } else for (;;) @@ -129,50 +148,42 @@ change_pin (int unblock_v2, int allow_admin) { /* Change PIN. */ rc = agent_scd_change_pin (1, info.serialno); + write_sc_op_status (rc); if (rc) tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); else - { - write_status (STATUS_SC_OP_SUCCESS); - tty_printf ("PIN changed.\n"); - } + tty_printf ("PIN changed.\n"); } else if (*answer == '2') { /* Unblock PIN. */ rc = agent_scd_change_pin (101, info.serialno); + write_sc_op_status (rc); if (rc) tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc)); else - { - write_status (STATUS_SC_OP_SUCCESS); - tty_printf ("PIN unblocked and new PIN set.\n"); - } + tty_printf ("PIN unblocked and new PIN set.\n"); } else if (*answer == '3') { /* Change Admin PIN. */ rc = agent_scd_change_pin (3, info.serialno); + write_sc_op_status (rc); if (rc) tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); else - { - write_status (STATUS_SC_OP_SUCCESS); - tty_printf ("PIN changed.\n"); - } + tty_printf ("PIN changed.\n"); } else if (*answer == '4') { /* Set a new Reset Code. */ rc = agent_scd_change_pin (102, info.serialno); + write_sc_op_status (rc); if (rc) tty_printf ("Error setting the Reset Code: %s\n", gpg_strerror (rc)); else - { - write_status (STATUS_SC_OP_SUCCESS); - tty_printf ("Reset Code set.\n"); - } + tty_printf ("Reset Code set.\n"); } else if (*answer == 'q' || *answer == 'Q') { @@ -694,6 +705,7 @@ change_url (void) if (rc) log_error ("error setting URL: %s\n", gpg_strerror (rc)); xfree (url); + write_sc_op_status (rc); return rc; } @@ -744,6 +756,7 @@ fetch_url(void) return rc; #else + #warning need to implemented fucntion return 0; #endif } @@ -839,6 +852,7 @@ change_login (const char *args) if (rc) log_error ("error setting login data: %s\n", gpg_strerror (rc)); xfree (data); + write_sc_op_status (rc); return rc; } @@ -884,6 +898,7 @@ change_private_do (const char *args, int nr) if (rc) log_error ("error setting private DO: %s\n", gpg_strerror (rc)); xfree (data); + write_sc_op_status (rc); return rc; } @@ -913,6 +928,7 @@ change_cert (const char *args) if (rc) log_error ("error writing certificate to card: %s\n", gpg_strerror (rc)); xfree (data); + write_sc_op_status (rc); return rc; } @@ -950,6 +966,7 @@ change_lang (void) if (rc) log_error ("error setting lang: %s\n", gpg_strerror (rc)); xfree (data); + write_sc_op_status (rc); return rc; } @@ -985,6 +1002,7 @@ change_sex (void) if (rc) log_error ("error setting sex: %s\n", gpg_strerror (rc)); xfree (data); + write_sc_op_status (rc); return rc; } @@ -1029,6 +1047,7 @@ change_cafpr (int fprno) fprno==3?"CA-FPR-3":"x", fpr, 20, NULL ); if (rc) log_error ("error setting cafpr: %s\n", gpg_strerror (rc)); + write_sc_op_status (rc); return rc; } @@ -1054,6 +1073,7 @@ toggle_forcesig (void) rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1, NULL); if (rc) log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc)); + write_sc_op_status (rc); } @@ -1111,8 +1131,11 @@ check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1) binding signature. */ rc = agent_scd_checkpin (info->serialno); if (rc) - log_error ("error checking the PIN: %s\n", gpg_strerror (rc)); - } + { + log_error ("error checking the PIN: %s\n", gpg_strerror (rc)); + write_sc_op_status (rc); + } + } return rc; } diff --git a/scd/ChangeLog b/scd/ChangeLog index 7520ff43c..7fc8fe46d 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,9 @@ +2009-06-09 Werner Koch + + * app-openpgp.c (do_readcert): Return NOT_FOUND if the retrieved + data has a length of zero. + (do_getattr): Add EXTCAP subkey "sm". + 2009-05-20 Werner Koch * app-openpgp.c (verify_chv2): Add case for v2 cards. diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index c29e33da5..658459eb8 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -833,13 +833,16 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) char tmp[100]; snprintf (tmp, sizeof tmp, - "gc=%d ki=%d fc=%d pd=%d mcl3=%u aac=%d", + "gc=%d ki=%d fc=%d pd=%d mcl3=%u aac=%d sm=%d", app->app_local->extcap.get_challenge, app->app_local->extcap.key_import, app->app_local->extcap.change_force_chv, app->app_local->extcap.private_dos, app->app_local->extcap.max_certlen_3, - app->app_local->extcap.algo_attr_change); + app->app_local->extcap.algo_attr_change, + (app->app_local->extcap.sm_supported + ? (app->app_local->extcap.sm_aes128? 7 : 2) + : 0)); send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0); return 0; } @@ -1398,8 +1401,9 @@ do_readcert (app_t app, const char *certid, if (!relptr) return gpg_error (GPG_ERR_NOT_FOUND); - *cert = xtrymalloc (buflen); - if (!*cert) + if (!buflen) + err = gpg_error (GPG_ERR_NOT_FOUND); + else if (!(*cert = xtrymalloc (buflen))) err = gpg_error_from_syserror (); else { diff --git a/scd/app.c b/scd/app.c index eb97d846a..3f8248296 100644 --- a/scd/app.c +++ b/scd/app.c @@ -620,7 +620,7 @@ app_readcert (app_t app, const char *certid, code returned. This function might not be supported by all applications. */ -gpg_error_t +gpg_error_t app_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen) { gpg_error_t err;