aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/ChangeLog7
-rw-r--r--g10/app-openpgp.c79
-rw-r--r--g10/card-util.c60
3 files changed, 93 insertions, 53 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index f3b1e79b6..e51bb46a9 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,10 +1,15 @@
2004-09-27 Werner Koch <[email protected]>
+ * card-util.c (card_edit): Take admin only status from the table.
+
* 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.
+ 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.
2004-09-25 David Shaw <[email protected]>
diff --git a/g10/app-openpgp.c b/g10/app-openpgp.c
index cec1353d4..94a62695b 100644
--- a/g10/app-openpgp.c
+++ b/g10/app-openpgp.c
@@ -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, 1, 0, "Card Capabilities" },
- { 0x00C0, 0, 0x6E, 1, 1, 0, "Extended Card Capabilities" },
- { 0x00C1, 0, 0x6E, 1, 1, 0, "Algorithm Attributes Signature" },
- { 0x00C2, 0, 0x6E, 1, 1, 0, "Algorithm Attributes Decryption" },
- { 0x00C3, 0, 0x6E, 1, 1, 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 }
};
@@ -267,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)
@@ -442,6 +457,21 @@ store_fpr (int slot, int keynumber, u32 timestamp,
if (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;
}
@@ -686,6 +716,8 @@ verify_chv3 (APP app,
void *relptr;
unsigned char *value;
size_t valuelen;
+ int reread_chv_status;
+
relptr = get_one_do (app, 0x00C4, &value, &valuelen);
if (!relptr || valuelen < 7)
@@ -701,6 +733,8 @@ verify_chv3 (APP app,
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);
@@ -729,6 +763,13 @@ verify_chv3 (APP 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;
}
diff --git a/g10/card-util.c b/g10/card-util.c
index a58dda097..0ded216e2 100644
--- a/g10/card-util.c
+++ b/g10/card-util.c
@@ -1166,6 +1166,7 @@ card_edit (STRLIST commands)
const char *arg_string = "";
char *p;
int i;
+ int cmd_admin_only;
tty_printf("\n");
if (redisplay )
@@ -1208,46 +1209,39 @@ card_edit (STRLIST commands)
}
trim_spaces(answer);
}
- while( *answer == '#' );
+ while ( *answer == '#' );
arg_number = 0; /* Yes, here is the init which egcc complains about */
+ cmd_admin_only = 0;
if (!*answer)
cmd = cmdLIST; /* Default to the list command */
else if (*answer == CONTROL_D)
cmd = cmdQUIT;
- else {
- if ((p=strchr (answer,' ')))
- {
- *p++ = 0;
- trim_spaces (answer);
- trim_spaces (p);
- arg_number = atoi(p);
- arg_string = p;
- }
-
- for (i=0; cmds[i].name; i++ )
- if (!ascii_strcasecmp (answer, cmds[i].name ))
- break;
-
- cmd = cmds[i].id;
- }
+ else
+ {
+ if ((p=strchr (answer,' ')))
+ {
+ *p++ = 0;
+ trim_spaces (answer);
+ trim_spaces (p);
+ arg_number = atoi(p);
+ arg_string = p;
+ }
+
+ for (i=0; cmds[i].name; i++ )
+ if (!ascii_strcasecmp (answer, cmds[i].name ))
+ break;
- if(!allow_admin)
- switch(cmd)
- {
- case cmdNAME:
- case cmdURL:
- case cmdLOGIN:
- case cmdLANG:
- case cmdCAFPR:
- case cmdFORCESIG:
- case cmdGENERATE:
- tty_printf ("\n");
- tty_printf (_("Admin-only command\n"));
- continue;
- default:
- break;
- }
+ cmd = cmds[i].id;
+ cmd_admin_only = cmds[i].admin_only;
+ }
+
+ if (!allow_admin && cmd_admin_only)
+ {
+ tty_printf ("\n");
+ tty_printf (_("Admin-only command\n"));
+ continue;
+ }
switch (cmd)
{