gpg: Prepare for a longer fingerprint
authorWerner Koch <wk@gnupg.org>
Wed, 27 Sep 2017 07:42:13 +0000 (09:42 +0200)
committerWerner Koch <wk@gnupg.org>
Wed, 27 Sep 2017 07:42:13 +0000 (09:42 +0200)
* g10/card-util.c (change_cafpr): Use MAX_FINGERPRINT_LEN.
* g10/cipher.c (write_header): Use snprintf.
* g10/gpg.h (MAX_FINGERPRINT_LEN): Change to 32.
(MAX_FORMATTED_FINGERPRINT_LEN): Change to 59
* g10/keyid.c (format_hexfingerprint): Add v5 fingerprint format.
* g10/tofu.c (get_policy): Use MAX_FINGERPRINT_LEN for the buffer but
keep the raw length for now.
--

Note that this patch only increases the size of the buffer and adds a
new formatting for v5 fingerprints.  Moe work is required to fix
internal data structures like those in trustdb.gpg and the tofu
tables.

Signed-off-by: Werner Koch <wk@gnupg.org>
g10/card-util.c
g10/cipher.c
g10/gpg.h
g10/keyid.c
g10/keylist.c
g10/sig-check.c
g10/tdbdump.c
g10/tofu.c

index 62b2a67..790f95e 100644 (file)
@@ -1121,7 +1121,8 @@ change_cafpr (int fprno)
   char *data;
   const char *s;
   int i, c, rc;
-  unsigned char fpr[20];
+  unsigned char fpr[MAX_FINGERPRINT_LEN];
+  int fprlen;
 
   data = cpr_get ("cardedit.change_cafpr", _("CA fingerprint: "));
   if (!data)
@@ -1129,7 +1130,7 @@ change_cafpr (int fprno)
   trim_spaces (data);
   cpr_kill_prompt ();
 
-  for (i=0, s=data; i < 20 && *s; )
+  for (i=0, s=data; i < MAX_FINGERPRINT_LEN && *s; )
     {
       while (spacep(s))
         s++;
@@ -1143,8 +1144,9 @@ change_cafpr (int fprno)
       fpr[i++] = c;
       s += 2;
     }
+  fprlen = i;
   xfree (data);
-  if (i != 20 || *s)
+  if ((fprlen != 20 && fprlen != 32) || *s)
     {
       tty_printf (_("Error: invalid formatted fingerprint.\n"));
       return -1;
@@ -1152,7 +1154,7 @@ change_cafpr (int fprno)
 
   rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
                           fprno==2?"CA-FPR-2":
-                          fprno==3?"CA-FPR-3":"x", fpr, 20, NULL );
+                          fprno==3?"CA-FPR-3":"x", fpr, fprlen, NULL );
   if (rc)
     log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
   write_sc_op_status (rc);
index 655937f..7031d93 100644 (file)
@@ -66,7 +66,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
     {
         char buf[20];
 
-        sprintf (buf, "%d %d", ed.mdc_method, cfx->dek->algo);
+        snprintf (buf, sizeof buf, "%d %d", ed.mdc_method, cfx->dek->algo);
         write_status_text (STATUS_BEGIN_ENCRYPTION, buf);
     }
 
index 9b8b77c..03fe384 100644 (file)
--- a/g10/gpg.h
+++ b/g10/gpg.h
 #define MAX_EXTERN_MPI_BITS 16384
 
 /* The maximum length of a binary fingerprints.  This is used to
-   provide a static buffer and will be increased if we need to support
-   longer fingerprints.
-   Warning: At some places we still use 20 instead of this macro. */
-#define MAX_FINGERPRINT_LEN 20
+ * provide a static buffer and will be increased if we need to support
+ * longer fingerprints.  Warning: At some places we have some
+ * assumption on a 20 byte fingerprint.
+ * Watch out for FIXME(fingerprint) */
+#define MAX_FINGERPRINT_LEN 32
 
 /* The maximum length of a formatted fingerprint as returned by
  format_hexfingerprint().  */
-#define MAX_FORMATTED_FINGERPRINT_LEN 50
* format_hexfingerprint().  */
+#define MAX_FORMATTED_FINGERPRINT_LEN 59
 
 
 /*
index de38580..78a5b0b 100644 (file)
@@ -835,8 +835,22 @@ format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen)
               /* Half way through we add a second space.  */
               + 1);
     }
+  else if (hexlen == 64 || hexlen == 50)  /* v5 fingerprint */
+    {
+      /* The v5 fingerprint is commonly printed truncated to 25
+       * octets.  We accept the truncated as well as the full hex
+       * version here and format it like this:
+       * B2CCB6 838332 5D61BA C50F9F 5E CD21A8 0AC8C5 2565C8 C52565
+       */
+      hexlen = 50;
+      space = 8 * 6 + 2 + 8 + 1;
+    }
   else  /* Other fingerprint versions - print as is.  */
     {
+      /* We truncated here so that we do not need to provide a buffer
+       * of a length which is in reality never used.  */
+      if (hexlen > MAX_FORMATTED_FINGERPRINT_LEN - 1)
+        hexlen = MAX_FORMATTED_FINGERPRINT_LEN - 1;
       space = hexlen + 1;
     }
 
@@ -849,7 +863,7 @@ format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen)
     {
       for (i = 0, j = 0; i < 40; i ++)
         {
-          if (i && i % 4 == 0)
+          if (i && !(i % 4))
             buffer[j ++] = ' ';
           if (i == 40 / 2)
             buffer[j ++] = ' ';
@@ -859,9 +873,29 @@ format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen)
       buffer[j ++] = 0;
       log_assert (j == space);
     }
+  else if (hexlen == 50)  /* v5 fingerprint */
+    {
+      for (i=j=0; i < 24; i++)
+        {
+          if (i && !(i % 6))
+            buffer[j++] = ' ';
+          buffer[j++] = fingerprint[i];
+        }
+      buffer[j++] = ' ';
+      buffer[j++] = fingerprint[i++];
+      buffer[j++] = fingerprint[i++];
+      for (; i < 50; i++)
+        {
+          if (!((i-26) % 6))
+            buffer[j++] = ' ';
+          buffer[j++] = fingerprint[i];
+        }
+      buffer[j++] = 0;
+      log_assert (j == space);
+    }
   else
     {
-      strcpy (buffer, fingerprint);
+      mem2str (buffer, fingerprint, space);
     }
 
   return buffer;
index 86d1c56..dccae91 100644 (file)
@@ -1906,6 +1906,9 @@ print_card_serialno (const char *serialno)
  * pub   dsa2048 2007-12-31 [SC] [expires: 2018-12-31]
  *       80615870F5BAD690333686D0F2AD85AC1E42B367
  *
+ * pub   rsa2048 2017-12-31 [SC] [expires: 2028-12-31]
+ *       80615870F5BAD690333686D0F2AD85AC1E42B3671122334455
+ *
  * Some global options may result in a different output format.  If
  * SECRET is set, "sec" or "ssb" is used instead of "pub" or "sub" and
  * depending on the value a flag character is shown:
index 63c38a6..f8e366b 100644 (file)
@@ -233,7 +233,7 @@ check_signature2 (ctrl_t ctrl,
        unsigned char *p, *buffer;
         size_t n, nbytes;
         int i;
-        char hashbuf[20];
+        char hashbuf[20];  /* We use SHA-1 here.  */
 
         nbytes = 6;
        for (i=0; i < nsig; i++ )
index 5ea903f..37bf78b 100644 (file)
@@ -129,7 +129,7 @@ import_ownertrust (ctrl_t ctrl, const char *fname )
     char *p;
     size_t n, fprlen;
     unsigned int otrust;
-    byte fpr[20];
+    byte fpr[MAX_FINGERPRINT_LEN];
     int any = 0;
     int rc;
 
@@ -171,7 +171,7 @@ import_ownertrust (ctrl_t ctrl, const char *fname )
            continue;
        }
        fprlen = p - line;
-       if( fprlen != 32 && fprlen != 40 ) {
+       if( fprlen != 32 && fprlen != 40 && fprlen != 64) {
            log_error (_("error in '%s': %s\n"),
                        fname, _("invalid fingerprint") );
            continue;
@@ -183,10 +183,12 @@ import_ownertrust (ctrl_t ctrl, const char *fname )
        }
        if( !otrust )
            continue; /* no otrust defined - no need to update or insert */
-       /* convert the ascii fingerprint to binary */
-       for(p=line, fprlen=0; fprlen < 20 && *p != ':'; p += 2 )
-           fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]);
-       while (fprlen < 20)
+       /* Convert the ascii fingerprint to binary */
+       for(p=line, fprlen=0;
+            fprlen < MAX_FINGERPRINT_LEN && *p != ':';
+            p += 2 )
+          fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]);
+       while (fprlen < MAX_FINGERPRINT_LEN)
            fpr[fprlen++] = 0;
 
        rc = tdbio_search_trust_byfpr (fpr, &rec);
index c183fc6..ddd7f8c 100644 (file)
@@ -2469,10 +2469,11 @@ get_policy (ctrl_t ctrl, tofu_dbs_t dbs, PKT_public_key *pk,
   /* See if the key is signed by an ultimately trusted key.  */
   {
     int fingerprint_raw_len = strlen (fingerprint) / 2;
-    char fingerprint_raw[20];
+    char fingerprint_raw[MAX_FINGERPRINT_LEN];
     int len = 0;
 
-    if (fingerprint_raw_len != sizeof fingerprint_raw
+    /* FIXME(fingerprint) */
+    if (fingerprint_raw_len != 20 /*sizeof fingerprint_raw */
         || ((len = hex2bin (fingerprint,
                             fingerprint_raw, fingerprint_raw_len))
             != strlen (fingerprint)))