mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Unification of the search descriptor usage.
This commit is contained in:
parent
bb861ac730
commit
9a96043be4
2
NEWS
2
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
|
* Numerical values may now be used as an alternative to the
|
||||||
debug-level keywords.
|
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)
|
Noteworthy changes in version 2.0.13 (2009-09-04)
|
||||||
|
@ -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>
|
2009-12-08 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* call-pinentry.c (start_pinentry): Convert posix fd to assuan fd.
|
* call-pinentry.c (start_pinentry): Convert posix fd to assuan fd.
|
||||||
|
@ -775,6 +775,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
|
|||||||
if (!n)
|
if (!n)
|
||||||
return gpg_error (GPG_ERR_INV_SEXP);
|
return gpg_error (GPG_ERR_INV_SEXP);
|
||||||
|
|
||||||
|
cleartext = NULL; /* Avoid cc warning. */
|
||||||
rc = do_decryption (s, n,
|
rc = do_decryption (s, n,
|
||||||
passphrase, s2ksalt, s2kcount,
|
passphrase, s2ksalt, s2kcount,
|
||||||
iv, 16,
|
iv, 16,
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
2009-12-08 Werner Koch <wk@g10code.com>
|
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.
|
* dns-cert.c (get_dns_cert): Add support for ADNS.
|
||||||
|
|
||||||
2009-12-08 Marcus Brinkmann <marcus@g10code.de>
|
2009-12-08 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
@ -70,6 +70,7 @@ common_sources = \
|
|||||||
http.c http.h \
|
http.c http.h \
|
||||||
localename.c \
|
localename.c \
|
||||||
session-env.c session-env.h \
|
session-env.c session-env.h \
|
||||||
|
userids.c userids.h \
|
||||||
helpfile.c
|
helpfile.c
|
||||||
|
|
||||||
# Sources only useful without PTH.
|
# Sources only useful without PTH.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* dns-cert.c - DNS CERT code
|
/* 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.
|
* This file is part of GNUPG.
|
||||||
*
|
*
|
||||||
|
322
common/userids.c
Normal file
322
common/userids.c
Normal file
@ -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;
|
||||||
|
}
|
28
common/userids.h
Normal file
28
common/userids.h
Normal file
@ -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*/
|
@ -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>
|
2009-12-04 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* keygen.c (DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE): New.
|
* keygen.c (DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE): New.
|
||||||
|
@ -63,12 +63,13 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
|
|||||||
|
|
||||||
*r_sec_avail = 0;
|
*r_sec_avail = 0;
|
||||||
|
|
||||||
/* search the userid */
|
/* Search the userid */
|
||||||
classify_user_id (username, &desc);
|
rc = classify_user_id (username, &desc);
|
||||||
exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR
|
exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR16
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR16
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR20);
|
|| 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) {
|
if (rc) {
|
||||||
log_error (_("key \"%s\" not found: %s\n"), username, g10_errstr (rc));
|
log_error (_("key \"%s\" not found: %s\n"), username, g10_errstr (rc));
|
||||||
write_status_text( STATUS_DELETE_PROBLEM, "1" );
|
write_status_text( STATUS_DELETE_PROBLEM, "1" );
|
||||||
|
@ -293,6 +293,7 @@ do_export_stream( IOBUF out, strlist_t users, int secret,
|
|||||||
KBNODE *keyblock_out, unsigned int options, int *any )
|
KBNODE *keyblock_out, unsigned int options, int *any )
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
gpg_error_t err;
|
||||||
PACKET pkt;
|
PACKET pkt;
|
||||||
KBNODE keyblock = NULL;
|
KBNODE keyblock = NULL;
|
||||||
KBNODE kbctx, node;
|
KBNODE kbctx, node;
|
||||||
@ -318,11 +319,11 @@ do_export_stream( IOBUF out, strlist_t users, int secret,
|
|||||||
desc = xmalloc ( ndesc * sizeof *desc);
|
desc = xmalloc ( ndesc * sizeof *desc);
|
||||||
|
|
||||||
for (ndesc=0, sl=users; sl; sl = sl->next) {
|
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++;
|
ndesc++;
|
||||||
else
|
else
|
||||||
log_error (_("key \"%s\" not found: %s\n"),
|
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
|
/* It would be nice to see which of the given users did
|
||||||
|
230
g10/getkey.c
230
g10/getkey.c
@ -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
|
static int
|
||||||
skip_unusable (void *dummy, u32 *keyid, PKT_user_id *uid)
|
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++ )
|
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)
|
if (ctx->items[n].exact)
|
||||||
ctx->exact = 1;
|
ctx->exact = 1;
|
||||||
if (!ctx->items[n].mode)
|
if (err)
|
||||||
{
|
{
|
||||||
xfree (ctx);
|
xfree (ctx);
|
||||||
return G10ERR_INV_USER_ID;
|
return gpg_err_code (err); /* FIXME: remove gpg_err_code. */
|
||||||
}
|
}
|
||||||
if(!include_unusable
|
if(!include_unusable
|
||||||
&& ctx->items[n].mode!=KEYDB_SEARCH_MODE_SHORT_KID
|
&& ctx->items[n].mode!=KEYDB_SEARCH_MODE_SHORT_KID
|
||||||
|
@ -50,9 +50,6 @@ struct server_local_s;
|
|||||||
|
|
||||||
/* Object used to describe a keyblok node. */
|
/* Object used to describe a keyblok node. */
|
||||||
typedef struct kbnode_struct *KBNODE;
|
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
|
/* Session control object. This object is passed to most functions to
|
||||||
|
30
g10/keydb.h
30
g10/keydb.h
@ -115,35 +115,6 @@ struct pubkey_find_info {
|
|||||||
|
|
||||||
typedef struct keydb_handle *KEYDB_HANDLE;
|
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. */
|
/* Helper type for preference fucntions. */
|
||||||
union pref_hint
|
union pref_hint
|
||||||
@ -221,7 +192,6 @@ char *get_last_passphrase(void);
|
|||||||
void next_to_last_passphrase(void);
|
void next_to_last_passphrase(void);
|
||||||
|
|
||||||
/*-- getkey.c --*/
|
/*-- getkey.c --*/
|
||||||
int classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc);
|
|
||||||
void cache_public_key( PKT_public_key *pk );
|
void cache_public_key( PKT_public_key *pk );
|
||||||
void getkey_disable_caches(void);
|
void getkey_disable_caches(void);
|
||||||
int get_pubkey( PKT_public_key *pk, u32 *keyid );
|
int get_pubkey( PKT_public_key *pk, u32 *keyid );
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#ifndef GPG_KEYRING_H
|
#ifndef GPG_KEYRING_H
|
||||||
#define GPG_KEYRING_H 1
|
#define GPG_KEYRING_H 1
|
||||||
|
|
||||||
|
#include "../common/userids.h"
|
||||||
|
|
||||||
typedef struct keyring_handle *KEYRING_HANDLE;
|
typedef struct keyring_handle *KEYRING_HANDLE;
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "srv.h"
|
#include "srv.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
/* It seems Vista doesn't grok X_OK and so fails access() tests.
|
/* 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
|
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)
|
if(ascii_strcasecmp("pub",record)==0)
|
||||||
{
|
{
|
||||||
char *tok;
|
char *tok;
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
if(work->desc.mode)
|
if(work->desc.mode)
|
||||||
{
|
{
|
||||||
@ -606,11 +608,11 @@ parse_keyrec(char *keystring)
|
|||||||
if((tok=strsep(&keystring,":"))==NULL)
|
if((tok=strsep(&keystring,":"))==NULL)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
classify_user_id(tok,&work->desc);
|
err = classify_user_id (tok, &work->desc);
|
||||||
if(work->desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID
|
if (err || (work->desc.mode != KEYDB_SEARCH_MODE_SHORT_KID
|
||||||
&& work->desc.mode!=KEYDB_SEARCH_MODE_LONG_KID
|
&& work->desc.mode != KEYDB_SEARCH_MODE_LONG_KID
|
||||||
&& work->desc.mode!=KEYDB_SEARCH_MODE_FPR16
|
&& work->desc.mode != KEYDB_SEARCH_MODE_FPR16
|
||||||
&& work->desc.mode!=KEYDB_SEARCH_MODE_FPR20)
|
&& work->desc.mode != KEYDB_SEARCH_MODE_FPR20))
|
||||||
{
|
{
|
||||||
work->desc.mode=KEYDB_SEARCH_MODE_NONE;
|
work->desc.mode=KEYDB_SEARCH_MODE_NONE;
|
||||||
return ret;
|
return ret;
|
||||||
@ -1598,6 +1600,7 @@ keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
|||||||
int
|
int
|
||||||
keyserver_export(strlist_t users)
|
keyserver_export(strlist_t users)
|
||||||
{
|
{
|
||||||
|
gpg_error_t err;
|
||||||
strlist_t sl=NULL;
|
strlist_t sl=NULL;
|
||||||
KEYDB_SEARCH_DESC desc;
|
KEYDB_SEARCH_DESC desc;
|
||||||
int rc=0;
|
int rc=0;
|
||||||
@ -1605,11 +1608,11 @@ keyserver_export(strlist_t users)
|
|||||||
/* Weed out descriptors that we don't support sending */
|
/* Weed out descriptors that we don't support sending */
|
||||||
for(;users;users=users->next)
|
for(;users;users=users->next)
|
||||||
{
|
{
|
||||||
classify_user_id (users->d, &desc);
|
err = classify_user_id (users->d, &desc);
|
||||||
if(desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
|
if (err || (desc.mode != KEYDB_SEARCH_MODE_SHORT_KID
|
||||||
desc.mode!=KEYDB_SEARCH_MODE_LONG_KID &&
|
&& desc.mode != KEYDB_SEARCH_MODE_LONG_KID
|
||||||
desc.mode!=KEYDB_SEARCH_MODE_FPR16 &&
|
&& desc.mode != KEYDB_SEARCH_MODE_FPR16
|
||||||
desc.mode!=KEYDB_SEARCH_MODE_FPR20)
|
&& desc.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;
|
continue;
|
||||||
@ -1630,6 +1633,7 @@ keyserver_export(strlist_t users)
|
|||||||
int
|
int
|
||||||
keyserver_import(strlist_t users)
|
keyserver_import(strlist_t users)
|
||||||
{
|
{
|
||||||
|
gpg_error_t err;
|
||||||
KEYDB_SEARCH_DESC *desc;
|
KEYDB_SEARCH_DESC *desc;
|
||||||
int num=100,count=0;
|
int num=100,count=0;
|
||||||
int rc=0;
|
int rc=0;
|
||||||
@ -1639,13 +1643,13 @@ keyserver_import(strlist_t users)
|
|||||||
|
|
||||||
for(;users;users=users->next)
|
for(;users;users=users->next)
|
||||||
{
|
{
|
||||||
classify_user_id (users->d, &desc[count]);
|
err = classify_user_id (users->d, &desc[count]);
|
||||||
if(desc[count].mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
|
if (err || (desc[count].mode != KEYDB_SEARCH_MODE_SHORT_KID
|
||||||
desc[count].mode!=KEYDB_SEARCH_MODE_LONG_KID &&
|
&& desc[count].mode != KEYDB_SEARCH_MODE_LONG_KID
|
||||||
desc[count].mode!=KEYDB_SEARCH_MODE_FPR16 &&
|
&& desc[count].mode != KEYDB_SEARCH_MODE_FPR16
|
||||||
desc[count].mode!=KEYDB_SEARCH_MODE_FPR20)
|
&& 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;
|
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)
|
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++;
|
ndesc++;
|
||||||
else
|
else
|
||||||
log_error (_("key \"%s\" not found: %s\n"),
|
log_error (_("key \"%s\" not found: %s\n"),
|
||||||
sl->d, g10_errstr (G10ERR_INV_USER_ID));
|
sl->d, gpg_strerror (err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
g10/packet.h
18
g10/packet.h
@ -27,6 +27,7 @@
|
|||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "../common/openpgpdefs.h"
|
#include "../common/openpgpdefs.h"
|
||||||
|
#include "../common/userids.h"
|
||||||
|
|
||||||
#define DEBUG_PARSE_PACKET 1
|
#define DEBUG_PARSE_PACKET 1
|
||||||
|
|
||||||
@ -151,14 +152,16 @@ typedef struct
|
|||||||
|
|
||||||
#define ATTRIB_IMAGE 1
|
#define ATTRIB_IMAGE 1
|
||||||
|
|
||||||
/* This is the cooked form of attributes */
|
/* This is the cooked form of attributes. */
|
||||||
struct user_attribute {
|
struct user_attribute {
|
||||||
byte type;
|
byte type;
|
||||||
const byte *data;
|
const byte *data;
|
||||||
u32 len;
|
u32 len;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
|
||||||
|
/* (See also keybox-search-desc.h) */
|
||||||
|
struct gpg_pkt_user_id_s
|
||||||
{
|
{
|
||||||
int ref; /* reference counter */
|
int ref; /* reference counter */
|
||||||
int len; /* length of the name */
|
int len; /* length of the name */
|
||||||
@ -181,12 +184,15 @@ typedef struct
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
/* TODO: Move more flags here */
|
/* TODO: Move more flags here */
|
||||||
unsigned mdc:1;
|
unsigned int mdc:1;
|
||||||
unsigned ks_modify:1;
|
unsigned int ks_modify:1;
|
||||||
unsigned compacted:1;
|
unsigned int compacted:1;
|
||||||
} flags;
|
} flags;
|
||||||
char name[1];
|
char name[1];
|
||||||
} PKT_user_id;
|
};
|
||||||
|
typedef struct gpg_pkt_user_id_s PKT_user_id;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct revoke_info
|
struct revoke_info
|
||||||
{
|
{
|
||||||
|
@ -787,7 +787,7 @@ find_and_check_key (const char *name, unsigned int use,
|
|||||||
int trustlevel;
|
int trustlevel;
|
||||||
|
|
||||||
if (!name || !*name)
|
if (!name || !*name)
|
||||||
return gpg_error (GPG_ERR_INV_NAME);
|
return gpg_error (GPG_ERR_INV_USER_ID);
|
||||||
|
|
||||||
pk = xtrycalloc (1, sizeof *pk);
|
pk = xtrycalloc (1, sizeof *pk);
|
||||||
if (!pk)
|
if (!pk)
|
||||||
|
10
g10/revoke.c
10
g10/revoke.c
@ -220,8 +220,9 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
|
|||||||
afx = new_armor_context ();
|
afx = new_armor_context ();
|
||||||
|
|
||||||
kdbhd = keydb_new (0);
|
kdbhd = keydb_new (0);
|
||||||
classify_user_id (uname, &desc);
|
rc = classify_user_id (uname, &desc);
|
||||||
rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
|
if (!rc)
|
||||||
|
rc = keydb_search (kdbhd, &desc, 1);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
log_error (_("key \"%s\" not found: %s\n"),uname, g10_errstr (rc));
|
log_error (_("key \"%s\" not found: %s\n"),uname, g10_errstr (rc));
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -463,8 +464,9 @@ gen_revoke( const char *uname )
|
|||||||
* We don't want the whole getkey stuff here but the entire keyblock
|
* We don't want the whole getkey stuff here but the entire keyblock
|
||||||
*/
|
*/
|
||||||
kdbhd = keydb_new (1);
|
kdbhd = keydb_new (1);
|
||||||
classify_user_id (uname, &desc);
|
rc = classify_user_id (uname, &desc);
|
||||||
rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
|
if (!rc)
|
||||||
|
rc = keydb_search (kdbhd, &desc, 1);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error (_("secret key \"%s\" not found: %s\n"),
|
log_error (_("secret key \"%s\" not found: %s\n"),
|
||||||
|
@ -214,9 +214,11 @@ register_trusted_keyid(u32 *keyid)
|
|||||||
void
|
void
|
||||||
register_trusted_key( const char *string )
|
register_trusted_key( const char *string )
|
||||||
{
|
{
|
||||||
|
gpg_error_t err;
|
||||||
KEYDB_SEARCH_DESC desc;
|
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 );
|
log_error(_("`%s' is not a valid long keyID\n"), string );
|
||||||
return;
|
return;
|
||||||
|
@ -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>
|
2008-12-09 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* kbxutil.c (main): Call i18n_init before init_common_subsystems.
|
* kbxutil.c (main): Call i18n_init before init_common_subsystems.
|
||||||
|
@ -48,24 +48,31 @@ typedef enum {
|
|||||||
KEYDB_SEARCH_MODE_NEXT
|
KEYDB_SEARCH_MODE_NEXT
|
||||||
} KeydbSearchMode;
|
} 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;
|
KeydbSearchMode mode;
|
||||||
int (*skipfnc)(void *,void*); /* used to be: void*, u32* */
|
int (*skipfnc)(void *, u32 *, gpg_pkt_user_id_t);
|
||||||
void *skipfncvalue;
|
void *skipfncvalue;
|
||||||
const unsigned char *sn;
|
const unsigned char *sn;
|
||||||
int snlen; /* -1 := sn is a hex string */
|
int snlen; /* -1 := sn is a hex string */
|
||||||
union {
|
union {
|
||||||
const char *name;
|
const char *name;
|
||||||
unsigned char fpr[24];
|
unsigned char fpr[24];
|
||||||
unsigned char kid[8];
|
u32 kid[2]; /* Note that this is in native endianess. */
|
||||||
unsigned char grip[20];
|
unsigned char grip[20];
|
||||||
} u;
|
} u;
|
||||||
|
int exact; /* Use exactly this key ('!' suffix in gpg). */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct keydb_search_desc;
|
struct keydb_search_desc;
|
||||||
typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
|
typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
|
||||||
|
|
||||||
typedef struct keydb_search_desc KEYBOX_SEARCH_DESC;
|
typedef struct keydb_search_desc KEYBOX_SEARCH_DESC;
|
||||||
|
|
||||||
|
|
||||||
|
@ -530,15 +530,29 @@ blob_x509_has_grip (KEYBOXBLOB blob, const unsigned char *grip)
|
|||||||
The has_foo functions are used as helpers for search
|
The has_foo functions are used as helpers for search
|
||||||
*/
|
*/
|
||||||
static inline int
|
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
|
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
|
static inline int
|
||||||
@ -877,11 +891,11 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
|
|||||||
goto found;
|
goto found;
|
||||||
break;
|
break;
|
||||||
case KEYDB_SEARCH_MODE_SHORT_KID:
|
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;
|
goto found;
|
||||||
break;
|
break;
|
||||||
case KEYDB_SEARCH_MODE_LONG_KID:
|
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;
|
goto found;
|
||||||
break;
|
break;
|
||||||
case KEYDB_SEARCH_MODE_FPR:
|
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++)
|
for (n=any_skip?0:ndesc; n < ndesc; n++)
|
||||||
{
|
{
|
||||||
/* if (desc[n].skipfnc */
|
/* if (desc[n].skipfnc */
|
||||||
/* && desc[n].skipfnc (desc[n].skipfncvalue, aki)) */
|
/* && desc[n].skipfnc (desc[n].skipfncvalue, aki, NULL)) */
|
||||||
/* break; */
|
/* break; */
|
||||||
}
|
}
|
||||||
if (n == ndesc)
|
if (n == ndesc)
|
||||||
|
@ -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>
|
2009-12-08 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* call-dirmngr.c (start_dirmngr_ext): Convert posix fd to assuan fd.
|
* call-dirmngr.c (start_dirmngr_ext): Convert posix fd to assuan fd.
|
||||||
|
@ -301,7 +301,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
|
|||||||
KEYDB_HANDLE kh = NULL;
|
KEYDB_HANDLE kh = NULL;
|
||||||
ksba_cert_t cert = NULL;
|
ksba_cert_t cert = NULL;
|
||||||
|
|
||||||
rc = keydb_classify_name (name, &desc);
|
rc = classify_user_id (name, &desc);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
kh = keydb_new (0);
|
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;
|
KEYDB_HANDLE kh = NULL;
|
||||||
|
|
||||||
*r_cert = NULL;
|
*r_cert = NULL;
|
||||||
rc = keydb_classify_name (name, &desc);
|
rc = classify_user_id (name, &desc);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
kh = keydb_new (0);
|
kh = keydb_new (0);
|
||||||
|
@ -45,7 +45,7 @@ delete_one (ctrl_t ctrl, const char *username)
|
|||||||
int duplicates = 0;
|
int duplicates = 0;
|
||||||
int is_ephem = 0;
|
int is_ephem = 0;
|
||||||
|
|
||||||
rc = keydb_classify_name (username, &desc);
|
rc = classify_user_id (username, &desc);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error (_("certificate `%s' not found: %s\n"),
|
log_error (_("certificate `%s' not found: %s\n"),
|
||||||
|
@ -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)
|
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)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error ("key `%s' not found: %s\n",
|
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;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = keydb_classify_name (name, desc);
|
rc = classify_user_id (name, desc);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error ("key `%s' not found: %s\n",
|
log_error ("key `%s' not found: %s\n",
|
||||||
|
@ -452,7 +452,7 @@ reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
|
|||||||
|
|
||||||
stats->count++;
|
stats->count++;
|
||||||
|
|
||||||
err = keydb_classify_name (line, &desc);
|
err = classify_user_id (line, &desc);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
print_import_problem (ctrl, NULL, 0);
|
print_import_problem (ctrl, NULL, 0);
|
||||||
|
284
sm/keydb.c
284
sm/keydb.c
@ -949,8 +949,8 @@ keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
|
|||||||
|
|
||||||
memset (&desc, 0, sizeof desc);
|
memset (&desc, 0, sizeof desc);
|
||||||
desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
|
desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||||
/* desc.u.kid[0] = kid[0]; */
|
desc.u.kid[0] = kid[0];
|
||||||
/* desc.u.kid[1] = kid[1]; */
|
desc.u.kid[1] = kid[1];
|
||||||
return keydb_search (hd, &desc, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Store the certificate in the key DB but make sure that it does not
|
/* Store the certificate in the key DB but make sure that it does not
|
||||||
already exists. We do this simply by comparing the fingerprint.
|
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)
|
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)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error ("key `%s' not found: %s\n",
|
log_error ("key `%s' not found: %s\n",
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include <ksba.h>
|
#include <ksba.h>
|
||||||
|
|
||||||
#include "../kbx/keybox-search-desc.h"
|
#include "../common/userids.h"
|
||||||
|
|
||||||
typedef struct keydb_handle *KEYDB_HANDLE;
|
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);
|
const char *issuer, const unsigned char *serial);
|
||||||
int keydb_search_subject (KEYDB_HANDLE hd, const char *issuer);
|
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);
|
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,
|
gpg_error_t keydb_set_cert_flags (ksba_cert_t cert, int ephemeral,
|
||||||
int which, int idx,
|
int which, int idx,
|
||||||
|
@ -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)
|
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)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error ("key `%s' not found: %s\n",
|
log_error ("key `%s' not found: %s\n",
|
||||||
|
@ -209,7 +209,7 @@ get_default_signer (ctrl_t ctrl)
|
|||||||
return cert;
|
return cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = keydb_classify_name (opt.local_user, &desc);
|
rc = classify_user_id (opt.local_user, &desc);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error ("failed to find default signer: %s\n", gpg_strerror (rc));
|
log_error ("failed to find default signer: %s\n", gpg_strerror (rc));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user