gpg: Prepare for longer card fingerprints.

* g10/call-agent.h (agent_card_info_s): Rename the "*valid" fields to
"*len".
* g10/call-agent.c (unhexify_fpr): Change to take a FPRLEN and to
return the actual length.
(agent_release_card_info): Adjust for these changes.
* g10/card-util.c (print_sha1_fpr): Rename to print_shax_fpr and add
arg FPRLEN.  Change all callers to pass the length.
(print_sha1_fpr_colon): Rename to print_shax_fpr_colon and add arg
FPRLEN.  Change all callers to pass the length.
(fpr_is_zero): Add arg FPRLEN.
(fpr_is_ff): Ditto.
(show_card_key_info): Use the new functions.
* g10/skclist.c (enum_secret_keys): Use MAX_FINGERPRINT_LEN.
--

This is not needed right now but we should get rid of all hard coded
fingerprint lengths.  Thus this change.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2018-08-27 16:57:04 +02:00
parent b823788d20
commit 108702ccae
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
4 changed files with 89 additions and 76 deletions

View File

@ -388,22 +388,23 @@ unescape_status_string (const unsigned char *s)
} }
/* Take a 20 byte hexencoded string and put it into the provided /* Take a 20 or 32 byte hexencoded string and put it into the provided
20 byte buffer FPR in binary format. */ * FPRLEN byte long buffer FPR in binary format. Returns the actual
static int * used length of the FPR buffer or 0 on error. */
unhexify_fpr (const char *hexstr, unsigned char *fpr) static unsigned int
unhexify_fpr (const char *hexstr, unsigned char *fpr, unsigned int fprlen)
{ {
const char *s; const char *s;
int n; int n;
for (s=hexstr, n=0; hexdigitp (s); s++, n++) for (s=hexstr, n=0; hexdigitp (s); s++, n++)
; ;
if ((*s && *s != ' ') || (n != 40)) if ((*s && *s != ' ') || !(n == 40 || n == 64))
return 0; /* no fingerprint (invalid or wrong length). */ return 0; /* no fingerprint (invalid or wrong length). */
for (s=hexstr, n=0; *s && n < 20; s += 2, n++) for (s=hexstr, n=0; *s && n < fprlen; s += 2, n++)
fpr[n] = xtoi_2 (s); fpr[n] = xtoi_2 (s);
return 1; /* okay */ return (n == 20 || n == 32)? n : 0;
} }
/* Take the serial number from LINE and return it verbatim in a newly /* Take the serial number from LINE and return it verbatim in a newly
@ -488,8 +489,8 @@ agent_release_card_info (struct agent_card_info_s *info)
xfree (info->disp_lang); info->disp_lang = NULL; xfree (info->disp_lang); info->disp_lang = NULL;
xfree (info->pubkey_url); info->pubkey_url = NULL; xfree (info->pubkey_url); info->pubkey_url = NULL;
xfree (info->login_data); info->login_data = NULL; xfree (info->login_data); info->login_data = NULL;
info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0; info->cafpr1len = info->cafpr2len = info->cafpr3len = 0;
info->fpr1valid = info->fpr2valid = info->fpr3valid = 0; info->fpr1len = info->fpr2len = info->fpr3len = 0;
for (i=0; i < DIM(info->private_do); i++) for (i=0; i < DIM(info->private_do); i++)
{ {
xfree (info->private_do[i]); xfree (info->private_do[i]);
@ -625,11 +626,11 @@ learn_status_cb (void *opaque, const char *line)
while (spacep (line)) while (spacep (line))
line++; line++;
if (no == 1) if (no == 1)
parm->fpr1valid = unhexify_fpr (line, parm->fpr1); parm->fpr1len = unhexify_fpr (line, parm->fpr1, sizeof parm->fpr1);
else if (no == 2) else if (no == 2)
parm->fpr2valid = unhexify_fpr (line, parm->fpr2); parm->fpr2len = unhexify_fpr (line, parm->fpr2, sizeof parm->fpr2);
else if (no == 3) else if (no == 3)
parm->fpr3valid = unhexify_fpr (line, parm->fpr3); parm->fpr3len = unhexify_fpr (line, parm->fpr3, sizeof parm->fpr3);
} }
else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen)) else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen))
{ {
@ -657,11 +658,11 @@ learn_status_cb (void *opaque, const char *line)
if (strncmp (line, "OPENPGP.", 8)) if (strncmp (line, "OPENPGP.", 8))
; ;
else if ((no = atoi (line+8)) == 1) else if ((no = atoi (line+8)) == 1)
unhexify_fpr (hexgrp, parm->grp1); unhexify_fpr (hexgrp, parm->grp1, sizeof parm->grp1);
else if (no == 2) else if (no == 2)
unhexify_fpr (hexgrp, parm->grp2); unhexify_fpr (hexgrp, parm->grp2, sizeof parm->grp2);
else if (no == 3) else if (no == 3)
unhexify_fpr (hexgrp, parm->grp3); unhexify_fpr (hexgrp, parm->grp3, sizeof parm->grp3);
} }
else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen)) else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
{ {
@ -671,11 +672,11 @@ learn_status_cb (void *opaque, const char *line)
while (spacep (line)) while (spacep (line))
line++; line++;
if (no == 1) if (no == 1)
parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1); parm->cafpr1len = unhexify_fpr (line, parm->cafpr1,sizeof parm->cafpr1);
else if (no == 2) else if (no == 2)
parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2); parm->cafpr2len = unhexify_fpr (line, parm->cafpr2,sizeof parm->cafpr2);
else if (no == 3) else if (no == 3)
parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3); parm->cafpr3len = unhexify_fpr (line, parm->cafpr3,sizeof parm->cafpr3);
} }
else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen)) else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen))
{ {
@ -823,6 +824,8 @@ agent_keytocard (const char *hexgrip, int keyno, int force,
return rc; return rc;
} }
/* Call the agent to retrieve a data object. This function returns /* Call the agent to retrieve a data object. This function returns
the data in the same structure as used by the learn command. It is the data in the same structure as used by the learn command. It is

View File

@ -39,15 +39,15 @@ struct agent_card_info_s
char *pubkey_url; /* malloced. */ char *pubkey_url; /* malloced. */
char *login_data; /* malloced. */ char *login_data; /* malloced. */
char *private_do[4]; /* malloced. */ char *private_do[4]; /* malloced. */
char cafpr1valid; char cafpr1len; /* Length of the CA-fingerprint or 0 if invalid. */
char cafpr2valid; char cafpr2len;
char cafpr3valid; char cafpr3len;
char cafpr1[20]; char cafpr1[20];
char cafpr2[20]; char cafpr2[20];
char cafpr3[20]; char cafpr3[20];
char fpr1valid; unsigned char fpr1len; /* Length of the fingerprint or 0 if invalid. */
char fpr2valid; unsigned char fpr2len;
char fpr3valid; unsigned char fpr3len;
char fpr1[20]; char fpr1[20];
char fpr2[20]; char fpr2[20];
char fpr3[20]; char fpr3[20];

View File

@ -231,13 +231,14 @@ get_manufacturer (unsigned int no)
static void static void
print_sha1_fpr (estream_t fp, const unsigned char *fpr) print_shax_fpr (estream_t fp, const unsigned char *fpr, unsigned int fprlen)
{ {
int i; int i;
if (fpr) if (fpr)
{ {
for (i=0; i < 20 ; i+=2, fpr += 2 ) /* FIXME: Fix formatting for FPRLEN != 20 */
for (i=0; i < fprlen ; i+=2, fpr += 2 )
{ {
if (i == 10 ) if (i == 10 )
tty_fprintf (fp, " "); tty_fprintf (fp, " ");
@ -251,13 +252,14 @@ print_sha1_fpr (estream_t fp, const unsigned char *fpr)
static void static void
print_sha1_fpr_colon (estream_t fp, const unsigned char *fpr) print_shax_fpr_colon (estream_t fp,
const unsigned char *fpr, unsigned int fprlen)
{ {
int i; int i;
if (fpr) if (fpr)
{ {
for (i=0; i < 20 ; i++, fpr++) for (i=0; i < fprlen ; i++, fpr++)
es_fprintf (fp, "%02X", *fpr); es_fprintf (fp, "%02X", *fpr);
} }
es_putc (':', fp); es_putc (':', fp);
@ -356,25 +358,25 @@ print_isoname (estream_t fp, const char *text,
/* Return true if the SHA1 fingerprint FPR consists only of zeroes. */ /* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
static int static int
fpr_is_zero (const char *fpr) fpr_is_zero (const char *fpr, unsigned int fprlen)
{ {
int i; int i;
for (i=0; i < 20 && !fpr[i]; i++) for (i=0; i < fprlen && !fpr[i]; i++)
; ;
return (i == 20); return (i == fprlen);
} }
/* Return true if the SHA1 fingerprint FPR consists only of 0xFF. */ /* Return true if the fingerprint FPR consists only of 0xFF. */
static int static int
fpr_is_ff (const char *fpr) fpr_is_ff (const char *fpr, unsigned int fprlen)
{ {
int i; int i;
for (i=0; i < 20 && fpr[i] == '\xff'; i++) for (i=0; i < fprlen && fpr[i] == '\xff'; i++)
; ;
return (i == 20); return (i == fprlen);
} }
@ -389,6 +391,7 @@ current_card_status (ctrl_t ctrl, estream_t fp,
int rc; int rc;
unsigned int uval; unsigned int uval;
const unsigned char *thefpr; const unsigned char *thefpr;
unsigned int thefprlen;
int i; int i;
if (serialno && serialnobuflen) if (serialno && serialnobuflen)
@ -521,22 +524,25 @@ current_card_status (ctrl_t ctrl, estream_t fp,
} }
es_fputs ("cafpr:", fp); es_fputs ("cafpr:", fp);
print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL); print_shax_fpr_colon (fp, info.cafpr1len? info.cafpr1:NULL,
print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL); info.cafpr2len);
print_sha1_fpr_colon (fp, info.cafpr3valid? info.cafpr3:NULL); print_shax_fpr_colon (fp, info.cafpr2len? info.cafpr2:NULL,
info.cafpr2len);
print_shax_fpr_colon (fp, info.cafpr3len? info.cafpr3:NULL,
info.cafpr3len);
es_putc ('\n', fp); es_putc ('\n', fp);
es_fputs ("fpr:", fp); es_fputs ("fpr:", fp);
print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL); print_shax_fpr_colon (fp, info.fpr1len? info.fpr1:NULL, info.fpr1len);
print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL); print_shax_fpr_colon (fp, info.fpr2len? info.fpr2:NULL, info.fpr2len);
print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL); print_shax_fpr_colon (fp, info.fpr3len? info.fpr3:NULL, info.fpr3len);
es_putc ('\n', fp); es_putc ('\n', fp);
es_fprintf (fp, "fprtime:%lu:%lu:%lu:\n", es_fprintf (fp, "fprtime:%lu:%lu:%lu:\n",
(unsigned long)info.fpr1time, (unsigned long)info.fpr2time, (unsigned long)info.fpr1time, (unsigned long)info.fpr2time,
(unsigned long)info.fpr3time); (unsigned long)info.fpr3time);
es_fputs ("grp:", fp); es_fputs ("grp:", fp);
print_sha1_fpr_colon (fp, info.grp1); print_shax_fpr_colon (fp, info.grp1, sizeof info.grp1);
print_sha1_fpr_colon (fp, info.grp2); print_shax_fpr_colon (fp, info.grp2, sizeof info.grp2);
print_sha1_fpr_colon (fp, info.grp3); print_shax_fpr_colon (fp, info.grp3, sizeof info.grp3);
es_putc ('\n', fp); es_putc ('\n', fp);
} }
else else
@ -566,20 +572,20 @@ current_card_status (ctrl_t ctrl, estream_t fp,
print_name (fp, "Private DO 3 .....: ", info.private_do[2]); print_name (fp, "Private DO 3 .....: ", info.private_do[2]);
if (info.private_do[3]) if (info.private_do[3])
print_name (fp, "Private DO 4 .....: ", info.private_do[3]); print_name (fp, "Private DO 4 .....: ", info.private_do[3]);
if (info.cafpr1valid) if (info.cafpr1len)
{ {
tty_fprintf (fp, "CA fingerprint %d .:", 1); tty_fprintf (fp, "CA fingerprint %d .:", 1);
print_sha1_fpr (fp, info.cafpr1); print_shax_fpr (fp, info.cafpr1, info.cafpr1len);
} }
if (info.cafpr2valid) if (info.cafpr2len)
{ {
tty_fprintf (fp, "CA fingerprint %d .:", 2); tty_fprintf (fp, "CA fingerprint %d .:", 2);
print_sha1_fpr (fp, info.cafpr2); print_shax_fpr (fp, info.cafpr2, info.cafpr2len);
} }
if (info.cafpr3valid) if (info.cafpr3len)
{ {
tty_fprintf (fp, "CA fingerprint %d .:", 3); tty_fprintf (fp, "CA fingerprint %d .:", 3);
print_sha1_fpr (fp, info.cafpr3); print_shax_fpr (fp, info.cafpr3, info.cafpr3len);
} }
tty_fprintf (fp, "Signature PIN ....: %s\n", tty_fprintf (fp, "Signature PIN ....: %s\n",
info.chv1_cached? _("not forced"): _("forced")); info.chv1_cached? _("not forced"): _("forced"));
@ -612,24 +618,24 @@ current_card_status (ctrl_t ctrl, estream_t fp,
info.chvretry[0], info.chvretry[1], info.chvretry[2]); info.chvretry[0], info.chvretry[1], info.chvretry[2]);
tty_fprintf (fp, "Signature counter : %lu\n", info.sig_counter); tty_fprintf (fp, "Signature counter : %lu\n", info.sig_counter);
tty_fprintf (fp, "Signature key ....:"); tty_fprintf (fp, "Signature key ....:");
print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL); print_shax_fpr (fp, info.fpr1len? info.fpr1:NULL, info.fpr1len);
if (info.fpr1valid && info.fpr1time) if (info.fpr1len && info.fpr1time)
{ {
tty_fprintf (fp, " created ....: %s\n", tty_fprintf (fp, " created ....: %s\n",
isotimestamp (info.fpr1time)); isotimestamp (info.fpr1time));
print_keygrip (fp, info.grp1); print_keygrip (fp, info.grp1);
} }
tty_fprintf (fp, "Encryption key....:"); tty_fprintf (fp, "Encryption key....:");
print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL); print_shax_fpr (fp, info.fpr2len? info.fpr2:NULL, info.fpr2len);
if (info.fpr2valid && info.fpr2time) if (info.fpr2len && info.fpr2time)
{ {
tty_fprintf (fp, " created ....: %s\n", tty_fprintf (fp, " created ....: %s\n",
isotimestamp (info.fpr2time)); isotimestamp (info.fpr2time));
print_keygrip (fp, info.grp2); print_keygrip (fp, info.grp2);
} }
tty_fprintf (fp, "Authentication key:"); tty_fprintf (fp, "Authentication key:");
print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL); print_shax_fpr (fp, info.fpr3len? info.fpr3:NULL, info.fpr3len);
if (info.fpr3valid && info.fpr3time) if (info.fpr3len && info.fpr3time)
{ {
tty_fprintf (fp, " created ....: %s\n", tty_fprintf (fp, " created ....: %s\n",
isotimestamp (info.fpr3time)); isotimestamp (info.fpr3time));
@ -637,12 +643,14 @@ current_card_status (ctrl_t ctrl, estream_t fp,
} }
tty_fprintf (fp, "General key info..: "); tty_fprintf (fp, "General key info..: ");
thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 : thefpr = (info.fpr1len? info.fpr1 : info.fpr2len? info.fpr2 :
info.fpr3valid? info.fpr3 : NULL); info.fpr3len? info.fpr3 : NULL);
thefprlen = (info.fpr1len? info.fpr1len : info.fpr2len? info.fpr2len :
info.fpr3len? info.fpr3len : 0);
/* If the fingerprint is all 0xff, the key has no asssociated /* If the fingerprint is all 0xff, the key has no asssociated
OpenPGP certificate. */ OpenPGP certificate. */
if ( thefpr && !fpr_is_ff (thefpr) if ( thefpr && !fpr_is_ff (thefpr, thefprlen)
&& !get_pubkey_byfprint (ctrl, pk, &keyblock, thefpr, 20)) && !get_pubkey_byfprint (ctrl, pk, &keyblock, thefpr, thefprlen))
{ {
print_pubkey_info (ctrl, fp, pk); print_pubkey_info (ctrl, fp, pk);
if (keyblock) if (keyblock)
@ -845,9 +853,10 @@ fetch_url (ctrl_t ctrl)
rc = keyserver_fetch (ctrl, sl, KEYORG_URL); rc = keyserver_fetch (ctrl, sl, KEYORG_URL);
free_strlist (sl); free_strlist (sl);
} }
else if (info.fpr1valid) else if (info.fpr1len)
{ {
rc = keyserver_import_fprint (ctrl, info.fpr1, 20, opt.keyserver, 0); rc = keyserver_import_fprint (ctrl, info.fpr1, info.fpr1len,
opt.keyserver, 0);
} }
} }
@ -1309,11 +1318,11 @@ static void
show_card_key_info (struct agent_card_info_s *info) show_card_key_info (struct agent_card_info_s *info)
{ {
tty_fprintf (NULL, "Signature key ....:"); tty_fprintf (NULL, "Signature key ....:");
print_sha1_fpr (NULL, info->fpr1valid? info->fpr1:NULL); print_shax_fpr (NULL, info->fpr1len? info->fpr1:NULL, info->fpr1len);
tty_fprintf (NULL, "Encryption key....:"); tty_fprintf (NULL, "Encryption key....:");
print_sha1_fpr (NULL, info->fpr2valid? info->fpr2:NULL); print_shax_fpr (NULL, info->fpr2len? info->fpr2:NULL, info->fpr2len);
tty_fprintf (NULL, "Authentication key:"); tty_fprintf (NULL, "Authentication key:");
print_sha1_fpr (NULL, info->fpr3valid? info->fpr3:NULL); print_shax_fpr (NULL, info->fpr3len? info->fpr3:NULL, info->fpr3len);
tty_printf ("\n"); tty_printf ("\n");
} }
@ -1324,9 +1333,9 @@ replace_existing_key_p (struct agent_card_info_s *info, int keyno)
{ {
log_assert (keyno >= 0 && keyno <= 3); log_assert (keyno >= 0 && keyno <= 3);
if ((keyno == 1 && info->fpr1valid) if ((keyno == 1 && info->fpr1len)
|| (keyno == 2 && info->fpr2valid) || (keyno == 2 && info->fpr2len)
|| (keyno == 3 && info->fpr3valid)) || (keyno == 3 && info->fpr3len))
{ {
tty_printf ("\n"); tty_printf ("\n");
log_info ("WARNING: such a key has already been stored on the card!\n"); log_info ("WARNING: such a key has already been stored on the card!\n");
@ -1620,9 +1629,9 @@ generate_card_keys (ctrl_t ctrl)
else else
want_backup = 0; want_backup = 0;
if ( (info.fpr1valid && !fpr_is_zero (info.fpr1)) if ( (info.fpr1len && !fpr_is_zero (info.fpr1, info.fpr1len))
|| (info.fpr2valid && !fpr_is_zero (info.fpr2)) || (info.fpr2len && !fpr_is_zero (info.fpr2, info.fpr2len))
|| (info.fpr3valid && !fpr_is_zero (info.fpr3))) || (info.fpr3len && !fpr_is_zero (info.fpr3, info.fpr3len)))
{ {
tty_printf ("\n"); tty_printf ("\n");
log_info (_("Note: keys are already stored on the card!\n")); log_info (_("Note: keys are already stored on the card!\n"));

View File

@ -149,7 +149,8 @@ build_sk_list (ctrl_t ctrl,
} }
err = get_seckey_default_or_card (ctrl, pk, err = get_seckey_default_or_card (ctrl, pk,
info.fpr1valid? info.fpr1 : NULL, 20); info.fpr1len? info.fpr1 : NULL,
info.fpr1len);
if (err) if (err)
{ {
free_public_key (pk); free_public_key (pk);
@ -331,7 +332,7 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
strlist_t sl; strlist_t sl;
strlist_t card_list; strlist_t card_list;
char *serialno; char *serialno;
char fpr2[43]; char fpr2[2 * MAX_FINGERPRINT_LEN + 3 ];
struct agent_card_info_s info; struct agent_card_info_s info;
kbnode_t keyblock; kbnode_t keyblock;
kbnode_t node; kbnode_t node;
@ -419,17 +420,17 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
} }
xfree (serialno); xfree (serialno);
c->info.fpr2valid = 0; c->info.fpr2len = 0;
err = agent_scd_getattr ("KEY-FPR", &c->info); err = agent_scd_getattr ("KEY-FPR", &c->info);
if (err) if (err)
log_error ("error retrieving key fingerprint from card: %s\n", log_error ("error retrieving key fingerprint from card: %s\n",
gpg_strerror (err)); gpg_strerror (err));
if (c->info.fpr2valid) if (c->info.fpr2len)
{ {
c->fpr2[0] = '0'; c->fpr2[0] = '0';
c->fpr2[1] = 'x'; c->fpr2[1] = 'x';
bin2hex (c->info.fpr2, 20, c->fpr2+2); bin2hex (c->info.fpr2, sizeof c->info.fpr2,c->fpr2+2);
name = c->fpr2; name = c->fpr2;
} }
c->sl = c->sl->next; c->sl = c->sl->next;