diff --git a/po/ChangeLog b/po/ChangeLog index c1bcd81e1..25d7d4595 100644 --- a/po/ChangeLog +++ b/po/ChangeLog @@ -1,3 +1,9 @@ +2004-09-30 Werner Koch + + * de.po: Updated. + + * POTFILES.in: Add more files. + 2004-07-22 Werner Koch * de.po: Updated. diff --git a/po/POTFILES.in b/po/POTFILES.in index ae54716ac..eb4e36c85 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -15,6 +15,8 @@ jnlib/logging.c kbx/kbxutil.c scd/scdaemon.c +scd/sc-investigate.c +scd/app-openpgp.c sm/base64.c sm/call-agent.c diff --git a/po/de.po b/po/de.po index a09f0024d..3c4d90a44 100644 --- a/po/de.po +++ b/po/de.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: gnupg2 1.9.10\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"POT-Creation-Date: 2004-09-29 18:01+0200\n" -"PO-Revision-Date: 2004-09-29 18:10+0200\n" +"POT-Creation-Date: 2004-09-30 15:22+0200\n" +"PO-Revision-Date: 2004-09-30 15:23+0200\n" "Last-Translator: Werner Koch \n" "Language-Team: de\n" "MIME-Version: 1.0\n" @@ -100,12 +100,12 @@ msgid "allow clients to mark keys as \"trusted\"" msgstr "erlaube Aufrufern Schlüssel als \"vertrauenswürdig\" zu markieren" #: agent/gpg-agent.c:195 agent/protect-tool.c:134 scd/scdaemon.c:168 -#: sm/gpgsm.c:485 tools/gpgconf.c:85 +#: scd/sc-investigate.c:113 sm/gpgsm.c:485 tools/gpgconf.c:85 msgid "Please report bugs to <" msgstr "Fehlerberichte bitte an <" #: agent/gpg-agent.c:195 agent/protect-tool.c:134 scd/scdaemon.c:168 -#: sm/gpgsm.c:485 tools/gpgconf.c:85 +#: scd/sc-investigate.c:113 sm/gpgsm.c:485 tools/gpgconf.c:85 msgid ">.\n" msgstr ">.\n" @@ -127,7 +127,7 @@ msgid "invalid debug-level `%s' given\n" msgstr "ungültige Debugebene `%s' angegeben\n" #: agent/gpg-agent.c:446 agent/protect-tool.c:1050 kbx/kbxutil.c:436 -#: scd/scdaemon.c:357 sm/gpgsm.c:731 +#: scd/scdaemon.c:357 scd/sc-investigate.c:181 sm/gpgsm.c:731 #, c-format msgid "libgcrypt is too old (need %s, have %s)\n" msgstr "" @@ -432,6 +432,103 @@ msgstr "" "Bitte die Option `--daemon' nutzen um das Programm im Hintergund " "auszuführen\n" +#: scd/sc-investigate.c:116 +msgid "Usage: sc-investigate [options] (-h for help)\n" +msgstr "Gebrauch: sc-investigate [Optionen] (-h für Hilfe)\n" + +#: scd/sc-investigate.c:118 +msgid "" +"Syntax: sc-investigate [options] [args]]\n" +"Have a look at smartcards\n" +msgstr "" +"Gebrauch: sc-investigate [Optionen] [Argumente]\n" +"Den Inhalt einer Smartcard inspizieren\n" + +#: scd/app-openpgp.c:458 +#, c-format +msgid "failed to store the fingerprint: %s\n" +msgstr "Der Fingerprint kann nicht gespeichert werden: %s\n" + +#: scd/app-openpgp.c:471 +#, c-format +msgid "failed to store the creation date: %s\n" +msgstr "Das Erzeugungsdatum kann nicht gespeichert werden: %s\n" + +#: scd/app-openpgp.c:656 scd/app-openpgp.c:745 +#, c-format +msgid "PIN callback returned error: %s\n" +msgstr "Fehler vom PIN \"callback\": %s\n" + +#: scd/app-openpgp.c:662 scd/app-openpgp.c:751 scd/app-openpgp.c:1236 +#, c-format +msgid "prassphrase (CHV%d) is too short; minimum length is %d\n" +msgstr "Die Passphrase (CHV%d) ist zu kurz; Mindestlänge ist %d\n" + +#: scd/app-openpgp.c:671 scd/app-openpgp.c:685 scd/app-openpgp.c:761 +#: scd/app-openpgp.c:1245 scd/app-openpgp.c:1259 +#, c-format +msgid "verify CHV%d failed: %s\n" +msgstr "Prüfen von CHV%d fehlgeschlagen: %s\n" + +#: scd/app-openpgp.c:708 +msgid "access to admin commands is not configured\n" +msgstr "Zugriff auf Admin Kommandos ist nicht konfiguriert\n" + +#: scd/app-openpgp.c:725 +msgid "error retrieving CHV status from card\n" +msgstr "Fehler beim Holen des CHV Status von der Karte\n" + +#: scd/app-openpgp.c:731 +msgid "card is permanently locked!\n" +msgstr "Die Karte ist dauerhaft gesperrt!\n" + +#: scd/app-openpgp.c:738 +#, c-format +msgid "%d Admin PIN attempts remaining before card is permanently locked\n" +msgstr "" +"Noch %d Admin PIN Versuche möglich bevor die Karte dauerhaft gesperrt wird\n" + +#: scd/app-openpgp.c:742 +msgid "Admin PIN" +msgstr "Admin PIN" + +#: scd/app-openpgp.c:1504 +msgid "can't access CHV Status Bytes - invalid OpenPGP card?\n" +msgstr "" +"Zugriff auf die CHV Status Bytes nicht möglich - ungültige OpenPGP Karte?\n" + +#: scd/app-openpgp.c:1514 +msgid "can't access Extended Capability Flags - invalid OpenPGP card?\n" +msgstr "" +"Zugriff auf die Extended Capability Flags nicht möglich - ungültige OpenPGP " +"Karte?\n" + +#: scd/app-openpgp.c:1584 +#, c-format +msgid "error getting serial number: %s\n" +msgstr "Fehler beim Holen der Seriennummer: %s\n" + +#: scd/app-openpgp.c:1679 +#, c-format +msgid "failed to store the key: %s\n" +msgstr "Fehler beim Speichern des Schlüssels: %s\n" + +#: scd/app-openpgp.c:1721 +msgid "reading the key failed\n" +msgstr "Fehler beim Lesen des Schlüssels: %s\n" + +#: scd/app-openpgp.c:1728 +msgid "response does not contain the public key data\n" +msgstr "Die Antwort enthält keine Public Key Daten\n" + +#: scd/app-openpgp.c:1736 +msgid "response does not contain the RSA modulus\n" +msgstr "Die Antwort enthält keinen RSA Modulus\n" + +#: scd/app-openpgp.c:1747 +msgid "response does not contain the RSA public exponent\n" +msgstr "Die Antwort enthält keinen öffenlichen RSA Exponent\n" + #: sm/base64.c:315 #, c-format msgid "invalid radix64 character %02x skipped\n" @@ -488,7 +585,7 @@ msgstr "[Fehler - Ung msgid "[Error - invalid DN]" msgstr "[Fehler - Ungültiger DN]" -#: sm/certdump.c:652 +#: sm/certdump.c:655 #, c-format msgid "" "Please enter the passphrase to unlock the secret key for:\n" @@ -496,7 +593,7 @@ msgid "" "S/N %s, ID %08lX, created %s" msgstr "" "Bitte geben Sie die Passphrase an, um den \n" -"geheimen Schlüssels von\n" +"geheimen Schlüssel von\n" "\"%s\"\n" "S/N %s, ID %08lX, erzeugt %s\n" "zu entsperren" @@ -999,32 +1096,32 @@ msgstr "Verschl msgid "libksba is too old (need %s, have %s)\n" msgstr "Die Bibliothek Libksba is nicht aktuell (benötige %s, habe %s)\n" -#: sm/gpgsm.c:1182 +#: sm/gpgsm.c:1183 msgid "WARNING: program may create a core file!\n" msgstr "WARNUNG: Programm könnte eine core-dump-Datei schreiben!\n" -#: sm/gpgsm.c:1194 +#: sm/gpgsm.c:1195 msgid "WARNING: running with faked system time: " msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: " -#: sm/gpgsm.c:1220 +#: sm/gpgsm.c:1221 msgid "selected cipher algorithm is invalid\n" msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n" -#: sm/gpgsm.c:1228 +#: sm/gpgsm.c:1229 msgid "selected digest algorithm is invalid\n" msgstr "Das ausgewählte Hashverfahren ist ungültig\n" -#: sm/gpgsm.c:1258 +#: sm/gpgsm.c:1259 #, c-format msgid "can't sign using `%s': %s\n" msgstr "Signieren mit `%s' nicht möglich: %s\n" -#: sm/gpgsm.c:1422 +#: sm/gpgsm.c:1423 msgid "this command has not yet been implemented\n" msgstr "Diee Kommando wurde noch nicht implementiert\n" -#: sm/gpgsm.c:1645 sm/gpgsm.c:1678 +#: sm/gpgsm.c:1646 sm/gpgsm.c:1679 #, c-format msgid "can't open `%s': %s\n" msgstr "Datei `%s' kann nicht geöffnet werden: %s\n" diff --git a/scd/ChangeLog b/scd/ChangeLog index e6789fcb2..9640ef6b2 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,74 @@ +2004-09-30 Werner Koch + + * app-openpgp.c (do_sign): Add the error string to the verify + failed messages. + +2004-09-27 Werner Koch + + From gnupg 1.3 + + * app-openpgp.c: Made all strings translatable. + (verify_chv3) [GNUPG_MAJOR_VERSION]: Make opt.allow_admin + available for use in gnupg 2. + (verify_chv3): Reimplemented countdown showing to use only + functions from this module. Flush the CVH status cache on a + successful read. + (get_one_do): Hack to bypass the cache for cards versions > 1.0. + (store_fpr): Store the creation date for card version > 1.0. + + * app-openpgp.c (app_openpgp_storekey): Call flush_cache. + (get_cached_data): Move local data initialization to .. + (app_select_openpgp): .. here. Read some flags for later use. + (do_getattr): New read-only attribute EXTCAP. + + * apdu.c (open_pcsc_reader): Do not print empty reader string. + + * ccid-driver.c (do_close_reader): Factored some code out from ... + (ccid_close_reader): ..here. + (ccid_shutdown_reader): New. + + * apdu.c (apdu_shutdown_reader): New. + (shutdown_ccid_reader): New. + + * apdu.c (open_ccid_reader): New arg PORTSTR. Pass it to + ccid_open_reader. + (apdu_open_reader): Pass portstr to open_ccid_reader. + (apdu_open_reader): No fallback if a full CCID reader id has been + given. + + * ccid-driver.c (ccid_get_reader_list): New. + (ccid_open_reader): Changed API to take a string for the reader. + Removed al the cruft for the libusb development vesion which seems + not to be maintained anymore and there are no packages anyway. + The stable library works just fine. + (struct ccid_reader_id_s): Deleted and replaced everywhere by a + simple string. + (usb_get_string_simple): Removed. + (bulk_in): Do valgrind hack here and not just everywhere. + + * ccid-driver.c (read_device_info): Removed. + (make_reader_id, scan_or_find_devices): New. + (ccid_open_reader): Simplified by make use of the new functions. + (ccid_set_debug_level): New. Changed the macros to make use of + it. It has turned out that it is often useful to enable debugging + at runtime so I added this option. + + From gnupg 1.3 - David Shaw + + * app-openpgp.c (verify_chv3): Show a countdown of how many wrong + admin PINs can be entered before the card is locked. + + * app-openpgp.c (get_cached_data): Avoid mallocing zero since it + breaks us when using --enable-m-guard. + + * ccid-driver.c (usb_get_string_simple): Replacement function to + work with older libusb. + + * ccid-driver.c (read_device_info): Fix segfault when usb device + is not accessible. + (ccid_open_reader): Allow working with an even older version of + libusb (usb_busses global instead of usb_get_busses()). + 2004-09-11 Werner Koch * app-openpgp.c (app_select_openpgp): Its app_munge_serialno and diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 1617ab888..6f9837c90 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -34,12 +34,12 @@ #include "errors.h" #include "memory.h" #include "util.h" -#include "i18n.h" #include "cardglue.h" #else /* GNUPG_MAJOR_VERSION != 1 */ #include "scdaemon.h" #endif /* GNUPG_MAJOR_VERSION != 1 */ +#include "i18n.h" #include "iso7816.h" #include "app-common.h" #include "tlv.h" @@ -52,27 +52,33 @@ static struct { int binary; int dont_cache; int flush_on_error; + int get_immediate_in_v11; /* Enable a hack to bypass the cache of + this data object if it is used in 1.1 + and later versions of the card. This + does not work with composite DO and is + currently only useful for the CHV + status bytes. */ char *desc; } data_objects[] = { - { 0x005E, 0, 0, 1, 0, 0, "Login Data" }, - { 0x5F50, 0, 0, 0, 0, 0, "URL" }, - { 0x0065, 1, 0, 1, 0, 0, "Cardholder Related Data"}, - { 0x005B, 0, 0x65, 0, 0, 0, "Name" }, - { 0x5F2D, 0, 0x65, 0, 0, 0, "Language preferences" }, - { 0x5F35, 0, 0x65, 0, 0, 0, "Sex" }, - { 0x006E, 1, 0, 1, 0, 0, "Application Related Data" }, - { 0x004F, 0, 0x6E, 1, 0, 0, "AID" }, - { 0x0073, 1, 0, 1, 0, 0, "Discretionary Data Objects" }, - { 0x0047, 0, 0x6E, 1, 0, 0, "Card Capabilities" }, - { 0x00C0, 0, 0x6E, 1, 0, 0, "Extended Card Capabilities" }, - { 0x00C1, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Signature" }, - { 0x00C2, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Decryption" }, - { 0x00C3, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Authentication" }, - { 0x00C4, 0, 0x6E, 1, 0, 1, "CHV Status Bytes" }, - { 0x00C5, 0, 0x6E, 1, 0, 0, "Fingerprints" }, - { 0x00C6, 0, 0x6E, 1, 0, 0, "CA Fingerprints" }, - { 0x007A, 1, 0, 1, 0, 0, "Security Support Template" }, - { 0x0093, 0, 0x7A, 1, 1, 0, "Digital Signature Counter" }, + { 0x005E, 0, 0, 1, 0, 0, 0, "Login Data" }, + { 0x5F50, 0, 0, 0, 0, 0, 0, "URL" }, + { 0x0065, 1, 0, 1, 0, 0, 0, "Cardholder Related Data"}, + { 0x005B, 0, 0x65, 0, 0, 0, 0, "Name" }, + { 0x5F2D, 0, 0x65, 0, 0, 0, 0, "Language preferences" }, + { 0x5F35, 0, 0x65, 0, 0, 0, 0, "Sex" }, + { 0x006E, 1, 0, 1, 0, 0, 0, "Application Related Data" }, + { 0x004F, 0, 0x6E, 1, 0, 0, 0, "AID" }, + { 0x0073, 1, 0, 1, 0, 0, 0, "Discretionary Data Objects" }, + { 0x0047, 0, 0x6E, 1, 1, 0, 0, "Card Capabilities" }, + { 0x00C0, 0, 0x6E, 1, 1, 0, 0, "Extended Card Capabilities" }, + { 0x00C1, 0, 0x6E, 1, 1, 0, 0, "Algorithm Attributes Signature" }, + { 0x00C2, 0, 0x6E, 1, 1, 0, 0, "Algorithm Attributes Decryption" }, + { 0x00C3, 0, 0x6E, 1, 1, 0, 0, "Algorithm Attributes Authentication" }, + { 0x00C4, 0, 0x6E, 1, 0, 1, 1, "CHV Status Bytes" }, + { 0x00C5, 0, 0x6E, 1, 0, 0, 0, "Fingerprints" }, + { 0x00C6, 0, 0x6E, 1, 0, 0, 0, "CA Fingerprints" }, + { 0x007A, 1, 0, 1, 0, 0, 0, "Security Support Template" }, + { 0x0093, 0, 0x7A, 1, 1, 0, 0, "Digital Signature Counter" }, { 0 } }; @@ -86,6 +92,13 @@ struct cache_s { struct app_local_s { struct cache_s *cache; + struct + { + unsigned int get_challenge:1; + unsigned int key_import:1; + unsigned int change_force_chv:1; + unsigned int private_dos:1; + } extcap; }; @@ -124,24 +137,26 @@ get_cached_data (app_t app, int tag, size_t len; struct cache_s *c; - *result = NULL; *resultlen = 0; - if (app->app_local) - { - for (c=app->app_local->cache; c; c = c->next) - if (c->tag == tag) + for (c=app->app_local->cache; c; c = c->next) + if (c->tag == tag) + { + if(c->length) { - p = xtrymalloc (c->length); - if (!p) - return gpg_error (gpg_err_code_from_errno (errno)); - memcpy (p, c->data, c->length); - *resultlen = c->length; - *result = p; - return 0; + p = xtrymalloc (c->length); + if (!p) + return gpg_error (gpg_err_code_from_errno (errno)); + memcpy (p, c->data, c->length); + *result = p; } - } + + *resultlen = c->length; + + return 0; + } + err = iso7816_get_data (app->slot, tag, &p, &len); if (err) @@ -159,24 +174,18 @@ get_cached_data (app_t app, int tag, } /* No, cache it. */ - if (!app->app_local) - app->app_local = xtrycalloc (1, sizeof *app->app_local); - /* Note that we can safely ignore out of core errors. */ - if (app->app_local) + for (c=app->app_local->cache; c; c = c->next) + assert (c->tag != tag); + + c = xtrymalloc (sizeof *c + len); + if (c) { - for (c=app->app_local->cache; c; c = c->next) - assert (c->tag != tag); - - c = xtrymalloc (sizeof *c + len); - if (c) - { - memcpy (c->data, p, len); - c->length = len; - c->tag = tag; - c->next = app->app_local->cache; - app->app_local->cache = c; - } + memcpy (c->data, p, len); + c->length = len; + c->tag = tag; + c->next = app->app_local->cache; + app->app_local->cache = c; } return 0; @@ -202,7 +211,9 @@ flush_cache_item (app_t app, int tag) xfree (c); for (c=app->app_local->cache; c ; c = c->next) - assert (c->tag != tag); /* Oops: duplicated entry. */ + { + assert (c->tag != tag); /* Oops: duplicated entry. */ + } return; } @@ -262,6 +273,15 @@ get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes) for (i=0; data_objects[i].tag && data_objects[i].tag != tag; i++) ; + if (app->card_version > 0x0100 && data_objects[i].get_immediate_in_v11) + { + if( iso7816_get_data (app->slot, tag, &buffer, &buflen)) + return NULL; + *result = buffer; + *nbytes = buflen; + return buffer; + } + value = NULL; rc = -1; if (data_objects[i].tag && data_objects[i].get_from) @@ -428,7 +448,6 @@ store_fpr (int slot, int keynumber, u32 timestamp, *p++ = nbits; memcpy (p, e, elen); p += elen; - log_printhex ("fprbuf:", buffer, n+3); gcry_md_hash_buffer (GCRY_MD_SHA1, fpr, buffer, n+3); xfree (buffer); @@ -436,7 +455,22 @@ store_fpr (int slot, int keynumber, u32 timestamp, rc = iso7816_put_data (slot, (card_version > 0x0007? 0xC7 : 0xC6) + keynumber, fpr, 20); if (rc) - log_error ("failed to store the fingerprint: %s\n",gpg_strerror (rc)); + log_error (_("failed to store the fingerprint: %s\n"),gpg_strerror (rc)); + + if (!rc && card_version > 0x0100) + { + unsigned char buf[4]; + + buf[0] = timestamp >> 24; + buf[1] = timestamp >> 16; + buf[2] = timestamp >> 8; + buf[3] = timestamp; + + rc = iso7816_put_data (slot, 0xCE + keynumber, buf, 4); + if (rc) + log_error (_("failed to store the creation date: %s\n"), + gpg_strerror (rc)); + } return rc; } @@ -502,6 +536,7 @@ do_getattr (APP app, CTRL ctrl, const char *name) { "SIG-COUNTER", 0x0093, 2 }, { "SERIALNO", 0x004F, -1 }, { "AID", 0x004F }, + { "EXTCAP", 0x0000, -2 }, { NULL, 0 } }; int idx, i; @@ -536,6 +571,18 @@ do_getattr (APP app, CTRL ctrl, const char *name) } return 0; } + if (table[idx].special == -2) + { + char tmp[50]; + + sprintf (tmp, "gc=%d ki=%d fc=%d pd=%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); + send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0); + return 0; + } relptr = get_one_do (app, table[idx].tag, &value, &valuelen); if (relptr) @@ -575,6 +622,7 @@ do_getattr (APP app, CTRL ctrl, const char *name) static int do_learn_status (APP app, CTRL ctrl) { + do_getattr (app, ctrl, "EXTCAP"); do_getattr (app, ctrl, "DISP-NAME"); do_getattr (app, ctrl, "DISP-LANG"); do_getattr (app, ctrl, "DISP-SEX"); @@ -605,13 +653,14 @@ verify_chv2 (app_t app, rc = pincb (pincb_arg, "PIN", &pinvalue); if (rc) { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); + log_info (_("PIN callback returned error: %s\n"), gpg_strerror (rc)); return rc; } if (strlen (pinvalue) < 6) { - log_error ("prassphrase (CHV2) is too short; minimum length is 6\n"); + log_error (_("prassphrase (CHV%d) is too short;" + " minimum length is %d\n"), 2, 6); xfree (pinvalue); return gpg_error (GPG_ERR_BAD_PIN); } @@ -619,7 +668,7 @@ verify_chv2 (app_t app, rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue)); if (rc) { - log_error ("verify CHV2 failed: %s\n", gpg_strerror (rc)); + log_error (_("verify CHV%d failed: %s\n"), 2, gpg_strerror (rc)); xfree (pinvalue); flush_cache_after_error (app); return rc; @@ -633,7 +682,7 @@ verify_chv2 (app_t app, rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); if (rc) { - log_error ("verify CHV1 failed: %s\n", gpg_strerror (rc)); + log_error (_("verify CHV%d failed: %s\n"), 1, gpg_strerror (rc)); xfree (pinvalue); flush_cache_after_error (app); return rc; @@ -653,26 +702,54 @@ verify_chv3 (APP app, { int rc = 0; +#if GNUPG_MAJOR_VERSION != 1 if (!opt.allow_admin) { - log_info ("access to admin commands is not configured\n"); + log_info (_("access to admin commands is not configured\n")); return gpg_error (GPG_ERR_EACCES); } +#endif if (!app->did_chv3) { char *pinvalue; + void *relptr; + unsigned char *value; + size_t valuelen; + int reread_chv_status; + - rc = pincb (pincb_arg, "Admin PIN", &pinvalue); + 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); + } + if (value[6] == 0) + { + log_info (_("card is permanently locked!\n")); + xfree (relptr); + return gpg_error (GPG_ERR_BAD_PIN); + } + + reread_chv_status = (value[6] < 3); + + log_info(_("%d Admin PIN attempts remaining before card" + " is permanently locked\n"), value[6]); + xfree (relptr); + + rc = pincb (pincb_arg, _("Admin PIN"), &pinvalue); if (rc) { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); + log_info (_("PIN callback returned error: %s\n"), gpg_strerror (rc)); return rc; } if (strlen (pinvalue) < 6) { - log_error ("prassphrase (CHV3) is too short; minimum length is 6\n"); + log_error (_("prassphrase (CHV%d) is too short;" + " minimum length is %d\n"), 3, 6); xfree (pinvalue); return gpg_error (GPG_ERR_BAD_PIN); } @@ -681,11 +758,18 @@ verify_chv3 (APP app, xfree (pinvalue); if (rc) { - log_error ("verify CHV3 failed: %s\n", gpg_strerror (rc)); + log_error (_("verify CHV%d failed: %s\n"), 3, gpg_strerror (rc)); flush_cache_after_error (app); return rc; } app->did_chv3 = 1; + /* If the PIN has been entered wrongly before, we need to flush + the cached value so that the next read correctly reflects the + resetted retry counter. Note that version 1.1 of the specs + allow direct reading of that DO, so that we could actually + flush it in all cases. */ + if (reread_chv_status) + flush_cache_item (app, 0x00C4); } return rc; } @@ -1149,7 +1233,8 @@ do_sign (APP app, const char *keyidstr, int hashalgo, if (strlen (pinvalue) < 6) { - log_error ("prassphrase (CHV1) is too short; minimum length is 6\n"); + log_error (_("prassphrase (CHV%d) is too short;" + " minimum length is %d\n"), 1, 6); xfree (pinvalue); return gpg_error (GPG_ERR_BAD_PIN); } @@ -1157,7 +1242,7 @@ do_sign (APP app, const char *keyidstr, int hashalgo, rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); if (rc) { - log_error ("verify CHV1 failed\n"); + log_error (_("verify CHV%d failed: %s\n"), 1, gpg_strerror (rc)); xfree (pinvalue); flush_cache_after_error (app); return rc; @@ -1171,7 +1256,7 @@ do_sign (APP app, const char *keyidstr, int hashalgo, rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); if (rc) { - log_error ("verify CHV2 failed\n"); + log_error (_("verify CHV%d failed: %s\n"), 2, gpg_strerror (rc)); xfree (pinvalue); flush_cache_after_error (app); return rc; @@ -1375,11 +1460,14 @@ app_select_openpgp (APP app) rc = iso7816_select_application (slot, aid, sizeof aid); if (!rc) { + unsigned int manufacturer; + app->apptype = "OPENPGP"; app->did_chv1 = 0; app->did_chv2 = 0; app->did_chv3 = 0; + app->app_local = NULL; /* The OpenPGP card returns the serial number as part of the AID; because we prefer to use OpenPGP serial numbers, we @@ -1391,33 +1479,57 @@ app_select_openpgp (APP app) goto leave; if (opt.verbose) { - log_info ("got AID: "); + log_info ("AID: "); log_printhex ("", buffer, buflen); } -#if GNUPG_MAJOR_VERSION != 1 - /* A valid OpenPGP card should never need this but well the test - is cheap. */ - rc = app_munge_serialno (app); - if (rc) - goto leave; -#endif app->card_version = buffer[6] << 8; app->card_version |= buffer[7]; + manufacturer = (buffer[8]<<8 | buffer[9]); + xfree (app->serialno); app->serialno = buffer; app->serialnolen = buflen; buffer = NULL; + app->app_local = xtrycalloc (1, sizeof *app->app_local); + if (!app->app_local) + { + rc = gpg_error (gpg_err_code_from_errno (errno)); + goto leave; + } relptr = get_one_do (app, 0x00C4, &buffer, &buflen); if (!relptr) { - log_error ("can't access CHV Status Bytes - invalid OpenPGP card?\n"); + log_error (_("can't access CHV Status Bytes " + "- invalid OpenPGP card?\n")); goto leave; } app->force_chv1 = (buflen && *buffer == 0); xfree (relptr); - + + relptr = get_one_do (app, 0x00C0, &buffer, &buflen); + if (!relptr) + { + log_error (_("can't access Extended Capability Flags - " + "invalid OpenPGP card?\n")); + goto leave; + } + if (buflen) + { + app->app_local->extcap.get_challenge = !!(*buffer & 0x40); + app->app_local->extcap.key_import = !!(*buffer & 0x20); + app->app_local->extcap.change_force_chv = !!(*buffer & 0x10); + app->app_local->extcap.private_dos = !!(*buffer & 0x08); + } + xfree (relptr); + + /* Some of the first cards accidently don't set the + CHANGE_FORCE_CHV bit but allow it anyway. */ + if (app->card_version <= 0x0100 && manufacturer == 1) + app->app_local->extcap.change_force_chv = 1; + + if (opt.verbose > 1) dump_all_do (slot); @@ -1435,6 +1547,8 @@ app_select_openpgp (APP app) } leave: + if (rc) + do_deinit (app); return rc; } @@ -1467,7 +1581,8 @@ app_openpgp_cardinfo (APP app, rc = app_get_serial_and_stamp (app, serialno, &dummy); if (rc) { - log_error ("error getting serial number: %s\n", gpg_strerror (rc)); + log_error (_("error getting serial number: %s\n"), + gpg_strerror (rc)); return rc; } } @@ -1554,13 +1669,14 @@ app_openpgp_storekey (APP app, int keyno, if (rc) goto leave; + flush_cache (app); rc = iso7816_put_data (app->slot, (app->card_version > 0x0007? 0xE0 : 0xE9) + keyno, template, template_len); if (rc) { - log_error ("failed to store the key: rc=%s\n", gpg_strerror (rc)); + log_error (_("failed to store the key: %s\n"), gpg_strerror (rc)); rc = gpg_error (GPG_ERR_CARD); goto leave; } @@ -1602,14 +1718,14 @@ app_openpgp_readkey (APP app, int keyno, unsigned char **m, size_t *mlen, if (rc) { rc = gpg_error (GPG_ERR_CARD); - log_error ("reading key failed\n"); + log_error (_("reading the key failed\n")); goto leave; } keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen); if (!keydata) { - log_error ("response does not contain the public key data\n"); + log_error (_("response does not contain the public key data\n")); rc = gpg_error (GPG_ERR_CARD); goto leave; } @@ -1617,7 +1733,7 @@ app_openpgp_readkey (APP app, int keyno, unsigned char **m, size_t *mlen, a = find_tlv (keydata, keydatalen, 0x0081, &alen); if (!a) { - log_error ("response does not contain the RSA modulus\n"); + log_error (_("response does not contain the RSA modulus\n")); rc = gpg_error (GPG_ERR_CARD); goto leave; } @@ -1628,7 +1744,7 @@ app_openpgp_readkey (APP app, int keyno, unsigned char **m, size_t *mlen, a = find_tlv (keydata, keydatalen, 0x0082, &alen); if (!a) { - log_error ("response does not contain the RSA public exponent\n"); + log_error (_("response does not contain the RSA public exponent\n")); rc = gpg_error (GPG_ERR_CARD); goto leave; } diff --git a/sm/ChangeLog b/sm/ChangeLog index 2391deb18..28a397182 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,8 @@ +2004-09-30 Werner Koch + + * keylist.c (list_cert_colon): Make sure that the expired flag has + a higher precedence than the invalid flag. + 2004-09-29 Werner Koch * import.c (parse_p12): Write an error status line for bad diff --git a/sm/keylist.c b/sm/keylist.c index 0c8ebd33e..e9985f3ec 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -333,6 +333,9 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, fputs (have_secret? "crs:":"crt:", fp); + + /* Note: We can't use multiple flags, like "ei", because the + validation check does only return one error. */ truststring[0] = 0; truststring[1] = 0; if ((validity & VALIDITY_REVOKED) @@ -340,8 +343,6 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, *truststring = 'r'; else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED) *truststring = 'e'; - else if (valerr) - *truststring = 'i'; else { /* Lets also check whether the certificate under question @@ -354,6 +355,8 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, && !ksba_cert_get_validity (cert, 1, not_after) && *not_after && strcmp (current_time, not_after) > 0 ) *truststring = 'e'; + else if (valerr) + *truststring = 'i'; } /* Is we have no truststring yet (i.e. the certificate might be