[svn] GnuPG - r5220 - in trunk: . agent common g10 kbx sm
svn author wk
cvs at cvs.gnupg.org
Tue Dec 8 17:30:34 CET 2009
Author: wk
Date: 2009-12-08 17:30:33 +0100 (Tue, 08 Dec 2009)
New Revision: 5220
Added:
trunk/common/userids.c
trunk/common/userids.h
Modified:
trunk/NEWS
trunk/agent/ChangeLog
trunk/agent/protect.c
trunk/common/ChangeLog
trunk/common/Makefile.am
trunk/common/dns-cert.c
trunk/g10/ChangeLog
trunk/g10/delkey.c
trunk/g10/export.c
trunk/g10/getkey.c
trunk/g10/gpg.h
trunk/g10/keydb.h
trunk/g10/keyring.h
trunk/g10/keyserver.c
trunk/g10/packet.h
trunk/g10/pkclist.c
trunk/g10/revoke.c
trunk/g10/trustdb.c
trunk/kbx/ChangeLog
trunk/kbx/keybox-search-desc.h
trunk/kbx/keybox-search.c
trunk/sm/ChangeLog
trunk/sm/certlist.c
trunk/sm/delete.c
trunk/sm/export.c
trunk/sm/import.c
trunk/sm/keydb.c
trunk/sm/keydb.h
trunk/sm/keylist.c
trunk/sm/sign.c
Log:
Unification of the search descriptor usage.
[The diff below has been truncated]
Modified: trunk/agent/ChangeLog
===================================================================
--- trunk/agent/ChangeLog 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/agent/ChangeLog 2009-12-08 16:30:33 UTC (rev 5220)
@@ -1,3 +1,7 @@
+2009-12-08 Werner Koch <wk at g10code.com>
+
+ * protect.c (agent_unprotect): Avoid compiler warning.
+
2009-12-08 Marcus Brinkmann <marcus at g10code.de>
* call-pinentry.c (start_pinentry): Convert posix fd to assuan fd.
Modified: trunk/common/ChangeLog
===================================================================
--- trunk/common/ChangeLog 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/common/ChangeLog 2009-12-08 16:30:33 UTC (rev 5220)
@@ -1,11 +1,14 @@
2009-12-08 Werner Koch <wk at 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 at 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
Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/ChangeLog 2009-12-08 16:30:33 UTC (rev 5220)
@@ -1,3 +1,23 @@
+2009-12-08 Werner Koch <wk at 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 at g10code.com>
* keygen.c (DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE): New.
Modified: trunk/kbx/ChangeLog
===================================================================
--- trunk/kbx/ChangeLog 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/kbx/ChangeLog 2009-12-08 16:30:33 UTC (rev 5220)
@@ -1,3 +1,11 @@
+2009-12-08 Werner Koch <wk at 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 at g10code.com>
* kbxutil.c (main): Call i18n_init before init_common_subsystems.
Modified: trunk/sm/ChangeLog
===================================================================
--- trunk/sm/ChangeLog 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/ChangeLog 2009-12-08 16:30:33 UTC (rev 5220)
@@ -1,3 +1,12 @@
+2009-12-08 Werner Koch <wk at 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 at g10code.de>
* call-dirmngr.c (start_dirmngr_ext): Convert posix fd to assuan fd.
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/NEWS 2009-12-08 16:30:33 UTC (rev 5220)
@@ -14,7 +14,7 @@
* 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)
Modified: trunk/agent/protect.c
===================================================================
--- trunk/agent/protect.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/agent/protect.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -775,6 +775,7 @@
if (!n)
return gpg_error (GPG_ERR_INV_SEXP);
+ cleartext = NULL; /* Avoid cc warning. */
rc = do_decryption (s, n,
passphrase, s2ksalt, s2kcount,
iv, 16,
Modified: trunk/common/Makefile.am
===================================================================
--- trunk/common/Makefile.am 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/common/Makefile.am 2009-12-08 16:30:33 UTC (rev 5220)
@@ -70,6 +70,7 @@
http.c http.h \
localename.c \
session-env.c session-env.h \
+ userids.c userids.h \
helpfile.c
# Sources only useful without PTH.
Modified: trunk/common/dns-cert.c
===================================================================
--- trunk/common/dns-cert.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/common/dns-cert.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -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.
*
Added: trunk/common/userids.c
===================================================================
--- trunk/common/userids.c (rev 0)
+++ trunk/common/userids.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -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 "()<>[]{}. 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.
+ */
+
+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;
+}
Added: trunk/common/userids.h
===================================================================
--- trunk/common/userids.h (rev 0)
+++ trunk/common/userids.h 2009-12-08 16:30:33 UTC (rev 5220)
@@ -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*/
Modified: trunk/g10/delkey.c
===================================================================
--- trunk/g10/delkey.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/delkey.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -63,12 +63,13 @@
*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" );
Modified: trunk/g10/export.c
===================================================================
--- trunk/g10/export.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/export.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -293,6 +293,7 @@
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 @@
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
Modified: trunk/g10/getkey.c
===================================================================
--- trunk/g10/getkey.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/getkey.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -536,229 +536,7 @@
}
-/****************
- * 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 "()<>[]{}. 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
-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 @@
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
Modified: trunk/g10/gpg.h
===================================================================
--- trunk/g10/gpg.h 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/gpg.h 2009-12-08 16:30:33 UTC (rev 5220)
@@ -50,11 +50,8 @@
/* 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
convey the status of a session. Note that the defaults are set by
gpg_init_default_ctrl(). */
Modified: trunk/g10/keydb.h
===================================================================
--- trunk/g10/keydb.h 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/keydb.h 2009-12-08 16:30:33 UTC (rev 5220)
@@ -115,36 +115,7 @@
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 @@
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 );
Modified: trunk/g10/keyring.h
===================================================================
--- trunk/g10/keyring.h 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/keyring.h 2009-12-08 16:30:33 UTC (rev 5220)
@@ -20,6 +20,7 @@
#ifndef GPG_KEYRING_H
#define GPG_KEYRING_H 1
+#include "../common/userids.h"
typedef struct keyring_handle *KEYRING_HANDLE;
Modified: trunk/g10/keyserver.c
===================================================================
--- trunk/g10/keyserver.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/keyserver.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -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 @@
if(ascii_strcasecmp("pub",record)==0)
{
char *tok;
+ gpg_error_t err;
if(work->desc.mode)
{
@@ -606,11 +608,11 @@
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 @@
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 @@
/* 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 @@
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 @@
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 @@
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));
}
}
Modified: trunk/g10/packet.h
===================================================================
--- trunk/g10/packet.h 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/packet.h 2009-12-08 16:30:33 UTC (rev 5220)
@@ -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 @@
#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,13 +184,16 @@
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
{
/* revoked at this date */
Modified: trunk/g10/pkclist.c
===================================================================
--- trunk/g10/pkclist.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/pkclist.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -787,7 +787,7 @@
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)
Modified: trunk/g10/revoke.c
===================================================================
--- trunk/g10/revoke.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/revoke.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -220,8 +220,9 @@
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 @@
* 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"),
Modified: trunk/g10/trustdb.c
===================================================================
--- trunk/g10/trustdb.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/trustdb.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -214,9 +214,11 @@
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;
Modified: trunk/kbx/keybox-search-desc.h
===================================================================
--- trunk/kbx/keybox-search-desc.h 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/kbx/keybox-search-desc.h 2009-12-08 16:30:33 UTC (rev 5220)
@@ -48,24 +48,31 @@
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;
Modified: trunk/kbx/keybox-search.c
===================================================================
--- trunk/kbx/keybox-search.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/kbx/keybox-search.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -530,15 +530,29 @@
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 @@
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 @@
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)
Modified: trunk/sm/certlist.c
===================================================================
--- trunk/sm/certlist.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/certlist.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -301,7 +301,7 @@
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 @@
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);
Modified: trunk/sm/delete.c
===================================================================
--- trunk/sm/delete.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/delete.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -45,7 +45,7 @@
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"),
Modified: trunk/sm/export.c
===================================================================
--- trunk/sm/export.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/export.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -180,7 +180,7 @@
{
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 @@
goto leave;
}
- rc = keydb_classify_name (name, desc);
+ rc = classify_user_id (name, desc);
if (rc)
{
log_error ("key `%s' not found: %s\n",
Modified: trunk/sm/import.c
===================================================================
--- trunk/sm/import.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/import.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -452,7 +452,7 @@
stats->count++;
- err = keydb_classify_name (line, &desc);
+ err = classify_user_id (line, &desc);
if (err)
{
print_import_problem (ctrl, NULL, 0);
Modified: trunk/sm/keydb.c
===================================================================
--- trunk/sm/keydb.c 2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/keydb.c 2009-12-08 16:30:33 UTC (rev 5220)
@@ -949,8 +949,8 @@
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 @@
}
-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;
-}
-
/* 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 @@
{
for (ndesc=0, sl=names; sl; sl = sl->next)
{
- rc = keydb_classify_name (sl->d, desc+ndesc);
More information about the Gnupg-commits
mailing list