* de.po: Updated.

* POTFILES.in: Add more files.

* app-openpgp.c (do_sign): Add the error string to the verify
failed messages.

* keylist.c (list_cert_colon): Make sure that the expired flag has
a higher precedence than the invalid flag.
This commit is contained in:
Werner Koch 2004-09-30 13:24:33 +00:00
parent ce6a094cc0
commit f67c66e56f
7 changed files with 396 additions and 96 deletions

View File

@ -1,3 +1,9 @@
2004-09-30 Werner Koch <wk@g10code.com>
* de.po: Updated.
* POTFILES.in: Add more files.
2004-07-22 Werner Koch <wk@g10code.de> 2004-07-22 Werner Koch <wk@g10code.de>
* de.po: Updated. * de.po: Updated.

View File

@ -15,6 +15,8 @@ jnlib/logging.c
kbx/kbxutil.c kbx/kbxutil.c
scd/scdaemon.c scd/scdaemon.c
scd/sc-investigate.c
scd/app-openpgp.c
sm/base64.c sm/base64.c
sm/call-agent.c sm/call-agent.c

125
po/de.po
View File

@ -10,8 +10,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gnupg2 1.9.10\n" "Project-Id-Version: gnupg2 1.9.10\n"
"Report-Msgid-Bugs-To: translations@gnupg.org\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n"
"POT-Creation-Date: 2004-09-29 18:01+0200\n" "POT-Creation-Date: 2004-09-30 15:22+0200\n"
"PO-Revision-Date: 2004-09-29 18:10+0200\n" "PO-Revision-Date: 2004-09-30 15:23+0200\n"
"Last-Translator: Werner Koch <wk@gnupg.org>\n" "Last-Translator: Werner Koch <wk@gnupg.org>\n"
"Language-Team: de\n" "Language-Team: de\n"
"MIME-Version: 1.0\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" msgstr "erlaube Aufrufern Schlüssel als \"vertrauenswürdig\" zu markieren"
#: agent/gpg-agent.c:195 agent/protect-tool.c:134 scd/scdaemon.c:168 #: 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 <" msgid "Please report bugs to <"
msgstr "Fehlerberichte bitte an <" msgstr "Fehlerberichte bitte an <"
#: agent/gpg-agent.c:195 agent/protect-tool.c:134 scd/scdaemon.c:168 #: 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" msgid ">.\n"
msgstr ">.\n" msgstr ">.\n"
@ -127,7 +127,7 @@ msgid "invalid debug-level `%s' given\n"
msgstr "ungültige Debugebene `%s' angegeben\n" msgstr "ungültige Debugebene `%s' angegeben\n"
#: agent/gpg-agent.c:446 agent/protect-tool.c:1050 kbx/kbxutil.c:436 #: 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 #, c-format
msgid "libgcrypt is too old (need %s, have %s)\n" msgid "libgcrypt is too old (need %s, have %s)\n"
msgstr "" msgstr ""
@ -432,6 +432,103 @@ msgstr ""
"Bitte die Option `--daemon' nutzen um das Programm im Hintergund " "Bitte die Option `--daemon' nutzen um das Programm im Hintergund "
"auszuführen\n" "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 #: sm/base64.c:315
#, c-format #, c-format
msgid "invalid radix64 character %02x skipped\n" msgid "invalid radix64 character %02x skipped\n"
@ -488,7 +585,7 @@ msgstr "[Fehler - Ung
msgid "[Error - invalid DN]" msgid "[Error - invalid DN]"
msgstr "[Fehler - Ungültiger DN]" msgstr "[Fehler - Ungültiger DN]"
#: sm/certdump.c:652 #: sm/certdump.c:655
#, c-format #, c-format
msgid "" msgid ""
"Please enter the passphrase to unlock the secret key for:\n" "Please enter the passphrase to unlock the secret key for:\n"
@ -496,7 +593,7 @@ msgid ""
"S/N %s, ID %08lX, created %s" "S/N %s, ID %08lX, created %s"
msgstr "" msgstr ""
"Bitte geben Sie die Passphrase an, um den \n" "Bitte geben Sie die Passphrase an, um den \n"
"geheimen Schlüssels von\n" "geheimen Schlüssel von\n"
"\"%s\"\n" "\"%s\"\n"
"S/N %s, ID %08lX, erzeugt %s\n" "S/N %s, ID %08lX, erzeugt %s\n"
"zu entsperren" "zu entsperren"
@ -999,32 +1096,32 @@ msgstr "Verschl
msgid "libksba is too old (need %s, have %s)\n" msgid "libksba is too old (need %s, have %s)\n"
msgstr "Die Bibliothek Libksba is nicht aktuell (benötige %s, habe %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" msgid "WARNING: program may create a core file!\n"
msgstr "WARNUNG: Programm könnte eine core-dump-Datei schreiben!\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: " msgid "WARNING: running with faked system time: "
msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: " msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: "
#: sm/gpgsm.c:1220 #: sm/gpgsm.c:1221
msgid "selected cipher algorithm is invalid\n" msgid "selected cipher algorithm is invalid\n"
msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\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" msgid "selected digest algorithm is invalid\n"
msgstr "Das ausgewählte Hashverfahren ist ungültig\n" msgstr "Das ausgewählte Hashverfahren ist ungültig\n"
#: sm/gpgsm.c:1258 #: sm/gpgsm.c:1259
#, c-format #, c-format
msgid "can't sign using `%s': %s\n" msgid "can't sign using `%s': %s\n"
msgstr "Signieren mit `%s' nicht möglich: %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" msgid "this command has not yet been implemented\n"
msgstr "Diee Kommando wurde noch nicht implementiert\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 #, c-format
msgid "can't open `%s': %s\n" msgid "can't open `%s': %s\n"
msgstr "Datei `%s' kann nicht geöffnet werden: %s\n" msgstr "Datei `%s' kann nicht geöffnet werden: %s\n"

View File

@ -1,3 +1,74 @@
2004-09-30 Werner Koch <wk@g10code.com>
* app-openpgp.c (do_sign): Add the error string to the verify
failed messages.
2004-09-27 Werner Koch <wk@g10code.com>
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 <dshaw@jabberwocky.com>
* 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 <wk@g10code.com> 2004-09-11 Werner Koch <wk@g10code.com>
* app-openpgp.c (app_select_openpgp): Its app_munge_serialno and * app-openpgp.c (app_select_openpgp): Its app_munge_serialno and

View File

@ -34,12 +34,12 @@
#include "errors.h" #include "errors.h"
#include "memory.h" #include "memory.h"
#include "util.h" #include "util.h"
#include "i18n.h"
#include "cardglue.h" #include "cardglue.h"
#else /* GNUPG_MAJOR_VERSION != 1 */ #else /* GNUPG_MAJOR_VERSION != 1 */
#include "scdaemon.h" #include "scdaemon.h"
#endif /* GNUPG_MAJOR_VERSION != 1 */ #endif /* GNUPG_MAJOR_VERSION != 1 */
#include "i18n.h"
#include "iso7816.h" #include "iso7816.h"
#include "app-common.h" #include "app-common.h"
#include "tlv.h" #include "tlv.h"
@ -52,27 +52,33 @@ static struct {
int binary; int binary;
int dont_cache; int dont_cache;
int flush_on_error; 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; char *desc;
} data_objects[] = { } data_objects[] = {
{ 0x005E, 0, 0, 1, 0, 0, "Login Data" }, { 0x005E, 0, 0, 1, 0, 0, 0, "Login Data" },
{ 0x5F50, 0, 0, 0, 0, 0, "URL" }, { 0x5F50, 0, 0, 0, 0, 0, 0, "URL" },
{ 0x0065, 1, 0, 1, 0, 0, "Cardholder Related Data"}, { 0x0065, 1, 0, 1, 0, 0, 0, "Cardholder Related Data"},
{ 0x005B, 0, 0x65, 0, 0, 0, "Name" }, { 0x005B, 0, 0x65, 0, 0, 0, 0, "Name" },
{ 0x5F2D, 0, 0x65, 0, 0, 0, "Language preferences" }, { 0x5F2D, 0, 0x65, 0, 0, 0, 0, "Language preferences" },
{ 0x5F35, 0, 0x65, 0, 0, 0, "Sex" }, { 0x5F35, 0, 0x65, 0, 0, 0, 0, "Sex" },
{ 0x006E, 1, 0, 1, 0, 0, "Application Related Data" }, { 0x006E, 1, 0, 1, 0, 0, 0, "Application Related Data" },
{ 0x004F, 0, 0x6E, 1, 0, 0, "AID" }, { 0x004F, 0, 0x6E, 1, 0, 0, 0, "AID" },
{ 0x0073, 1, 0, 1, 0, 0, "Discretionary Data Objects" }, { 0x0073, 1, 0, 1, 0, 0, 0, "Discretionary Data Objects" },
{ 0x0047, 0, 0x6E, 1, 0, 0, "Card Capabilities" }, { 0x0047, 0, 0x6E, 1, 1, 0, 0, "Card Capabilities" },
{ 0x00C0, 0, 0x6E, 1, 0, 0, "Extended Card Capabilities" }, { 0x00C0, 0, 0x6E, 1, 1, 0, 0, "Extended Card Capabilities" },
{ 0x00C1, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Signature" }, { 0x00C1, 0, 0x6E, 1, 1, 0, 0, "Algorithm Attributes Signature" },
{ 0x00C2, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Decryption" }, { 0x00C2, 0, 0x6E, 1, 1, 0, 0, "Algorithm Attributes Decryption" },
{ 0x00C3, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Authentication" }, { 0x00C3, 0, 0x6E, 1, 1, 0, 0, "Algorithm Attributes Authentication" },
{ 0x00C4, 0, 0x6E, 1, 0, 1, "CHV Status Bytes" }, { 0x00C4, 0, 0x6E, 1, 0, 1, 1, "CHV Status Bytes" },
{ 0x00C5, 0, 0x6E, 1, 0, 0, "Fingerprints" }, { 0x00C5, 0, 0x6E, 1, 0, 0, 0, "Fingerprints" },
{ 0x00C6, 0, 0x6E, 1, 0, 0, "CA Fingerprints" }, { 0x00C6, 0, 0x6E, 1, 0, 0, 0, "CA Fingerprints" },
{ 0x007A, 1, 0, 1, 0, 0, "Security Support Template" }, { 0x007A, 1, 0, 1, 0, 0, 0, "Security Support Template" },
{ 0x0093, 0, 0x7A, 1, 1, 0, "Digital Signature Counter" }, { 0x0093, 0, 0x7A, 1, 1, 0, 0, "Digital Signature Counter" },
{ 0 } { 0 }
}; };
@ -86,6 +92,13 @@ struct cache_s {
struct app_local_s { struct app_local_s {
struct cache_s *cache; 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; size_t len;
struct cache_s *c; struct cache_s *c;
*result = NULL; *result = NULL;
*resultlen = 0; *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); p = xtrymalloc (c->length);
if (!p) if (!p)
return gpg_error (gpg_err_code_from_errno (errno)); return gpg_error (gpg_err_code_from_errno (errno));
memcpy (p, c->data, c->length); memcpy (p, c->data, c->length);
*resultlen = c->length; *result = p;
*result = p;
return 0;
} }
}
*resultlen = c->length;
return 0;
}
err = iso7816_get_data (app->slot, tag, &p, &len); err = iso7816_get_data (app->slot, tag, &p, &len);
if (err) if (err)
@ -159,24 +174,18 @@ get_cached_data (app_t app, int tag,
} }
/* No, cache it. */ /* 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. */ for (c=app->app_local->cache; c; c = c->next)
if (app->app_local) assert (c->tag != tag);
c = xtrymalloc (sizeof *c + len);
if (c)
{ {
for (c=app->app_local->cache; c; c = c->next) memcpy (c->data, p, len);
assert (c->tag != tag); c->length = len;
c->tag = tag;
c = xtrymalloc (sizeof *c + len); c->next = app->app_local->cache;
if (c) 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; return 0;
@ -202,7 +211,9 @@ flush_cache_item (app_t app, int tag)
xfree (c); xfree (c);
for (c=app->app_local->cache; c ; c = c->next) 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; 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++) 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; value = NULL;
rc = -1; rc = -1;
if (data_objects[i].tag && data_objects[i].get_from) if (data_objects[i].tag && data_objects[i].get_from)
@ -428,7 +448,6 @@ store_fpr (int slot, int keynumber, u32 timestamp,
*p++ = nbits; *p++ = nbits;
memcpy (p, e, elen); p += elen; memcpy (p, e, elen); p += elen;
log_printhex ("fprbuf:", buffer, n+3);
gcry_md_hash_buffer (GCRY_MD_SHA1, fpr, buffer, n+3); gcry_md_hash_buffer (GCRY_MD_SHA1, fpr, buffer, n+3);
xfree (buffer); xfree (buffer);
@ -436,7 +455,22 @@ store_fpr (int slot, int keynumber, u32 timestamp,
rc = iso7816_put_data (slot, (card_version > 0x0007? 0xC7 : 0xC6) rc = iso7816_put_data (slot, (card_version > 0x0007? 0xC7 : 0xC6)
+ keynumber, fpr, 20); + keynumber, fpr, 20);
if (rc) 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; return rc;
} }
@ -502,6 +536,7 @@ do_getattr (APP app, CTRL ctrl, const char *name)
{ "SIG-COUNTER", 0x0093, 2 }, { "SIG-COUNTER", 0x0093, 2 },
{ "SERIALNO", 0x004F, -1 }, { "SERIALNO", 0x004F, -1 },
{ "AID", 0x004F }, { "AID", 0x004F },
{ "EXTCAP", 0x0000, -2 },
{ NULL, 0 } { NULL, 0 }
}; };
int idx, i; int idx, i;
@ -536,6 +571,18 @@ do_getattr (APP app, CTRL ctrl, const char *name)
} }
return 0; 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); relptr = get_one_do (app, table[idx].tag, &value, &valuelen);
if (relptr) if (relptr)
@ -575,6 +622,7 @@ do_getattr (APP app, CTRL ctrl, const char *name)
static int static int
do_learn_status (APP app, CTRL ctrl) do_learn_status (APP app, CTRL ctrl)
{ {
do_getattr (app, ctrl, "EXTCAP");
do_getattr (app, ctrl, "DISP-NAME"); do_getattr (app, ctrl, "DISP-NAME");
do_getattr (app, ctrl, "DISP-LANG"); do_getattr (app, ctrl, "DISP-LANG");
do_getattr (app, ctrl, "DISP-SEX"); do_getattr (app, ctrl, "DISP-SEX");
@ -605,13 +653,14 @@ verify_chv2 (app_t app,
rc = pincb (pincb_arg, "PIN", &pinvalue); rc = pincb (pincb_arg, "PIN", &pinvalue);
if (rc) 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; return rc;
} }
if (strlen (pinvalue) < 6) 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); xfree (pinvalue);
return gpg_error (GPG_ERR_BAD_PIN); 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)); rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
if (rc) 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); xfree (pinvalue);
flush_cache_after_error (app); flush_cache_after_error (app);
return rc; return rc;
@ -633,7 +682,7 @@ verify_chv2 (app_t app,
rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED);
if (rc) 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); xfree (pinvalue);
flush_cache_after_error (app); flush_cache_after_error (app);
return rc; return rc;
@ -653,26 +702,54 @@ verify_chv3 (APP app,
{ {
int rc = 0; int rc = 0;
#if GNUPG_MAJOR_VERSION != 1
if (!opt.allow_admin) 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); return gpg_error (GPG_ERR_EACCES);
} }
#endif
if (!app->did_chv3) if (!app->did_chv3)
{ {
char *pinvalue; 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) 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; return rc;
} }
if (strlen (pinvalue) < 6) 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); xfree (pinvalue);
return gpg_error (GPG_ERR_BAD_PIN); return gpg_error (GPG_ERR_BAD_PIN);
} }
@ -681,11 +758,18 @@ verify_chv3 (APP app,
xfree (pinvalue); xfree (pinvalue);
if (rc) 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); flush_cache_after_error (app);
return rc; return rc;
} }
app->did_chv3 = 1; 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; return rc;
} }
@ -1149,7 +1233,8 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
if (strlen (pinvalue) < 6) 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); xfree (pinvalue);
return gpg_error (GPG_ERR_BAD_PIN); 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)); rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
if (rc) if (rc)
{ {
log_error ("verify CHV1 failed\n"); log_error (_("verify CHV%d failed: %s\n"), 1, gpg_strerror (rc));
xfree (pinvalue); xfree (pinvalue);
flush_cache_after_error (app); flush_cache_after_error (app);
return rc; return rc;
@ -1171,7 +1256,7 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED);
if (rc) if (rc)
{ {
log_error ("verify CHV2 failed\n"); log_error (_("verify CHV%d failed: %s\n"), 2, gpg_strerror (rc));
xfree (pinvalue); xfree (pinvalue);
flush_cache_after_error (app); flush_cache_after_error (app);
return rc; return rc;
@ -1375,11 +1460,14 @@ app_select_openpgp (APP app)
rc = iso7816_select_application (slot, aid, sizeof aid); rc = iso7816_select_application (slot, aid, sizeof aid);
if (!rc) if (!rc)
{ {
unsigned int manufacturer;
app->apptype = "OPENPGP"; app->apptype = "OPENPGP";
app->did_chv1 = 0; app->did_chv1 = 0;
app->did_chv2 = 0; app->did_chv2 = 0;
app->did_chv3 = 0; app->did_chv3 = 0;
app->app_local = NULL;
/* The OpenPGP card returns the serial number as part of the /* The OpenPGP card returns the serial number as part of the
AID; because we prefer to use OpenPGP serial numbers, we AID; because we prefer to use OpenPGP serial numbers, we
@ -1391,33 +1479,57 @@ app_select_openpgp (APP app)
goto leave; goto leave;
if (opt.verbose) if (opt.verbose)
{ {
log_info ("got AID: "); log_info ("AID: ");
log_printhex ("", buffer, buflen); 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[6] << 8;
app->card_version |= buffer[7]; app->card_version |= buffer[7];
manufacturer = (buffer[8]<<8 | buffer[9]);
xfree (app->serialno); xfree (app->serialno);
app->serialno = buffer; app->serialno = buffer;
app->serialnolen = buflen; app->serialnolen = buflen;
buffer = NULL; 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); relptr = get_one_do (app, 0x00C4, &buffer, &buflen);
if (!relptr) 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; goto leave;
} }
app->force_chv1 = (buflen && *buffer == 0); app->force_chv1 = (buflen && *buffer == 0);
xfree (relptr); 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) if (opt.verbose > 1)
dump_all_do (slot); dump_all_do (slot);
@ -1435,6 +1547,8 @@ app_select_openpgp (APP app)
} }
leave: leave:
if (rc)
do_deinit (app);
return rc; return rc;
} }
@ -1467,7 +1581,8 @@ app_openpgp_cardinfo (APP app,
rc = app_get_serial_and_stamp (app, serialno, &dummy); rc = app_get_serial_and_stamp (app, serialno, &dummy);
if (rc) 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; return rc;
} }
} }
@ -1554,13 +1669,14 @@ app_openpgp_storekey (APP app, int keyno,
if (rc) if (rc)
goto leave; goto leave;
flush_cache (app);
rc = iso7816_put_data (app->slot, rc = iso7816_put_data (app->slot,
(app->card_version > 0x0007? 0xE0 : 0xE9) + keyno, (app->card_version > 0x0007? 0xE0 : 0xE9) + keyno,
template, template_len); template, template_len);
if (rc) 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); rc = gpg_error (GPG_ERR_CARD);
goto leave; goto leave;
} }
@ -1602,14 +1718,14 @@ app_openpgp_readkey (APP app, int keyno, unsigned char **m, size_t *mlen,
if (rc) if (rc)
{ {
rc = gpg_error (GPG_ERR_CARD); rc = gpg_error (GPG_ERR_CARD);
log_error ("reading key failed\n"); log_error (_("reading the key failed\n"));
goto leave; goto leave;
} }
keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen); keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen);
if (!keydata) 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); rc = gpg_error (GPG_ERR_CARD);
goto leave; 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); a = find_tlv (keydata, keydatalen, 0x0081, &alen);
if (!a) 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); rc = gpg_error (GPG_ERR_CARD);
goto leave; 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); a = find_tlv (keydata, keydatalen, 0x0082, &alen);
if (!a) 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); rc = gpg_error (GPG_ERR_CARD);
goto leave; goto leave;
} }

View File

@ -1,3 +1,8 @@
2004-09-30 Werner Koch <wk@g10code.com>
* keylist.c (list_cert_colon): Make sure that the expired flag has
a higher precedence than the invalid flag.
2004-09-29 Werner Koch <wk@g10code.com> 2004-09-29 Werner Koch <wk@g10code.com>
* import.c (parse_p12): Write an error status line for bad * import.c (parse_p12): Write an error status line for bad

View File

@ -333,6 +333,9 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
fputs (have_secret? "crs:":"crt:", fp); 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[0] = 0;
truststring[1] = 0; truststring[1] = 0;
if ((validity & VALIDITY_REVOKED) if ((validity & VALIDITY_REVOKED)
@ -340,8 +343,6 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
*truststring = 'r'; *truststring = 'r';
else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED) else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
*truststring = 'e'; *truststring = 'e';
else if (valerr)
*truststring = 'i';
else else
{ {
/* Lets also check whether the certificate under question /* 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) && !ksba_cert_get_validity (cert, 1, not_after)
&& *not_after && strcmp (current_time, not_after) > 0 ) && *not_after && strcmp (current_time, not_after) > 0 )
*truststring = 'e'; *truststring = 'e';
else if (valerr)
*truststring = 'i';
} }
/* Is we have no truststring yet (i.e. the certificate might be /* Is we have no truststring yet (i.e. the certificate might be