Unification of the search descriptor usage.
authorWerner Koch <wk@gnupg.org>
Tue, 8 Dec 2009 16:30:33 +0000 (16:30 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 8 Dec 2009 16:30:33 +0000 (16:30 +0000)
32 files changed:
NEWS
agent/ChangeLog
agent/protect.c
common/ChangeLog
common/Makefile.am
common/dns-cert.c
common/userids.c [new file with mode: 0644]
common/userids.h [new file with mode: 0644]
g10/ChangeLog
g10/delkey.c
g10/export.c
g10/getkey.c
g10/gpg.h
g10/keydb.h
g10/keyring.h
g10/keyserver.c
g10/packet.h
g10/pkclist.c
g10/revoke.c
g10/trustdb.c
kbx/ChangeLog
kbx/keybox-search-desc.h
kbx/keybox-search.c
sm/ChangeLog
sm/certlist.c
sm/delete.c
sm/export.c
sm/import.c
sm/keydb.c
sm/keydb.h
sm/keylist.c
sm/sign.c

diff --git a/NEWS b/NEWS
index 0d543cd..53c4a88 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,7 +14,7 @@ Noteworthy changes in version 2.1.x (under development)
  * Numerical values may now be used as an alternative to the
    debug-level keywords.
 
- * Support SRV and PKA records on W32.
+ * Support DNS lookups for SRV, PKA and CERT on W32.
 
 
 Noteworthy changes in version 2.0.13 (2009-09-04)
index 5618f06..ceb693f 100644 (file)
@@ -1,3 +1,7 @@
+2009-12-08  Werner Koch  <wk@g10code.com>
+
+       * protect.c (agent_unprotect): Avoid compiler warning.
+
 2009-12-08  Marcus Brinkmann  <marcus@g10code.de>
 
        * call-pinentry.c (start_pinentry): Convert posix fd to assuan fd.
index d6457ad..54f6bd3 100644 (file)
@@ -775,6 +775,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
   if (!n)
     return gpg_error (GPG_ERR_INV_SEXP); 
   
+  cleartext = NULL; /* Avoid cc warning. */
   rc = do_decryption (s, n,
                       passphrase, s2ksalt, s2kcount,
                       iv, 16,
index f71e0e3..ab9a59f 100644 (file)
@@ -1,11 +1,14 @@
 2009-12-08  Werner Koch  <wk@g10code.com>
 
+       * userids.h, userids.c: New.
+       (classify_user_id): Merged from similar fucntions in sm/ and g10/.
+
        * dns-cert.c (get_dns_cert): Add support for ADNS.
 
 2009-12-08  Marcus Brinkmann  <marcus@g10code.de>
 
        * asshelp.c (start_new_gpg_agent): Convert posix FD to assuan FD.
-       
+
        * asshelp.c (start_new_gpg_agent) [HAVE_W32_SYSTEM]: Add missing
        argument in assuan_socket_connect invocation.
        * iobuf.c (iobuf_open_fd_or_name): Fix type of FD in function
index 29312c9..d5446dd 100644 (file)
@@ -70,6 +70,7 @@ common_sources = \
        http.c http.h \
        localename.c \
        session-env.c session-env.h \
+       userids.c userids.h \
        helpfile.c
 
 # Sources only useful without PTH.
index 54441d3..efdefaf 100644 (file)
@@ -1,5 +1,5 @@
 /* dns-cert.c - DNS CERT code
- * Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.
  *
  * This file is part of GNUPG.
  *
diff --git a/common/userids.c b/common/userids.c
new file mode 100644 (file)
index 0000000..9a072dd
--- /dev/null
@@ -0,0 +1,322 @@
+/* userids.c - Utility functions for user ids.
+ * Copyright (C) 2001, 2003, 2004, 2006,
+ *               2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This file implements a few utility functions useful when working
+   with canonical encrypted S-expresions (i.e. not the S-exprssion
+   objects from libgcrypt).  */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+#include "userids.h"
+
+
+/* Parse the user-id NAME and build a search description for it.
+ * Returns 0 on succdess or an error code.  DESC may be NULL to merely
+ * check the validity of a user-id.
+ *
+ * Some used rules:
+ * - If the username starts with 8,9,16 or 17 hex-digits (the first one
+ *   must be in the range 0..9), this is considered a keyid; depending
+ *   on the length a short or complete one.
+ * - If the username starts with 32,33,40 or 41 hex-digits (the first one
+ *   must be in the range 0..9), this is considered a fingerprint.
+ * - If the username starts with a left angle, we assume it is a complete
+ *   email address and look only at this part.
+ * - If the username starts with a colon we assume it is a unified 
+ *   key specfification. 
+ * - If the username starts with a '.', we assume it is the ending
+ *   part of an email address
+ * - If the username starts with an '@', we assume it is a part of an
+ *   email address
+ * - If the userid start with an '=' an exact compare is done.
+ * - If the userid starts with a '*' a case insensitive substring search is
+ *   done (This is the default).
+ * - If the userid starts with a '+' we will compare individual words
+ *   and a match requires that all the words are in the userid.
+ *   Words are delimited by white space or "()<>[]{}.@-+_,;/&!"
+ *   (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.
+ */
+
+gpg_error_t
+classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc)
+{
+  const char *s;
+  int hexprefix = 0;
+  int hexlength;
+  int mode = 0;   
+  KEYDB_SEARCH_DESC dummy_desc;
+
+  if (!desc)
+    desc = &dummy_desc;
+    
+  /* Clear the structure so that the mode field is set to zero unless
+     we set it to the correct value right at the end of this
+     function. */
+  memset (desc, 0, sizeof *desc);
+
+  /* Skip leading spaces.  */
+  for(s = name; *s && spacep (s); s++ )
+    ;
+
+  switch (*s) 
+    {
+    case 0:  /* Empty string is an error.  */
+      return gpg_error (GPG_ERR_INV_USER_ID);
+
+    case '.': /* An email address, compare from end.  Note that this
+                 has not yet been implemented in the search code.  */
+      mode = KEYDB_SEARCH_MODE_MAILEND;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '<': /* An email address.  */
+      mode = KEYDB_SEARCH_MODE_MAIL;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '@':  /* Part of an email address.  */
+      mode = KEYDB_SEARCH_MODE_MAILSUB;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '=':  /* Exact compare.  */
+      mode = KEYDB_SEARCH_MODE_EXACT;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '*':  /* Case insensitive substring search.  */
+      mode = KEYDB_SEARCH_MODE_SUBSTR;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '+':  /* Compare individual words.  Note that this has not
+                  yet been implemented in the search code.  */
+      mode = KEYDB_SEARCH_MODE_WORDS;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '/': /* Subject's DN.  */
+      s++;
+      if (!*s || spacep (s)) /* No DN or prefixed with a space.  */
+        return gpg_error (GPG_ERR_INV_USER_ID);
+      desc->u.name = s;
+      mode = KEYDB_SEARCH_MODE_SUBJECT;
+      break;
+
+    case '#': /* S/N with optional issuer id or just issuer id.  */
+      { 
+        const char *si;
+        
+        s++;
+        if ( *s == '/')
+          { /* "#/" indicates an issuer's DN.  */
+            s++;
+            if (!*s || spacep (s)) /* No DN or prefixed with a space.  */
+              return gpg_error (GPG_ERR_INV_USER_ID); 
+            desc->u.name = s;
+            mode = KEYDB_SEARCH_MODE_ISSUER;
+          }
+        else 
+          { /* Serialnumber + optional issuer ID.  */
+            for (si=s; *si && *si != '/'; si++)
+              {
+                 /* Check for an invalid digit in the serial number. */
+                if (!strchr("01234567890abcdefABCDEF", *si))
+                  return gpg_error (GPG_ERR_INV_USER_ID);
+              }
+            desc->sn = (const unsigned char*)s;
+            desc->snlen = -1;
+            if (!*si)
+              mode = KEYDB_SEARCH_MODE_SN;
+            else
+              {
+                s = si+1;
+                if (!*s || spacep (s))  /* No DN or prefixed with a space.  */
+                  return gpg_error (GPG_ERR_INV_USER_ID);
+                desc->u.name = s;
+                mode = KEYDB_SEARCH_MODE_ISSUER_SN;
+              }
+          }
+      }
+      break;
+
+    case ':': /* Unified fingerprint. */
+      {  
+        const char *se, *si;
+        int i;
+        
+        se = strchr (++s,':');
+        if (!se)
+          return gpg_error (GPG_ERR_INV_USER_ID);
+        for (i=0,si=s; si < se; si++, i++ )
+          {
+            if (!strchr("01234567890abcdefABCDEF", *si))
+              return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid digit.  */
+          }
+        if (i != 32 && i != 40)
+          return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid length of fpr.  */
+        for (i=0,si=s; si < se; i++, si +=2) 
+          desc->u.fpr[i] = hextobyte(si);
+        for (; i < 20; i++)
+          desc->u.fpr[i]= 0;
+        s = se + 1;
+        mode = KEYDB_SEARCH_MODE_FPR;
+      } 
+      break;
+
+    case '&': /* Keygrip*/
+      {  
+        if (hex2bin (s+1, desc->u.grip, 20) < 0)
+          return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid. */
+        mode = KEYDB_SEARCH_MODE_KEYGRIP;
+      } 
+      break;
+
+    default:
+      if (s[0] == '0' && s[1] == 'x')
+        {
+          hexprefix = 1;
+          s += 2;
+        }
+
+      hexlength = strspn(s, "0123456789abcdefABCDEF");
+      if (hexlength >= 8 && s[hexlength] =='!')
+        {
+          desc->exact = 1;
+          hexlength++; /* Just for the following check.  */
+        }
+      
+      /* Check if a hexadecimal number is terminated by EOS or blank.  */
+      if (hexlength && s[hexlength] && !spacep (s+hexlength)) 
+        {
+          if (hexprefix) /* A "0x" prefix without a correct
+                            termination is an error.  */
+            return gpg_error (GPG_ERR_INV_USER_ID); 
+          /* The first characters looked like a hex number, but the
+             entire string is not.  */
+          hexlength = 0;  
+        }
+      
+      if (desc->exact)
+        hexlength--; /* Remove the bang.  */
+
+      if (hexlength == 8
+          || (!hexprefix && hexlength == 9 && *s == '0'))
+        { 
+          /* Short keyid.  */
+          if (hexlength == 9)
+            s++; 
+          desc->u.kid[1] = strtoul( s, NULL, 16 );
+          mode = KEYDB_SEARCH_MODE_SHORT_KID;
+        }
+      else if (hexlength == 16
+               || (!hexprefix && hexlength == 17 && *s == '0'))
+        { 
+          /* Long keyid.  */
+          char buf[9];
+          if (hexlength == 17)
+            s++;
+          mem2str (buf, s, 9);
+          desc->u.kid[0] = strtoul (buf, NULL, 16);
+          desc->u.kid[1] = strtoul (s+8, NULL, 16);
+          mode = KEYDB_SEARCH_MODE_LONG_KID;
+        }
+      else if (hexlength == 32
+               || (!hexprefix && hexlength == 33 && *s == '0'))
+        { 
+          /* MD5 fingerprint.  */
+          int i;
+          if (hexlength == 33)
+            s++;
+          memset (desc->u.fpr+16, 0, 4); 
+          for (i=0; i < 16; i++, s+=2) 
+            {
+              int c = hextobyte(s);
+              if (c == -1)
+                return gpg_error (GPG_ERR_INV_USER_ID);
+              desc->u.fpr[i] = c;
+            }
+          mode = KEYDB_SEARCH_MODE_FPR16;
+        }
+      else if (hexlength == 40
+               || (!hexprefix && hexlength == 41 && *s == '0'))
+        { 
+          /* SHA1/RMD160 fingerprint.  */
+          int i;
+          if (hexlength == 41)
+            s++;
+          for (i=0; i < 20; i++, s+=2) 
+            {
+              int c = hextobyte(s);
+              if (c == -1)
+                return gpg_error (GPG_ERR_INV_USER_ID);
+              desc->u.fpr[i] = c;
+            }
+          mode = KEYDB_SEARCH_MODE_FPR20;
+        }
+      else if (!hexprefix)
+        { 
+          /* The fingerprint in an X.509 listing is often delimited by
+             colons, so we try to single this case out. */
+          mode = 0;
+          hexlength = strspn (s, ":0123456789abcdefABCDEF");
+          if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) 
+            {
+              int i;
+
+              for (i=0; i < 20; i++, s += 3) 
+                {
+                  int c = hextobyte(s);
+                  if (c == -1 || (i < 19 && s[2] != ':'))
+                    break;
+                  desc->u.fpr[i] = c;
+                }
+              if (i == 20)
+                mode = KEYDB_SEARCH_MODE_FPR20;
+            }
+          if (!mode) /* Default to substring search.  */
+            { 
+              desc->exact = 0;
+              desc->u.name = s;
+              mode = KEYDB_SEARCH_MODE_SUBSTR; 
+            }
+        }
+      else
+       { 
+          /* Hex number with a prefix but with a wrong length.  */
+          return gpg_error (GPG_ERR_INV_USER_ID);
+        }
+    }
+  
+  desc->mode = mode;
+  return 0;
+}
diff --git a/common/userids.h b/common/userids.h
new file mode 100644 (file)
index 0000000..246b107
--- /dev/null
@@ -0,0 +1,28 @@
+/* userids.h - Utility functions for user ids.
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_COMMON_USERIDS_H
+#define GNUPG_COMMON_USERIDS_H
+
+#include "../kbx/keybox-search-desc.h"
+
+gpg_error_t classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc);
+
+
+#endif /*GNUPG_COMMON_USERIDS_H*/
index 9ac9f85..873167c 100644 (file)
@@ -1,3 +1,23 @@
+2009-12-08  Werner Koch  <wk@g10code.com>
+
+       * keyring.h: Include userids.h. 
+       * gpg.h (KEYDB_SEARCH_DESC): Remove.
+       * packet.h: Include userids.h.
+       (PKT_user_id): Declare using gpg_pkt_user_id_s.
+       * keydb.h (KeydbSearchMode, struct keydb_search_desc): Remove.  We
+       now use those in ../kbx.
+       * getkey.c (classify_user_id): Remove.  It is now in common/.
+       (key_byname): Adjust for changed classify_user_id.
+       * delkey.c (do_delete_key): Ditto.
+       * trustdb.c (register_trusted_key): Ditto.
+       * revoke.c (gen_desig_revoke, gen_revoke): Ditto.
+       * keyserver.c (parse_keyrec, keyserver_export, keyserver_import)
+       (keyidlist): Ditto.
+       * export.c (do_export_stream): Ditto.
+
+       * pkclist.c (find_and_check_key): Replace GPG_ERR_INV_NAME by
+       GPG_ERR_INV_USER_ID.
+
 2009-12-04  Werner Koch  <wk@g10code.com>
 
        * keygen.c (DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE): New.
index fe29d52..5d86e72 100644 (file)
@@ -63,12 +63,13 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
 
     *r_sec_avail = 0;
 
-    /* search the userid */
-    classify_user_id (username, &desc);
+    /* Search the userid */
+    rc = classify_user_id (username, &desc);
     exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR
                   || desc.mode == KEYDB_SEARCH_MODE_FPR16
                   || desc.mode == KEYDB_SEARCH_MODE_FPR20);
-    rc = desc.mode? keydb_search (hd, &desc, 1):G10ERR_INV_USER_ID;
+    if (!rc)
+      rc = keydb_search (hd, &desc, 1);
     if (rc) {
        log_error (_("key \"%s\" not found: %s\n"), username, g10_errstr (rc));
        write_status_text( STATUS_DELETE_PROBLEM, "1" );
index 9b87e59..3a4c665 100644 (file)
@@ -293,6 +293,7 @@ do_export_stream( IOBUF out, strlist_t users, int secret,
                  KBNODE *keyblock_out, unsigned int options, int *any )
 {
     int rc = 0;
+    gpg_error_t err;
     PACKET pkt;
     KBNODE keyblock = NULL;
     KBNODE kbctx, node;
@@ -318,11 +319,11 @@ do_export_stream( IOBUF out, strlist_t users, int secret,
         desc = xmalloc ( ndesc * sizeof *desc);
         
         for (ndesc=0, sl=users; sl; sl = sl->next) {
-           if (classify_user_id (sl->d, desc+ndesc))
+            if (!(err=classify_user_id (sl->d, desc+ndesc)))
                 ndesc++;
             else
                 log_error (_("key \"%s\" not found: %s\n"),
-                           sl->d, g10_errstr (G10ERR_INV_USER_ID));
+                           sl->d, gpg_strerror (err));
         }
 
         /* It would be nice to see which of the given users did
index 54843cf..c636d6b 100644 (file)
@@ -536,228 +536,6 @@ seckey_available( u32 *keyid )
 }
 
 
-/****************
- * Return the type of the user id:
- *
- * Please use the constants KEYDB_SERCH_MODE_xxx
- *  0 = Invalid user ID
- *  1 = exact match
- *  2 = match a substring
- *  3 = match an email address
- *  4 = match a substring of an email address
- *  5 = match an email address, but compare from end
- *  6 = word match mode
- * 10 = it is a short KEYID (don't care about keyid[0])
- * 11 = it is a long  KEYID
- * 12 = it is a trustdb index (keyid is looked up)
- * 16 = it is a 16 byte fingerprint
- * 20 = it is a 20 byte fingerprint
- * 21 = Unified fingerprint :fpr:pk_algo:
- *      (We don't use pk_algo yet)
- *
- * Rules used:
- * - If the username starts with 8,9,16 or 17 hex-digits (the first one
- *   must be in the range 0..9), this is considered a keyid; depending
- *   on the length a short or complete one.
- * - If the username starts with 32,33,40 or 41 hex-digits (the first one
- *   must be in the range 0..9), this is considered a fingerprint.
- * - If the username starts with a left angle, we assume it is a complete
- *   email address and look only at this part.
- * - If the username starts with a colon we assume it is a unified 
- *   key specfification. 
- * - If the username starts with a '.', we assume it is the ending
- *   part of an email address
- * - If the username starts with an '@', we assume it is a part of an
- *   email address
- * - If the userid start with an '=' an exact compare is done.
- * - If the userid starts with a '*' a case insensitive substring search is
- *   done (This is the default).
- * - If the userid starts with a '+' we will compare individual words
- *   and a match requires that all the words are in the userid.
- *   Words are delimited by white space or "()<>[]{}.@-+_,;/&!"
- *   (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
-classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc )
-{
-    const char *s;
-    int hexprefix = 0;
-    int hexlength;
-    int mode = 0;   
-    KEYDB_SEARCH_DESC dummy_desc;
-
-    if (!desc)
-        desc = &dummy_desc;
-
-    /* clear the structure so that the mode field is set to zero unless
-     * we set it to the correct value right at the end of this function */
-    memset (desc, 0, sizeof *desc);
-
-    /* skip leading spaces.  Fixme: what is with trailing spaces? */
-    for(s = name; *s && spacep (s); s++ )
-       ;
-
-    switch (*s) {
-       case 0:    /* empty string is an error */
-           return 0;
-
-#if 0
-       case '.':  /* an email address, compare from end */
-           mode = KEYDB_SEARCH_MODE_MAILEND;
-           s++;
-            desc->u.name = s;
-           break;
-#endif
-
-       case '<':  /* an email address */
-           mode = KEYDB_SEARCH_MODE_MAIL;
-            desc->u.name = s;
-           break;
-
-       case '@':  /* part of an email address */
-           mode = KEYDB_SEARCH_MODE_MAILSUB;
-           s++;
-            desc->u.name = s;
-           break;
-
-       case '=':  /* exact compare */
-           mode = KEYDB_SEARCH_MODE_EXACT;
-           s++;
-            desc->u.name = s;
-           break;
-
-       case '*':  /* case insensitive substring search */
-           mode = KEYDB_SEARCH_MODE_SUBSTR;
-           s++;
-            desc->u.name = s;
-           break;
-
-#if 0
-       case '+':  /* compare individual words */
-           mode = KEYDB_SEARCH_MODE_WORDS;
-           s++;
-            desc->u.name = s;
-           break;
-#endif
-
-       case '#':  /* local user id */
-            return 0; /* This is now obsolete and can't not be used anymore*/
-        
-        case ':': /*Unified fingerprint */
-            {  
-                const char *se, *si;
-                int i;
-                
-                se = strchr( ++s,':');
-                if ( !se )
-                    return 0;
-                for (i=0,si=s; si < se; si++, i++ ) {
-                    if ( !strchr("01234567890abcdefABCDEF", *si ) )
-                        return 0; /* invalid digit */
-                }
-                if (i != 32 && i != 40)
-                    return 0; /* invalid length of fpr*/
-                for (i=0,si=s; si < se; i++, si +=2) 
-                    desc->u.fpr[i] = hextobyte(si);
-                for ( ; i < 20; i++)
-                    desc->u.fpr[i]= 0;
-                s = se + 1;
-                mode = KEYDB_SEARCH_MODE_FPR;
-            } 
-            break;
-           
-       case '&':  /* keygrip */
-          return 0; /* Not yet implememted. */
-
-       default:
-           if (s[0] == '0' && s[1] == 'x') {
-               hexprefix = 1;
-               s += 2;
-           }
-
-           hexlength = strspn(s, "0123456789abcdefABCDEF");
-            if (hexlength >= 8 && s[hexlength] =='!') {
-               desc->exact = 1;
-                hexlength++; /* just for the following check */
-            }
-
-           /* check if a hexadecimal number is terminated by EOS or blank */
-           if (hexlength && s[hexlength] && !spacep(s+hexlength)) {
-               if (hexprefix)      /* a "0x" prefix without correct */
-                   return 0;       /* termination is an error */
-               else                /* The first chars looked like */
-                   hexlength = 0;  /* a hex number, but really were not. */
-           }
-
-            if (desc->exact)
-                hexlength--;
-
-           if (hexlength == 8
-                || (!hexprefix && hexlength == 9 && *s == '0')){
-               /* short keyid */
-               if (hexlength == 9)
-                   s++;
-                desc->u.kid[0] = 0;
-                desc->u.kid[1] = strtoul( s, NULL, 16 );
-               mode = KEYDB_SEARCH_MODE_SHORT_KID;
-           }
-           else if (hexlength == 16
-                     || (!hexprefix && hexlength == 17 && *s == '0')) {
-               /* complete keyid */
-               char buf[9];
-               if (hexlength == 17)
-                   s++;
-               mem2str(buf, s, 9 );
-               desc->u.kid[0] = strtoul( buf, NULL, 16 );
-               desc->u.kid[1] = strtoul( s+8, NULL, 16 );
-               mode = KEYDB_SEARCH_MODE_LONG_KID;
-           }
-           else if (hexlength == 32 || (!hexprefix && hexlength == 33
-                                                           && *s == '0')) {
-               /* md5 fingerprint */
-               int i;
-               if (hexlength == 33)
-                   s++;
-                memset(desc->u.fpr+16, 0, 4); 
-                for (i=0; i < 16; i++, s+=2) {
-                    int c = hextobyte(s);
-                    if (c == -1)
-                        return 0;
-                    desc->u.fpr[i] = c;
-                }
-               mode = KEYDB_SEARCH_MODE_FPR16;
-           }
-           else if (hexlength == 40 || (!hexprefix && hexlength == 41
-                                                             && *s == '0')) {
-               /* sha1/rmd160 fingerprint */
-               int i;
-               if (hexlength == 41)
-                   s++;
-                for (i=0; i < 20; i++, s+=2) {
-                    int c = hextobyte(s);
-                    if (c == -1)
-                        return 0;
-                    desc->u.fpr[i] = c;
-                }
-               mode = KEYDB_SEARCH_MODE_FPR20;
-           }
-           else {
-               if (hexprefix)  /* This was a hex number with a prefix */
-                   return 0;   /* and a wrong length */
-
-               desc->exact = 0;
-                desc->u.name = s;
-               mode = KEYDB_SEARCH_MODE_SUBSTR;   /* default mode */
-           }
-    }
-
-    desc->mode = mode;
-    return mode;
-}
-
 
 static int
 skip_unusable (void *dummy, u32 *keyid, PKT_user_id *uid)
@@ -851,14 +629,16 @@ key_byname( GETKEY_CTX *retctx, strlist_t namelist,
 
        for(n=0, r=namelist; r; r = r->next, n++ )
          {
-           classify_user_id (r->d, &ctx->items[n]);
+            gpg_error_t err;
+
+           err = classify_user_id (r->d, &ctx->items[n]);
         
            if (ctx->items[n].exact)
              ctx->exact = 1;
-           if (!ctx->items[n].mode)
+           if (err)
              {
                xfree (ctx);
-               return G10ERR_INV_USER_ID;
+               return gpg_err_code (err); /* FIXME: remove gpg_err_code.  */
              }
            if(!include_unusable
               && ctx->items[n].mode!=KEYDB_SEARCH_MODE_SHORT_KID
index b53303e..da2a738 100644 (file)
--- a/g10/gpg.h
+++ b/g10/gpg.h
@@ -50,9 +50,6 @@ struct server_local_s;
 
 /* Object used to describe a keyblok node.  */
 typedef struct kbnode_struct *KBNODE;
-/* Object used for looking ob keys.  */
-typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
-
 
 
 /* Session control object.  This object is passed to most functions to
index c58a101..68949a7 100644 (file)
@@ -115,35 +115,6 @@ struct pubkey_find_info {
 
 typedef struct keydb_handle *KEYDB_HANDLE;
 
-typedef enum {
-    KEYDB_SEARCH_MODE_NONE,
-    KEYDB_SEARCH_MODE_EXACT,
-    KEYDB_SEARCH_MODE_SUBSTR,
-    KEYDB_SEARCH_MODE_MAIL,
-    KEYDB_SEARCH_MODE_MAILSUB,
-    KEYDB_SEARCH_MODE_MAILEND,
-    KEYDB_SEARCH_MODE_WORDS,
-    KEYDB_SEARCH_MODE_SHORT_KID,
-    KEYDB_SEARCH_MODE_LONG_KID,
-    KEYDB_SEARCH_MODE_FPR16,
-    KEYDB_SEARCH_MODE_FPR20,
-    KEYDB_SEARCH_MODE_FPR,
-    KEYDB_SEARCH_MODE_FIRST,
-    KEYDB_SEARCH_MODE_NEXT
-} KeydbSearchMode;
-
-struct keydb_search_desc {
-    KeydbSearchMode mode;
-    int (*skipfnc)(void *,u32*,PKT_user_id*);
-    void *skipfncvalue;
-    union {
-        const char *name;
-        byte fpr[MAX_FINGERPRINT_LEN];
-        u32  kid[2];
-    } u;
-    int exact;
-};
-
 
 /* Helper type for preference fucntions. */
 union pref_hint
@@ -221,7 +192,6 @@ char *get_last_passphrase(void);
 void next_to_last_passphrase(void);
 
 /*-- getkey.c --*/
-int classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc);
 void cache_public_key( PKT_public_key *pk );
 void getkey_disable_caches(void);
 int get_pubkey( PKT_public_key *pk, u32 *keyid );
index 928605c..420e179 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef GPG_KEYRING_H
 #define GPG_KEYRING_H 1
 
+#include "../common/userids.h"
 
 typedef struct keyring_handle *KEYRING_HANDLE;
 
index 36c52f0..461444f 100644 (file)
@@ -46,6 +46,7 @@
 #include "srv.h"
 #endif
 
+
 #ifdef HAVE_W32_SYSTEM
 /* It seems Vista doesn't grok X_OK and so fails access() tests.
    Previous versions interpreted X_OK as F_OK anyway, so we'll just
@@ -595,6 +596,7 @@ parse_keyrec(char *keystring)
   if(ascii_strcasecmp("pub",record)==0)
     {
       char *tok;
+      gpg_error_t err;
 
       if(work->desc.mode)
        {
@@ -606,11 +608,11 @@ parse_keyrec(char *keystring)
       if((tok=strsep(&keystring,":"))==NULL)
        return ret;
 
-      classify_user_id(tok,&work->desc);
-      if(work->desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID
-        && work->desc.mode!=KEYDB_SEARCH_MODE_LONG_KID
-        && work->desc.mode!=KEYDB_SEARCH_MODE_FPR16
-        && work->desc.mode!=KEYDB_SEARCH_MODE_FPR20)
+      err = classify_user_id (tok, &work->desc);
+      if (err || (work->desc.mode    != KEYDB_SEARCH_MODE_SHORT_KID
+                  && work->desc.mode != KEYDB_SEARCH_MODE_LONG_KID
+                  && work->desc.mode != KEYDB_SEARCH_MODE_FPR16
+                  && work->desc.mode != KEYDB_SEARCH_MODE_FPR20))
        {
          work->desc.mode=KEYDB_SEARCH_MODE_NONE;
          return ret;
@@ -1598,6 +1600,7 @@ keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
 int 
 keyserver_export(strlist_t users)
 {
+  gpg_error_t err;
   strlist_t sl=NULL;
   KEYDB_SEARCH_DESC desc;
   int rc=0;
@@ -1605,11 +1608,11 @@ keyserver_export(strlist_t users)
   /* Weed out descriptors that we don't support sending */
   for(;users;users=users->next)
     {
-      classify_user_id (users->d, &desc);
-      if(desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
-        desc.mode!=KEYDB_SEARCH_MODE_LONG_KID &&
-        desc.mode!=KEYDB_SEARCH_MODE_FPR16 &&
-        desc.mode!=KEYDB_SEARCH_MODE_FPR20)
+      err = classify_user_id (users->d, &desc);
+      if (err || (desc.mode    != KEYDB_SEARCH_MODE_SHORT_KID
+                  && desc.mode != KEYDB_SEARCH_MODE_LONG_KID
+                  && desc.mode != KEYDB_SEARCH_MODE_FPR16
+                  && desc.mode != KEYDB_SEARCH_MODE_FPR20))
        {
          log_error(_("\"%s\" not a key ID: skipping\n"),users->d);
          continue;
@@ -1630,6 +1633,7 @@ keyserver_export(strlist_t users)
 int 
 keyserver_import(strlist_t users)
 {
+  gpg_error_t err;
   KEYDB_SEARCH_DESC *desc;
   int num=100,count=0;
   int rc=0;
@@ -1639,13 +1643,13 @@ keyserver_import(strlist_t users)
 
   for(;users;users=users->next)
     {
-      classify_user_id (users->d, &desc[count]);
-      if(desc[count].mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
-        desc[count].mode!=KEYDB_SEARCH_MODE_LONG_KID &&
-        desc[count].mode!=KEYDB_SEARCH_MODE_FPR16 &&
-        desc[count].mode!=KEYDB_SEARCH_MODE_FPR20)
+      err = classify_user_id (users->d, &desc[count]);
+      if (err || (desc[count].mode    != KEYDB_SEARCH_MODE_SHORT_KID
+                  && desc[count].mode != KEYDB_SEARCH_MODE_LONG_KID
+                  && desc[count].mode != KEYDB_SEARCH_MODE_FPR16
+                  && desc[count].mode != KEYDB_SEARCH_MODE_FPR20))
        {
-         log_error(_("\"%s\" not a key ID: skipping\n"),users->d);
+         log_error (_("\"%s\" not a key ID: skipping\n"), users->d);
          continue;
        }
 
@@ -1731,11 +1735,12 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
         
       for (ndesc=0, sl=users; sl; sl = sl->next)
        {
-         if(classify_user_id (sl->d, desc+ndesc))
+          gpg_error_t err; 
+         if (!(err = classify_user_id (sl->d, desc+ndesc)))
            ndesc++;
          else
            log_error (_("key \"%s\" not found: %s\n"),
-                      sl->d, g10_errstr (G10ERR_INV_USER_ID));
+                      sl->d, gpg_strerror (err));
        }
     }
 
index 395e70a..2ceaba4 100644 (file)
@@ -27,6 +27,7 @@
 #include "cipher.h"
 #include "filter.h"
 #include "../common/openpgpdefs.h"
+#include "../common/userids.h"
 
 #define DEBUG_PARSE_PACKET 1
 
@@ -151,14 +152,16 @@ typedef struct
 
 #define ATTRIB_IMAGE 1
 
-/* This is the cooked form of attributes */
+/* This is the cooked form of attributes */
 struct user_attribute {
   byte type;
   const byte *data;
   u32 len;
 };
 
-typedef struct
+
+/* (See also keybox-search-desc.h) */
+struct gpg_pkt_user_id_s
 {
   int ref;              /* reference counter */
   int len;             /* length of the name */
@@ -181,12 +184,15 @@ typedef struct
   struct
   {
     /* TODO: Move more flags here */
-    unsigned mdc:1;
-    unsigned ks_modify:1;
-    unsigned compacted:1;
+    unsigned int mdc:1;
+    unsigned int ks_modify:1;
+    unsigned int compacted:1;
   } flags;
   char name[1];
-} PKT_user_id;
+};
+typedef struct gpg_pkt_user_id_s PKT_user_id;
+
+
 
 struct revoke_info
 {
index 1683592..cbc76c7 100644 (file)
@@ -787,7 +787,7 @@ find_and_check_key (const char *name, unsigned int use,
   int trustlevel;
 
   if (!name || !*name)
-    return gpg_error (GPG_ERR_INV_NAME);
+    return gpg_error (GPG_ERR_INV_USER_ID);
 
   pk = xtrycalloc (1, sizeof *pk);
   if (!pk)
index b34684e..38b9556 100644 (file)
@@ -220,8 +220,9 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
     afx = new_armor_context ();
 
     kdbhd = keydb_new (0);
-    classify_user_id (uname, &desc);
-    rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
+    rc = classify_user_id (uname, &desc);
+    if (!rc)
+      rc = keydb_search (kdbhd, &desc, 1);
     if (rc) {
        log_error (_("key \"%s\" not found: %s\n"),uname, g10_errstr (rc));
        goto leave;
@@ -463,8 +464,9 @@ gen_revoke( const char *uname )
      * We don't want the whole getkey stuff here but the entire keyblock
      */
     kdbhd = keydb_new (1);
-    classify_user_id (uname, &desc);
-    rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
+    rc = classify_user_id (uname, &desc);
+    if (!rc)
+      rc = keydb_search (kdbhd, &desc, 1);
     if (rc)
       {
        log_error (_("secret key \"%s\" not found: %s\n"),
index 2db9715..9bfae9e 100644 (file)
@@ -214,9 +214,11 @@ register_trusted_keyid(u32 *keyid)
 void
 register_trusted_key( const char *string )
 {
+  gpg_error_t err;
   KEYDB_SEARCH_DESC desc;
 
-  if (classify_user_id (string, &desc) != KEYDB_SEARCH_MODE_LONG_KID )
+  err = classify_user_id (string, &desc);
+  if (err || desc.mode != KEYDB_SEARCH_MODE_LONG_KID )
     {
       log_error(_("`%s' is not a valid long keyID\n"), string );
       return;
index b4f9882..7b5a546 100644 (file)
@@ -1,3 +1,11 @@
+2009-12-08  Werner Koch  <wk@g10code.com>
+
+       * keybox-search-desc.h (keydb_search_desc): Use u32 type for
+       KID. Extend the skip function ptr.
+       (gpg_pkt_user_id_t): New.
+       * keybox-search.c (has_short_kid, has_long_kid): Change to use u32
+       args for KID.
+
 2008-12-09  Werner Koch  <wk@g10code.com>
 
        * kbxutil.c (main): Call i18n_init before init_common_subsystems.
index 98d8135..e5da155 100644 (file)
@@ -48,24 +48,31 @@ typedef enum {
   KEYDB_SEARCH_MODE_NEXT
 } KeydbSearchMode;
 
-struct keydb_search_desc {
+
+/* Forwward declaration.  See g10/packet.h.  */
+struct gpg_pkt_user_id_s;
+typedef struct gpg_pkt_user_id_s *gpg_pkt_user_id_t;
+
+/* A search descriptor.  */
+struct keydb_search_desc 
+{
   KeydbSearchMode mode;
-  int (*skipfnc)(void *,void*); /* used to be: void*, u32* */
+  int (*skipfnc)(void *, u32 *, gpg_pkt_user_id_t); 
   void *skipfncvalue;
   const unsigned char *sn; 
   int snlen;  /* -1 := sn is a hex string */
   union {
     const char *name;
     unsigned char fpr[24];
-    unsigned char kid[8]; 
+    u32 kid[2]; /* Note that this is in native endianess.  */
     unsigned char grip[20];
   } u;
+  int exact;    /* Use exactly this key ('!' suffix in gpg).  */
 };
 
 
 struct keydb_search_desc;
 typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
-
 typedef struct keydb_search_desc KEYBOX_SEARCH_DESC;
 
 
index 1680dd7..be4ca45 100644 (file)
@@ -530,15 +530,29 @@ blob_x509_has_grip (KEYBOXBLOB blob, const unsigned char *grip)
   The has_foo functions are used as helpers for search 
 */
 static inline int
-has_short_kid (KEYBOXBLOB blob, const unsigned char *kid)
+has_short_kid (KEYBOXBLOB blob, u32 lkid)
 {
-  return blob_cmp_fpr_part (blob, kid+4, 16, 4);
+  unsigned char buf[4];
+  buf[0] = lkid >> 24;
+  buf[1] = lkid >> 16;
+  buf[2] = lkid >> 8;
+  buf[3] = lkid;
+  return blob_cmp_fpr_part (blob, buf, 16, 4);
 }
 
 static inline int
-has_long_kid (KEYBOXBLOB blob, const unsigned char *kid)
+has_long_kid (KEYBOXBLOB blob, u32 mkid, u32 lkid)
 {
-  return blob_cmp_fpr_part (blob, kid, 12, 8);
+  unsigned char buf[8];
+  buf[0] = mkid >> 24;
+  buf[1] = mkid >> 16;
+  buf[2] = mkid >> 8;
+  buf[3] = mkid;
+  buf[4] = lkid >> 24;
+  buf[5] = lkid >> 16;
+  buf[6] = lkid >> 8;
+  buf[7] = lkid;
+  return blob_cmp_fpr_part (blob, buf, 12, 8);
 }
 
 static inline int
@@ -877,11 +891,11 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_SHORT_KID: 
-              if (has_short_kid (blob, desc[n].u.kid))
+              if (has_short_kid (blob, desc[n].u.kid[1]))
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_LONG_KID:
-              if (has_long_kid (blob, desc[n].u.kid))
+              if (has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]))
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_FPR:
@@ -909,7 +923,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
       for (n=any_skip?0:ndesc; n < ndesc; n++) 
         {
 /*            if (desc[n].skipfnc */
-/*                && desc[n].skipfnc (desc[n].skipfncvalue, aki)) */
+/*                && desc[n].skipfnc (desc[n].skipfncvalue, aki, NULL)) */
 /*              break; */
         }
       if (n == ndesc)
index a96b903..bb2b4b3 100644 (file)
@@ -1,3 +1,12 @@
+2009-12-08  Werner Koch  <wk@g10code.com>
+
+       * keydb.c (keydb_search_kid): Fix code even that it is not used.
+       (classify_user_id): Adjust for change of u.kid type.
+       (keydb_classify_name): Replace GPG_ERR_INV_NAME by
+       GPG_ERR_INV_USER_ID.
+       (keydb_classify_name): Remove.  Replace all callers by
+       classify_user_id.
+
 2009-12-08  Marcus Brinkmann  <marcus@g10code.de>
 
        * call-dirmngr.c (start_dirmngr_ext): Convert posix fd to assuan fd.
index 4137437..8221e4a 100644 (file)
@@ -301,7 +301,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
   KEYDB_HANDLE kh = NULL;
   ksba_cert_t cert = NULL;
 
-  rc = keydb_classify_name (name, &desc);
+  rc = classify_user_id (name, &desc);
   if (!rc)
     {
       kh = keydb_new (0);
@@ -480,7 +480,7 @@ gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert)
   KEYDB_HANDLE kh = NULL;
 
   *r_cert = NULL;
-  rc = keydb_classify_name (name, &desc);
+  rc = classify_user_id (name, &desc);
   if (!rc)
     {
       kh = keydb_new (0);
index fd49ebe..e2835a9 100644 (file)
@@ -45,7 +45,7 @@ delete_one (ctrl_t ctrl, const char *username)
   int duplicates = 0;
   int is_ephem = 0;
   
-  rc = keydb_classify_name (username, &desc);
+  rc = classify_user_id (username, &desc);
   if (rc)
     {
       log_error (_("certificate `%s' not found: %s\n"),
index fcf1dcc..b194d0d 100644 (file)
@@ -180,7 +180,7 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, FILE *fp, estream_t stream)
     {
       for (ndesc=0, sl=names; sl; sl = sl->next) 
         {
-          rc = keydb_classify_name (sl->d, desc+ndesc);
+          rc = classify_user_id (sl->d, desc+ndesc);
           if (rc)
             {
               log_error ("key `%s' not found: %s\n",
@@ -359,7 +359,7 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp)
       goto leave;
     }
 
-  rc = keydb_classify_name (name, desc);
+  rc = classify_user_id (name, desc);
   if (rc)
     {
       log_error ("key `%s' not found: %s\n",
index 5a0eded..bcc2d6d 100644 (file)
@@ -452,7 +452,7 @@ reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
     
       stats->count++;
 
-      err = keydb_classify_name (line, &desc);
+      err = classify_user_id (line, &desc);
       if (err)
         {
           print_import_problem (ctrl, NULL, 0);
index a1f0e9c..ddf9a48 100644 (file)
@@ -949,8 +949,8 @@ keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
   
   memset (&desc, 0, sizeof desc);
   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
-/*    desc.u.kid[0] = kid[0]; */
-/*    desc.u.kid[1] = kid[1]; */
+  desc.u.kid[0] = kid[0];
+  desc.u.kid[1] = kid[1];
   return keydb_search (hd, &desc, 1);
 }
 
@@ -1016,284 +1016,6 @@ keydb_search_subject (KEYDB_HANDLE hd, const char *name)
 }
 
 
-static int
-classify_user_id (const char *name, 
-                  KEYDB_SEARCH_DESC *desc,
-                  int *force_exact )
-{
-  const char *s;
-  int hexprefix = 0;
-  int hexlength;
-  int mode = 0;   
-    
-  /* clear the structure so that the mode field is set to zero unless
-   * we set it to the correct value right at the end of this function */
-  memset (desc, 0, sizeof *desc);
-  *force_exact = 0;
-  /* Skip leading spaces.  Fixme: what about trailing white space? */
-  for(s = name; *s && spacep (s); s++ )
-    ;
-
-  switch (*s) 
-    {
-    case 0:  /* empty string is an error */
-      return 0;
-
-    case '.': /* an email address, compare from end */
-      mode = KEYDB_SEARCH_MODE_MAILEND;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '<': /* an email address */
-      mode = KEYDB_SEARCH_MODE_MAIL;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '@':  /* part of an email address */
-      mode = KEYDB_SEARCH_MODE_MAILSUB;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '=':  /* exact compare */
-      mode = KEYDB_SEARCH_MODE_EXACT;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '*':  /* case insensitive substring search */
-      mode = KEYDB_SEARCH_MODE_SUBSTR;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '+':  /* compare individual words */
-      mode = KEYDB_SEARCH_MODE_WORDS;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '/': /* subject's DN */
-      s++;
-      if (!*s || spacep (s))
-        return 0; /* no DN or prefixed with a space */
-      desc->u.name = s;
-      mode = KEYDB_SEARCH_MODE_SUBJECT;
-      break;
-
-    case '#':
-      { 
-        const char *si;
-        
-        s++;
-        if ( *s == '/')
-          { /* "#/" indicates an issuer's DN */
-            s++;
-            if (!*s || spacep (s))
-              return 0; /* no DN or prefixed with a space */
-            desc->u.name = s;
-            mode = KEYDB_SEARCH_MODE_ISSUER;
-          }
-        else 
-          { /* serialnumber + optional issuer ID */
-            for (si=s; *si && *si != '/'; si++)
-              {
-                if (!strchr("01234567890abcdefABCDEF", *si))
-                  return 0; /* invalid digit in serial number*/
-              }
-            desc->sn = (const unsigned char*)s;
-            desc->snlen = -1;
-            if (!*si)
-              mode = KEYDB_SEARCH_MODE_SN;
-            else
-              {
-                s = si+1;
-                if (!*s || spacep (s))
-                  return 0; /* no DN or prefixed with a space */
-                desc->u.name = s;
-                mode = KEYDB_SEARCH_MODE_ISSUER_SN;
-              }
-          }
-      }
-      break;
-
-    case ':': /*Unified fingerprint */
-      {  
-        const char *se, *si;
-        int i;
-        
-        se = strchr (++s,':');
-        if (!se)
-          return 0;
-        for (i=0,si=s; si < se; si++, i++ )
-          {
-            if (!strchr("01234567890abcdefABCDEF", *si))
-              return 0; /* invalid digit */
-          }
-        if (i != 32 && i != 40)
-          return 0; /* invalid length of fpr*/
-        for (i=0,si=s; si < se; i++, si +=2) 
-          desc->u.fpr[i] = hextobyte(si);
-        for (; i < 20; i++)
-          desc->u.fpr[i]= 0;
-        s = se + 1;
-        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')
-        {
-          hexprefix = 1;
-          s += 2;
-        }
-
-      hexlength = strspn(s, "0123456789abcdefABCDEF");
-      if (hexlength >= 8 && s[hexlength] =='!')
-        {
-          *force_exact = 1;
-          hexlength++; /* just for the following check */
-        }
-      
-      /* check if a hexadecimal number is terminated by EOS or blank */
-      if (hexlength && s[hexlength] && !spacep (s+hexlength)) 
-        {
-          if (hexprefix) /* a "0x" prefix without correct */
-            return 0;   /* termination is an error */
-          /* The first chars looked like a hex number, but really is
-             not */
-          hexlength = 0;  
-        }
-      
-      if (*force_exact)
-        hexlength--; /* remove the bang */
-
-      if (hexlength == 8
-          || (!hexprefix && hexlength == 9 && *s == '0'))
-        { /* short keyid */
-          unsigned long kid;
-          if (hexlength == 9)
-            s++;
-          kid = strtoul( s, NULL, 16 );
-          desc->u.kid[4] = kid >> 24; 
-          desc->u.kid[5] = kid >> 16; 
-          desc->u.kid[6] = kid >>  8; 
-          desc->u.kid[7] = kid; 
-          mode = KEYDB_SEARCH_MODE_SHORT_KID;
-        }
-      else if (hexlength == 16
-               || (!hexprefix && hexlength == 17 && *s == '0'))
-        { /* complete keyid */
-          unsigned long kid0, kid1;
-          char buf[9];
-          if (hexlength == 17)
-            s++;
-          mem2str(buf, s, 9 );
-          kid0 = strtoul (buf, NULL, 16);
-          kid1 = strtoul (s+8, NULL, 16);
-          desc->u.kid[0] = kid0 >> 24; 
-          desc->u.kid[1] = kid0 >> 16; 
-          desc->u.kid[2] = kid0 >>  8; 
-          desc->u.kid[3] = kid0; 
-          desc->u.kid[4] = kid1 >> 24; 
-          desc->u.kid[5] = kid1 >> 16; 
-          desc->u.kid[6] = kid1 >>  8; 
-          desc->u.kid[7] = kid1; 
-          mode = KEYDB_SEARCH_MODE_LONG_KID;
-        }
-      else if (hexlength == 32
-               || (!hexprefix && hexlength == 33 && *s == '0'))
-        { /* md5 fingerprint */
-          int i;
-          if (hexlength == 33)
-            s++;
-          memset(desc->u.fpr+16, 0, 4); 
-          for (i=0; i < 16; i++, s+=2) 
-            {
-              int c = hextobyte(s);
-              if (c == -1)
-                return 0;
-              desc->u.fpr[i] = c;
-            }
-          mode = KEYDB_SEARCH_MODE_FPR16;
-        }
-      else if (hexlength == 40
-               || (!hexprefix && hexlength == 41 && *s == '0'))
-        { /* sha1/rmd160 fingerprint */
-          int i;
-          if (hexlength == 41)
-            s++;
-          for (i=0; i < 20; i++, s+=2) 
-            {
-              int c = hextobyte(s);
-              if (c == -1)
-                return 0;
-              desc->u.fpr[i] = c;
-            }
-          mode = KEYDB_SEARCH_MODE_FPR20;
-        }
-      else if (!hexprefix)
-        { 
-          /* The fingerprint in an X.509 listing is often delimited by
-             colons, so we try to single this case out. */
-          mode = 0;
-          hexlength = strspn (s, ":0123456789abcdefABCDEF");
-          if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) 
-            {
-              int i;
-
-              for (i=0; i < 20; i++, s += 3) 
-                {
-                  int c = hextobyte(s);
-                  if (c == -1 || (i < 19 && s[2] != ':'))
-                    break;
-                  desc->u.fpr[i] = c;
-                }
-              if (i == 20)
-                mode = KEYDB_SEARCH_MODE_FPR20;
-            }
-          if (!mode) /* default is substring search */
-            { 
-              *force_exact = 0;
-              desc->u.name = s;
-              mode = KEYDB_SEARCH_MODE_SUBSTR; 
-            }
-        }
-      else
-       { /* hex number with a prefix but a wrong length */
-          return 0;
-        }
-    }
-  
-  desc->mode = mode;
-  return mode;
-}
-
-
-int
-keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc)
-{
-  int dummy;
-  KEYDB_SEARCH_DESC dummy_desc;
-
-  if (!desc)
-    desc = &dummy_desc;
-
-  if (!classify_user_id (name, desc, &dummy))
-    return gpg_error (GPG_ERR_INV_NAME);
-  return 0;
-}
-
 \f
 /* Store the certificate in the key DB but make sure that it does not
    already exists.  We do this simply by comparing the fingerprint.
@@ -1483,7 +1205,7 @@ keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names)
     {
       for (ndesc=0, sl=names; sl; sl = sl->next) 
         {
-          rc = keydb_classify_name (sl->d, desc+ndesc);
+          rc = classify_user_id (sl->d, desc+ndesc);
           if (rc)
             {
               log_error ("key `%s' not found: %s\n",
index a440c50..a62ce99 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <ksba.h>
 
-#include "../kbx/keybox-search-desc.h"
+#include "../common/userids.h"
 
 typedef struct keydb_handle *KEYDB_HANDLE;
 
@@ -69,8 +69,6 @@ int keydb_search_issuer_sn (KEYDB_HANDLE hd,
                             const char *issuer, const unsigned char *serial);
 int keydb_search_subject (KEYDB_HANDLE hd, const char *issuer);
 
-int keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc);
-
 int keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed);
 gpg_error_t keydb_set_cert_flags (ksba_cert_t cert, int ephemeral,
                                   int which, int idx,
index 9b8538c..e323b27 100644 (file)
@@ -1334,7 +1334,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
     {
       for (ndesc=0, sl=names; sl; sl = sl->next) 
         {
-          rc = keydb_classify_name (sl->d, desc+ndesc);
+          rc = classify_user_id (sl->d, desc+ndesc);
           if (rc)
             {
               log_error ("key `%s' not found: %s\n",
index fd7c4ff..2ab8b42 100644 (file)
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -209,7 +209,7 @@ get_default_signer (ctrl_t ctrl)
       return cert;
     }
 
-  rc = keydb_classify_name (opt.local_user, &desc);
+  rc = classify_user_id (opt.local_user, &desc);
   if (rc)
     {
       log_error ("failed to find default signer: %s\n", gpg_strerror (rc));