gpg: Set the node flags while retrieving a keyblock.

* g10/keydb.c (parse_keyblock_image): Add args PK_NO and UID_NO and
set the note flags accordingly.
(keydb_get_keyblock): Transfer PK_NO and UID_NO to parse_keyblock_image.
* kbx/keybox-search.c (blob_cmp_fpr, blob_cmp_fpr_part)
(blob_cmp_name, blob_cmp_mail): Return the key/user number.
(keybox_search): Set the key and user number into the found struct.
(keybox_get_keyblock): Add args R_PK_NO and R_UID_NO and set them from
the found struct.
--

getkey.c needs to know whether the correct subkey was found.  Thus we
need to set the node flags the same way we did it with the keyring
storage.
This commit is contained in:
Werner Koch 2013-01-07 21:14:52 +01:00
parent 0baedfd25a
commit f6d7b3f1ee
3 changed files with 72 additions and 26 deletions

View File

@ -1,6 +1,6 @@
/* keydb.c - key database dispatcher
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
* 2008, 2009, 2011 Free Software Foundation, Inc.
* 2008, 2009, 2011, 2013 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -617,7 +617,8 @@ unlock_all (KEYDB_HANDLE hd)
static gpg_error_t
parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock)
parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
const u32 *sigstatus, kbnode_t *r_keyblock)
{
gpg_error_t err;
PACKET *pkt;
@ -625,6 +626,7 @@ parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock)
kbnode_t node, *tail;
int in_cert, save_mode;
u32 n_sigs;
int pk_count, uid_count;
*r_keyblock = NULL;
@ -636,6 +638,7 @@ parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock)
in_cert = 0;
n_sigs = 0;
tail = NULL;
pk_count = uid_count = 0;
while ((err = parse_packet (iobuf, pkt)) != -1)
{
if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET)
@ -714,6 +717,26 @@ parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock)
}
node = new_kbnode (pkt);
switch (pkt->pkttype)
{
case PKT_PUBLIC_KEY:
case PKT_PUBLIC_SUBKEY:
case PKT_SECRET_KEY:
case PKT_SECRET_SUBKEY:
if (++pk_count == pk_no)
node->flag |= 1;
break;
case PKT_USER_ID:
if (++uid_count == uid_no)
node->flag |= 2;
break;
default:
break;
}
if (!keyblock)
keyblock = node;
else
@ -779,12 +802,14 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
{
iobuf_t iobuf;
u32 *sigstatus;
int pk_no, uid_no;
err = keybox_get_keyblock (hd->active[hd->found].u.kb,
&iobuf, &sigstatus);
&iobuf, &pk_no, &uid_no, &sigstatus);
if (!err)
{
err = parse_keyblock_image (iobuf, sigstatus, ret_kb);
err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus,
ret_kb);
xfree (sigstatus);
iobuf_close (iobuf);
}

View File

@ -1,5 +1,6 @@
/* keybox-search.c - Search operations
* Copyright (C) 2001, 2002, 2003, 2004, 2012 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2003, 2004, 2012,
* 2013 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -233,6 +234,9 @@ blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
}
/* Returns 0 if not found or the number of the key which was found.
For X.509 this is always 1, for OpenPGP this is 1 for the primary
key and 2 and more for the subkeys. */
static int
blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr)
{
@ -259,7 +263,7 @@ blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr)
{
off = pos + idx*keyinfolen;
if (!memcmp (buffer + off, fpr, 20))
return 1; /* found */
return idx+1; /* found */
}
return 0; /* not found */
}
@ -291,7 +295,7 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
{
off = pos + idx*keyinfolen;
if (!memcmp (buffer + off + fproff, fpr, fprlen))
return 1; /* found */
return idx+1; /* found */
}
return 0; /* not found */
}
@ -352,15 +356,14 @@ blob_cmp_name (KEYBOXBLOB blob, int idx,
if (substr)
{
if (ascii_memcasemem (buffer+off, len, name, namelen))
return 1; /* found */
return idx+1; /* found */
}
else
{
if (len == namelen && !memcmp (buffer+off, name, len))
return 1; /* found */
return idx+1; /* found */
}
}
return 0; /* not found */
}
else
{
@ -376,13 +379,16 @@ blob_cmp_name (KEYBOXBLOB blob, int idx,
if (substr)
{
return !!ascii_memcasemem (buffer+off, len, name, namelen);
if (ascii_memcasemem (buffer+off, len, name, namelen))
return idx+1; /* found */
}
else
{
return len == namelen && !memcmp (buffer+off, name, len);
if (len == namelen && !memcmp (buffer+off, name, len))
return idx+1; /* found */
}
}
return 0; /* not found */
}
@ -458,12 +464,12 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr,
if (substr)
{
if (ascii_memcasemem (buffer+off+1, len, name, namelen))
return 1; /* found */
return idx+1; /* found */
}
else
{
if (len == namelen && !ascii_memcasecmp (buffer+off+1, name, len))
return 1; /* found */
return idx+1; /* found */
}
}
return 0; /* not found */
@ -734,6 +740,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
int need_words, any_skip;
KEYBOXBLOB blob = NULL;
struct sn_array_s *sn_array = NULL;
int pk_no, uid_no;
if (!hd)
return gpg_error (GPG_ERR_INV_VALUE);
@ -850,6 +857,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
}
pk_no = uid_no = 0;
for (;;)
{
unsigned int blobflags;
@ -875,19 +883,23 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
never_reached ();
break;
case KEYDB_SEARCH_MODE_EXACT:
if (has_username (blob, desc[n].u.name, 0))
uid_no = has_username (blob, desc[n].u.name, 0);
if (uid_no)
goto found;
break;
case KEYDB_SEARCH_MODE_MAIL:
if (has_mail (blob, desc[n].u.name, 0))
uid_no = has_mail (blob, desc[n].u.name, 0);
if (uid_no)
goto found;
break;
case KEYDB_SEARCH_MODE_MAILSUB:
if (has_mail (blob, desc[n].u.name, 1))
uid_no = has_mail (blob, desc[n].u.name, 1);
if (uid_no)
goto found;
break;
case KEYDB_SEARCH_MODE_SUBSTR:
if (has_username (blob, desc[n].u.name, 1))
uid_no = has_username (blob, desc[n].u.name, 1);
if (uid_no)
goto found;
break;
case KEYDB_SEARCH_MODE_MAILEND:
@ -914,16 +926,19 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
goto found;
break;
case KEYDB_SEARCH_MODE_SHORT_KID:
if (has_short_kid (blob, desc[n].u.kid[1]))
pk_no = has_short_kid (blob, desc[n].u.kid[1]);
if (pk_no)
goto found;
break;
case KEYDB_SEARCH_MODE_LONG_KID:
if (has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]))
pk_no = has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]);
if (pk_no)
goto found;
break;
case KEYDB_SEARCH_MODE_FPR:
case KEYDB_SEARCH_MODE_FPR20:
if (has_fingerprint (blob, desc[n].u.fpr))
pk_no = has_fingerprint (blob, desc[n].u.fpr);
if (pk_no)
goto found;
break;
case KEYDB_SEARCH_MODE_KEYGRIP:
@ -956,6 +971,8 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
if (!rc)
{
hd->found.blob = blob;
hd->found.pk_no = pk_no;
hd->found.uid_no = uid_no;
}
else if (rc == -1)
{
@ -985,9 +1002,12 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
/* Return the last found keyblock. Returns 0 on success and stores a
new iobuf at R_IOBUF and a signature status vector at R_SIGSTATUS
in that case. */
in that case. R_UID_NO and R_PK_NO are used to retun the number of
the key or user id which was matched the search criteria; if not
known they are set to 0. */
gpg_error_t
keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, u32 **r_sigstatus)
keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf,
int *r_pk_no, int *r_uid_no, u32 **r_sigstatus)
{
gpg_error_t err;
const unsigned char *buffer, *p;
@ -1029,6 +1049,8 @@ keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, u32 **r_sigstatus)
for (n=1; n <= n_sigs; n++, p += sigilen)
sigstatus[n] = get32 (p);
*r_pk_no = hd->found.pk_no;
*r_uid_no = hd->found.uid_no;
*r_sigstatus = sigstatus;
*r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len);
return 0;

View File

@ -81,8 +81,8 @@ int keybox_lock (KEYBOX_HANDLE hd, int yes);
int _keybox_write_header_blob (FILE *fp);
/*-- keybox-search.c --*/
gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd,
iobuf_t *r_iobuf, u32 **sigstatus);
gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf,
int *r_uid_no, int *r_pk_no, u32 **sigstatus);
#ifdef KEYBOX_WITH_X509
int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert);
#endif /*KEYBOX_WITH_X509*/
@ -114,7 +114,6 @@ int keybox_compress (KEYBOX_HANDLE hd);
/*-- --*/
#if 0
int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb);
int keybox_locate_writable (KEYBOX_HANDLE hd);
int keybox_search_reset (KEYBOX_HANDLE hd);
int keybox_search (KEYBOX_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc);