[svn] GnuPG - r4312 - in trunk: . common doc g10 kbx sm

svn author wk cvs at cvs.gnupg.org
Fri Oct 20 13:38:50 CEST 2006


Author: wk
Date: 2006-10-20 13:38:48 +0200 (Fri, 20 Oct 2006)
New Revision: 4312

Modified:
   trunk/NEWS
   trunk/common/ChangeLog
   trunk/common/convert.c
   trunk/common/t-convert.c
   trunk/common/util.h
   trunk/doc/specify-user-id.texi
   trunk/g10/ChangeLog
   trunk/g10/getkey.c
   trunk/kbx/ChangeLog
   trunk/kbx/keybox-search-desc.h
   trunk/kbx/keybox-search.c
   trunk/sm/ChangeLog
   trunk/sm/keydb.c
Log:
Allow to select X.509 certificates using the keygrip.


Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/NEWS	2006-10-20 11:38:48 UTC (rev 4312)
@@ -1,7 +1,10 @@
 Noteworthy changes in version 1.9.94
 -------------------------------------------------
 
+ * Keys for gpgsm may now be specified using a keygrip.  A keygrip is
+   indicated by a prefixing it with an ampersand.
 
+
 Noteworthy changes in version 1.9.93 (2006-10-18)
 -------------------------------------------------
 

Modified: trunk/common/ChangeLog
===================================================================
--- trunk/common/ChangeLog	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/common/ChangeLog	2006-10-20 11:38:48 UTC (rev 4312)
@@ -1,3 +1,7 @@
+2006-10-20  Werner Koch  <wk at g10code.com>
+
+	* convert.c (hex2bin): New.
+
 2006-10-17  Werner Koch  <wk at g10code.com>
 
 	* estream.c (struct estream_internal, es_initialize) 

Modified: trunk/common/convert.c
===================================================================
--- trunk/common/convert.c	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/common/convert.c	2006-10-20 11:38:48 UTC (rev 4312)
@@ -30,6 +30,35 @@
 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
 
 
+/* Convert STRING consisting of hex characters into its binary
+   representation and store that at BUFFER.  BUFFER needs to be of
+   LENGTH bytes.  The function check that the STRING will convert
+   exactly to LENGTH bytes. The string is delimited by either end of
+   string or a white space character.  The function returns -1 on
+   error or the length of the parsed string.  */
+int
+hex2bin (const char *string, void *buffer, size_t length)
+{
+  int i;
+  const char *s = string;
+
+  for (i=0; i < length; )
+    {
+      if (!hexdigitp (s) || !hexdigitp (s+1))
+        return -1;           /* Invalid hex digits. */
+      ((unsigned char*)buffer)[i++] = xtoi_2 (s);
+      s += 2;
+    }
+  if (*s && (!isascii (*s) || !isspace (*s)) )
+    return -1;             /* Not followed by Nul or white space.  */
+  if (i != length)
+    return -1;             /* Not of expected length.  */
+  if (*s)
+    s++; /* Skip the delimiter. */
+  return s - string;
+}
+
+
 /* Convert STRING consisting of hex characters into its binary representation
    and store that at BUFFER.  BUFFER needs to be of LENGTH bytes.  The
    function check that the STRING will convert exactly to LENGTH
@@ -73,7 +102,6 @@
 }
 
 
-
 static char *
 do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon)
 {

Modified: trunk/common/t-convert.c
===================================================================
--- trunk/common/t-convert.c	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/common/t-convert.c	2006-10-20 11:38:48 UTC (rev 4312)
@@ -33,6 +33,93 @@
 
 
 static void
+test_hex2bin (void)
+{
+  static const char *valid[] = {
+    "00112233445566778899aabbccddeeff11223344",
+    "00112233445566778899AABBCCDDEEFF11223344",
+    "00112233445566778899AABBCCDDEEFF11223344 blah",
+    "00112233445566778899AABBCCDDEEFF11223344\tblah",
+    "00112233445566778899AABBCCDDEEFF11223344\nblah",
+    NULL
+  };
+  static const char *invalid[] = {
+    "00112233445566778899aabbccddeeff1122334",
+    "00112233445566778899AABBCCDDEEFF1122334",
+    "00112233445566778899AABBCCDDEEFG11223344",
+    "00 112233445566778899aabbccddeeff11223344",
+    "00:112233445566778899aabbccddeeff11223344",
+    ":00112233445566778899aabbccddeeff11223344",
+    "0:0112233445566778899aabbccddeeff11223344",
+    "00112233445566778899aabbccddeeff11223344:",
+    "00112233445566778899aabbccddeeff112233445",
+    "00112233445566778899aabbccddeeff1122334455",
+    "00112233445566778899aabbccddeeff11223344blah",
+    NULL
+  };
+  static const char *valid2[] = {
+    "00",
+    "00 x",
+    NULL
+  };
+  static const char *invalid2[] = {
+    "",
+    "0",
+    "00:",
+    "00x",
+    " 00",
+    NULL
+  };
+  unsigned char buffer[20];
+  int len;
+  int i;
+  
+  
+  for (i=0; valid[i]; i++)
+    {
+      len = hex2bin (valid[i], buffer, sizeof buffer);
+      if (len < 0)
+        fail (i);
+      if (memcmp (buffer, ("\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa"
+                           "\xbb\xcc\xdd\xee\xff\x11\x22\x33\x44"), 20))
+          fail (i);
+    }
+  if (hex2bin (valid[0], buffer, sizeof buffer) != 40)
+    fail (0);
+  if (hex2bin (valid[2], buffer, sizeof buffer) != 41)
+    fail (0);
+  
+  for (i=0; invalid[i]; i++)
+    {
+      len = hex2bin (invalid[i], buffer, sizeof buffer);
+      if (!(len < 0))
+        fail (i);
+    }
+
+  for (i=0; valid2[i]; i++)
+    {
+      len = hex2bin (valid2[i], buffer, 1);
+      if (len < 0)
+        fail (i);
+      if (memcmp (buffer, "\x00", 1))
+        fail (i);
+    }
+  if (hex2bin (valid2[0], buffer, 1) != 2)
+    fail (0);
+  if (hex2bin (valid2[1], buffer, 1) != 3)
+    fail (0);
+  
+  for (i=0; invalid2[i]; i++)
+    {
+      len = hex2bin (invalid2[i], buffer, 1);
+      if (!(len < 0))
+        fail (i);
+    }
+}
+
+
+
+static void
 test_hexcolon2bin (void)
 {
   static const char *valid[] = {
@@ -195,6 +282,7 @@
 main (int argc, char **argv)
 {
   
+  test_hex2bin ();
   test_hexcolon2bin ();
   test_bin2hex ();
   test_bin2hexcolon ();

Modified: trunk/common/util.h
===================================================================
--- trunk/common/util.h	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/common/util.h	2006-10-20 11:38:48 UTC (rev 4312)
@@ -157,6 +157,7 @@
                                              size_t *nscanned);
 
 /*-- convert.c --*/
+int hex2bin (const char *string, void *buffer, size_t length);
 int hexcolon2bin (const char *string, void *buffer, size_t length);
 char *bin2hex (const void *buffer, size_t length, char *stringbuf);
 char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf);

Modified: trunk/doc/specify-user-id.texi
===================================================================
--- trunk/doc/specify-user-id.texi	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/doc/specify-user-id.texi	2006-10-20 11:38:48 UTC (rev 4312)
@@ -131,7 +131,18 @@
 @end example
 @end cartouche
 
+ at item By keygrip
+This is indicated by an ampersand followed by the 40 hex digits of a
+keygrip.  @command{gpgsm} prints the keygrip when using the command
+ at option{--dump-cert}.  It does not yet work for OpenPGP keys.
 
+ at cartouche
+ at example
+&D75F22C3F86E355877348498CDC92BD21010A480
+ at end example
+ at end cartouche
+
+
 @item By substring match.
 This is the default mode but applications may want to explicitly
 indicate this by putting the asterisk in front.  Match is not case

Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/g10/ChangeLog	2006-10-20 11:38:48 UTC (rev 4312)
@@ -1,3 +1,7 @@
+2006-10-20  Werner Koch  <wk at g10code.com>
+
+	* getkey.c (classify_user_id): Reserve '&' for search by keygrip.
+
 2006-10-19  Werner Koch  <wk at g10code.com>
 
 	* keygen.c (get_parameter_algo): Add special case for ELG_E which

Modified: trunk/g10/getkey.c
===================================================================
--- trunk/g10/getkey.c	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/g10/getkey.c	2006-10-20 11:38:48 UTC (rev 4312)
@@ -578,6 +578,7 @@
  *   Words are delimited by white space or "()<>[]{}. at -+_,;/&!"
  *   (note that you can't search for these characters). Compare
  *   is not case sensitive.
+ * - If the userid starts with a '&' a 40 hex digits keygrip is expected.
  */
 
 int
@@ -644,7 +645,7 @@
 #endif
 
 	case '#':  /* local user id */
-            return 0; /* This is now obsolete and van't not be used anymore*/
+            return 0; /* This is now obsolete and can't not be used anymore*/
         
         case ':': /*Unified fingerprint */
             {  
@@ -669,6 +670,9 @@
             } 
             break;
            
+	case '&':  /* keygrip */
+          return 0; /* Not yet implememted. */
+
 	default:
 	    if (s[0] == '0' && s[1] == 'x') {
 		hexprefix = 1;

Modified: trunk/kbx/ChangeLog
===================================================================
--- trunk/kbx/ChangeLog	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/kbx/ChangeLog	2006-10-20 11:38:48 UTC (rev 4312)
@@ -1,3 +1,10 @@
+2006-10-20  Werner Koch  <wk at g10code.com>
+
+	* keybox-search.c (blob_x509_has_grip, has_keygrip): New.
+	(keybox_search): Implement new search mode.
+	* keybox-search-desc.h (KEYDB_SEARCH_MODE_KEYGRIP): New.
+	(keydb_search_desc): New member GRIP.
+
 2006-09-20  Werner Koch  <wk at g10code.com>
 
 	* Makefile.am ($(PROGRAMS): New.

Modified: trunk/kbx/keybox-search-desc.h
===================================================================
--- trunk/kbx/keybox-search-desc.h	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/kbx/keybox-search-desc.h	2006-10-20 11:38:48 UTC (rev 4312)
@@ -45,6 +45,7 @@
   KEYDB_SEARCH_MODE_ISSUER_SN,
   KEYDB_SEARCH_MODE_SN,
   KEYDB_SEARCH_MODE_SUBJECT,
+  KEYDB_SEARCH_MODE_KEYGRIP,
   KEYDB_SEARCH_MODE_FIRST,
   KEYDB_SEARCH_MODE_NEXT
 } KeydbSearchMode;
@@ -59,6 +60,7 @@
     const char *name;
     unsigned char fpr[24];
     unsigned char kid[8]; 
+    unsigned char grip[20];
   } u;
 };
 

Modified: trunk/kbx/keybox-search.c
===================================================================
--- trunk/kbx/keybox-search.c	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/kbx/keybox-search.c	2006-10-20 11:38:48 UTC (rev 4312)
@@ -29,6 +29,7 @@
 #include "../jnlib/stringhelp.h" /* ascii_xxxx() */
 
 #include "keybox-defs.h"
+#include <gcrypt.h>
 
 
 #define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
@@ -456,7 +457,76 @@
 }
 
 
+#ifdef KEYBOX_WITH_X509
+/* Return true if the key in BLOB matches the 20 bytes keygrip GRIP.
+   We don't have the keygrips as meta data, thus wen need to parse the
+   certificate. Fixme: We might wat to return proper error codes
+   instead of failing a search for invalid certificates etc.  */
+static int
+blob_x509_has_grip (KEYBOXBLOB blob, const unsigned char *grip)
+{
+  int rc;
+  const unsigned char *buffer;
+  size_t length;
+  size_t cert_off, cert_len;
+  ksba_reader_t reader = NULL;
+  ksba_cert_t cert = NULL;
+  ksba_sexp_t p = NULL;
+  gcry_sexp_t s_pkey;
+  unsigned char array[20];
+  unsigned char *rcp;
+  size_t n;
+  
+  buffer = _keybox_get_blob_image (blob, &length);
+  if (length < 40)
+    return 0; /* Too short. */
+  cert_off = get32 (buffer+8);
+  cert_len = get32 (buffer+12);
+  if (cert_off+cert_len > length)
+    return 0; /* Too short.  */
 
+  rc = ksba_reader_new (&reader);
+  if (rc)
+    return 0; /* Problem with ksba. */
+  rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len);
+  if (rc)
+    goto failed;
+  rc = ksba_cert_new (&cert);
+  if (rc)
+    goto failed;
+  rc = ksba_cert_read_der (cert, reader);
+  if (rc)
+    goto failed;
+  p = ksba_cert_get_public_key (cert);
+  if (!p)
+    goto failed;
+  n = gcry_sexp_canon_len (p, 0, NULL, NULL);
+  if (!n)
+    goto failed;
+  rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)p, n);
+  if (rc)
+    {
+      gcry_sexp_release (s_pkey);
+      goto failed;
+    }
+  rcp = gcry_pk_get_keygrip (s_pkey, array);
+  gcry_sexp_release (s_pkey);
+  if (!rcp)
+    goto failed; /* Can't calculate keygrip. */
+
+  xfree (p);
+  ksba_cert_release (cert);
+  ksba_reader_release (reader);
+  return !memcmp (array, grip, 20);
+ failed:
+  xfree (p);
+  ksba_cert_release (cert);
+  ksba_reader_release (reader);
+  return 0;
+}
+#endif /*KEYBOX_WITH_X509*/
+
+
 
 /*
   The has_foo functions are used as helpers for search 
@@ -479,7 +549,17 @@
   return blob_cmp_fpr (blob, fpr);
 }
 
+static inline int
+has_keygrip (KEYBOXBLOB blob, const unsigned char *grip)
+{
+#ifdef KEYBOX_WITH_X509
+  if (blob_get_type (blob) == BLOBTYPE_X509)
+    return blob_x509_has_grip (blob, grip);
+#endif
+  return 0;
+}
 
+
 static inline int
 has_issuer (KEYBOXBLOB blob, const char *name)
 {
@@ -809,6 +889,10 @@
               if (has_fingerprint (blob, desc[n].u.fpr))
                 goto found;
               break;
+            case KEYDB_SEARCH_MODE_KEYGRIP:
+              if (has_keygrip (blob, desc[n].u.grip))
+                goto found;
+              break;
             case KEYDB_SEARCH_MODE_FIRST: 
               goto found;
               break;

Modified: trunk/sm/ChangeLog
===================================================================
--- trunk/sm/ChangeLog	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/sm/ChangeLog	2006-10-20 11:38:48 UTC (rev 4312)
@@ -1,3 +1,7 @@
+2006-10-20  Werner Koch  <wk at g10code.com>
+
+	* keydb.c (classify_user_id): Parse keygrip for the '&' identifier.
+
 2006-10-18  Werner Koch  <wk at g10code.com>
 
 	* keylist.c (list_cert_raw): Also test for GPG_ERR_NO_VALUE when

Modified: trunk/sm/keydb.c
===================================================================
--- trunk/sm/keydb.c	2006-10-20 04:00:19 UTC (rev 4311)
+++ trunk/sm/keydb.c	2006-10-20 11:38:48 UTC (rev 4312)
@@ -1140,7 +1140,15 @@
         mode = KEYDB_SEARCH_MODE_FPR;
       } 
       break;
-           
+
+    case '&': /* Keygrip*/
+      {  
+        if (hex2bin (s+1, desc->u.grip, 20) < 0)
+          return 0; /* Invalid. */
+        mode = KEYDB_SEARCH_MODE_KEYGRIP;
+      } 
+      break;
+
     default:
       if (s[0] == '0' && s[1] == 'x')
         {




More information about the Gnupg-commits mailing list