summaryrefslogtreecommitdiffstats
path: root/g10/keydb.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2019-03-14 08:54:59 +0100
committerWerner Koch <wk@gnupg.org>2019-03-14 11:26:54 +0100
commitf40e9d6a528521d12795e1a6cc15c849b216be92 (patch)
treebebe6f71b5d00e8dda7d67dae3b3f4e27e12a815 /g10/keydb.c
parentgpg: Implemented latest rfc4880bis version 5 packet hashing. (diff)
downloadgnupg2-f40e9d6a528521d12795e1a6cc15c849b216be92.tar.xz
gnupg2-f40e9d6a528521d12795e1a6cc15c849b216be92.zip
kbx: Add support for 32 byte fingerprints.
* common/userids.c (classify_user_id): Support 32 byte fingerprints. * kbx/keybox-search-desc.h (KEYDB_SEARCH_MODE_FPR32): New. (struct keydb_search_desc): Add field fprlen. * kbx/keybox-defs.h (struct _keybox_openpgp_key_info): Add field version and increase size of fpr to 32. * kbx/keybox-blob.c: Define new version 2 for PGP and X509 blobs. (struct keyboxblob_key): Add field fprlen and increase size of fpr. (pgp_create_key_part_single): Allow larger fingerprints. (create_blob_header): Implement blob version 2 and add arg want_fpr32. (_keybox_create_openpgp_blob): Detect the need for blob version 2. * kbx/keybox-search.c (blob_get_first_keyid): Support 32 byte fingerprints. (blob_cmp_fpr): Ditto. (blob_cmp_fpr_part): Ditto. (has_fingerprint): Add arg fprlen and pass on. (keybox_search): Support KEYDB_SEARCH_MODE_FPR32 and adjust for changed has_fingerprint. * kbx/keybox-openpgp.c (parse_key): Support version 5 keys. * kbx/keybox-dump.c (_keybox_dump_blob): Support blob version 2. * g10/delkey.c (do_delete_key): Support KEYDB_SEARCH_MODE_FPR32. * g10/export.c (exact_subkey_match_p): Ditto. * g10/gpg.c (main): Ditto. * g10/getkey.c (get_pubkey_byfprint): Adjust for changed KEYDB_SEARCH_MODE_FPR. * g10/keydb.c (keydb_search_desc_dump): Support KEYDB_SEARCH_MODE_FPR32 and adjust for changed KEYDB_SEARCH_MODE_FPR. (keydb_search): Add new arg fprlen and change all callers. * g10/keyedit.c (find_by_primary_fpr): Ditto. * g10/keyid.c (keystr_from_desc): Ditto. * g10/keyring.c (keyring_search): Ditto. * g10/keyserver.c (print_keyrec): Ditto. (parse_keyrec): Ditto. (keyserver_export): Ditto. (keyserver_retrieval_screener): Ditto. (keyserver_import): Ditto. (keyserver_import_fprint): Ditto. (keyidlist): Ditto. (keyserver_get_chunk): Ditto. * g10/keydb.c (keydb_search): Add new arg fprlen and change all callers. * sm/keydb.c (keydb_search_fpr): Adjust for changed KEYDB_SEARCH_MODE_FPR. -- This prepares the support for OpenPGP v5 keys. The new version 2 blob format is needed for the longer fingerprints and we also use this opportunity to prepare for storing the keygrip in the blob for faster lookup by keygrip. Right now this is not yet functional. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'g10/keydb.c')
-rw-r--r--g10/keydb.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/g10/keydb.c b/g10/keydb.c
index 03fadfd54..6ecb4eb8b 100644
--- a/g10/keydb.c
+++ b/g10/keydb.c
@@ -81,6 +81,7 @@ enum keyblock_cache_states {
struct keyblock_cache {
enum keyblock_cache_states state;
byte fpr[MAX_FINGERPRINT_LEN];
+ byte fprlen;
iobuf_t iobuf; /* Image of the keyblock. */
int pk_no;
int uid_no;
@@ -566,8 +567,12 @@ keydb_search_desc_dump (struct keydb_search_desc *desc)
bin2hex (desc->u.fpr, 20, fpr);
return xasprintf ("FPR20: '%s'",
format_hexfingerprint (fpr, b, sizeof (b)));
- case KEYDB_SEARCH_MODE_FPR:
+ case KEYDB_SEARCH_MODE_FPR32:
bin2hex (desc->u.fpr, 20, fpr);
+ return xasprintf ("FPR32: '%s'",
+ format_hexfingerprint (fpr, b, sizeof (b)));
+ case KEYDB_SEARCH_MODE_FPR:
+ bin2hex (desc->u.fpr, desc->fprlen, fpr);
return xasprintf ("FPR: '%s'",
format_hexfingerprint (fpr, b, sizeof (b)));
case KEYDB_SEARCH_MODE_ISSUER:
@@ -1531,6 +1536,8 @@ keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
fingerprint_from_pk (pk, desc.u.fpr, &len);
if (len == 20)
desc.mode = KEYDB_SEARCH_MODE_FPR20;
+ else if (len == 32)
+ desc.mode = KEYDB_SEARCH_MODE_FPR32;
else
log_bug ("%s: Unsupported key length: %zu\n", __func__, len);
@@ -1862,6 +1869,7 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
int was_reset = hd->is_reset;
/* If an entry is already in the cache, then don't add it again. */
int already_in_cache = 0;
+ int fprlen;
if (descindex)
*descindex = 0; /* Make sure it is always set on return. */
@@ -1902,12 +1910,21 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
/* NB: If one of the exact search modes below is used in a loop to
walk over all keys (with the same fingerprint) the caching must
have been disabled for the handle. */
+ if (desc[0].mode == KEYDB_SEARCH_MODE_FPR20)
+ fprlen = 20;
+ else if (desc[0].mode == KEYDB_SEARCH_MODE_FPR32)
+ fprlen = 32;
+ else if (desc[0].mode == KEYDB_SEARCH_MODE_FPR)
+ fprlen = desc[0].fprlen;
+ else
+ fprlen = 0;
+
if (!hd->no_caching
&& ndesc == 1
- && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
- || desc[0].mode == KEYDB_SEARCH_MODE_FPR)
- && hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED
- && !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, 20)
+ && fprlen
+ && hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED
+ && hd->keyblock_cache.fprlen == fprlen
+ && !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, fprlen)
/* Make sure the current file position occurs before the cached
result to avoid an infinite loop. */
&& (hd->current < hd->keyblock_cache.resource
@@ -1922,8 +1939,7 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
hd->current = hd->keyblock_cache.resource;
/* HD->KEYBLOCK_CACHE.OFFSET is the last byte in the record.
Seek just beyond that. */
- keybox_seek (hd->active[hd->current].u.kb,
- hd->keyblock_cache.offset + 1);
+ keybox_seek (hd->active[hd->current].u.kb, hd->keyblock_cache.offset + 1);
keydb_stats.found_cached++;
return 0;
}
@@ -1986,8 +2002,8 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
keyblock_cache_clear (hd);
if (!hd->no_caching
&& !rc
- && ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
- || desc[0].mode == KEYDB_SEARCH_MODE_FPR)
+ && ndesc == 1
+ && fprlen
&& hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYBOX)
{
hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
@@ -1997,11 +2013,14 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
within the record. */
hd->keyblock_cache.offset
= keybox_offset (hd->active[hd->current].u.kb) - 1;
- memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, 20);
+ memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, fprlen);
+ hd->keyblock_cache.fprlen = fprlen;
}
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND
- && ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID && was_reset
+ && ndesc == 1
+ && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID
+ && was_reset
&& !already_in_cache)
kid_not_found_insert (desc[0].u.kid);
@@ -2078,12 +2097,13 @@ keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
* off. If you want to search the whole database, then you need to
* first call keydb_search_reset(). */
gpg_error_t
-keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
+keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr, size_t fprlen)
{
KEYDB_SEARCH_DESC desc;
memset (&desc, 0, sizeof desc);
desc.mode = KEYDB_SEARCH_MODE_FPR;
- memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
+ memcpy (desc.u.fpr, fpr, fprlen);
+ desc.fprlen = fprlen;
return keydb_search (hd, &desc, 1, NULL);
}