From 58e4a492e2c8e908d16135486ed601f602f1e38d Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Tue, 17 Nov 2015 14:38:03 +0100 Subject: [PATCH] gpg: Change keydb_search to not return legacy keys. * g10/keyring.c (keyring_search): Take new argument, ignore_legacy. If set, skip any legacy keys. Update callers. * g10/keydb.c (keydb_search): Skip any legacy keys. (keydb_search_first): Don't skip legacy keys. Treat them as an error. (keydb_search_next): Likewise. (keydb_search_fpr): Likewise. * g10/export.c (do_export_stream): Likewise. * g10/getkey.c (lookup): Likewise. (have_secret_key_with_kid): Likewise. * g10/keylist.c (list_all): Likewise. (keyring_rebuild_cache): Likewise. * g10/keyserver.c (keyidlist): Likewise. * g10/trustdb.c (validate_key_list): Likewise. -- Signed-off-by: Neal H. Walfield --- g10/export.c | 4 ---- g10/getkey.c | 47 ++--------------------------------------------- g10/keydb.c | 37 +++++++++++-------------------------- g10/keydb.h | 5 +++-- g10/keyring.c | 20 +++++++++++++++----- g10/keyring.h | 2 +- g10/keyserver.c | 7 +------ g10/trustdb.c | 6 +----- 8 files changed, 34 insertions(+), 94 deletions(-) diff --git a/g10/export.c b/g10/export.c index 3c2aa5745..1d71c1c46 100644 --- a/g10/export.c +++ b/g10/export.c @@ -940,8 +940,6 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, err = keydb_search (kdbhd, desc, ndesc, &descindex); if (!users) desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - if (gpg_err_code (err) == GPG_ERR_LEGACY_KEY) - continue; /* Skip PGP2 keys. */ if (err) break; @@ -949,8 +947,6 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, release_kbnode (keyblock); keyblock = NULL; err = keydb_get_keyblock (kdbhd, &keyblock); - if (gpg_err_code (err) == GPG_ERR_LEGACY_KEY) - continue; /* Skip PGP2 keys. */ if (err) { log_error (_("error reading keyblock: %s\n"), gpg_strerror (err)); diff --git a/g10/getkey.c b/g10/getkey.c index dd6820be2..88d8c65a6 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -2679,29 +2679,6 @@ found: } -/* Return true if all the search modes are fingerprints. */ -static int -search_modes_are_fingerprint (getkey_ctx_t ctx) -{ - size_t n, found; - - for (n=found=0; n < ctx->nitems; n++) - { - switch (ctx->items[n].mode) - { - case KEYDB_SEARCH_MODE_FPR16: - case KEYDB_SEARCH_MODE_FPR20: - case KEYDB_SEARCH_MODE_FPR: - found++; - break; - default: - break; - } - } - return found && found == ctx->nitems; -} - - /* A high-level function to lookup keys. This function builds on top of the low-level keydb API. It first @@ -2709,10 +2686,6 @@ search_modes_are_fingerprint (getkey_ctx_t ctx) then it filters the results using CTX and, finally, if WANT_SECRET is set, it ignores any keys for which no secret key is available. - Note: this function skips any legacy keys unless the search mode is - KEYDB_SEARCH_MODE_FIRST or KEYDB_SEARCH_MODE_NEXT or we are - searching by fingerprint. - Unlike the low-level search functions, this function also merges all of the self-signed data into the keys, subkeys and user id packets (see the merge_selfsigs for details). @@ -2730,18 +2703,6 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key, for (;;) { rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems, NULL); - - /* Skip over all legacy keys unless we are iterating over all - keys in the DB or the key was requested by its fingerprint. - - Fixme: The lower level keydb code should actually do that but - then it would be harder to report the number of skipped - legacy keys during import. */ - if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY - && !(ctx->nitems && (ctx->items->mode == KEYDB_SEARCH_MODE_FIRST - || ctx->items->mode == KEYDB_SEARCH_MODE_NEXT)) - && !search_modes_are_fingerprint (ctx)) - continue; if (rc) break; @@ -2789,8 +2750,7 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key, } found: - if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND - && gpg_err_code (rc) != GPG_ERR_LEGACY_KEY) + if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND) log_error ("keydb_search failed: %s\n", gpg_strerror (rc)); if (!rc) @@ -2798,8 +2758,7 @@ found: *ret_keyblock = keyblock; /* Return the keyblock. */ keyblock = NULL; } - else if ((gpg_err_code (rc) == GPG_ERR_NOT_FOUND - || gpg_err_code (rc) == GPG_ERR_LEGACY_KEY) && no_suitable_key) + else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND && no_suitable_key) rc = want_secret? GPG_ERR_UNUSABLE_SECKEY : GPG_ERR_UNUSABLE_PUBKEY; else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND) rc = want_secret? GPG_ERR_NO_SECKEY : GPG_ERR_NO_PUBKEY; @@ -3207,8 +3166,6 @@ have_secret_key_with_kid (u32 *keyid) while (!result) { err = keydb_search (kdbhd, &desc, 1, NULL); - if (gpg_err_code (err) == GPG_ERR_LEGACY_KEY) - continue; if (err) break; diff --git a/g10/keydb.c b/g10/keydb.c index 40fb4c753..8a689809a 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -1708,12 +1708,14 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, break; case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_search (hd->active[hd->current].u.kr, desc, - ndesc, descindex); + ndesc, descindex, 1); break; case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_search (hd->active[hd->current].u.kb, desc, - ndesc, KEYBOX_BLOBTYPE_PGP, - descindex, &hd->skipped_long_blobs); + do + rc = keybox_search (hd->active[hd->current].u.kb, desc, + ndesc, KEYBOX_BLOBTYPE_PGP, + descindex, &hd->skipped_long_blobs); + while (rc == GPG_ERR_LEGACY_KEY); break; } @@ -1776,28 +1778,18 @@ keydb_search_first (KEYDB_HANDLE hd) memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_FIRST; - err = keydb_search (hd, &desc, 1, NULL); - if (gpg_err_code (err) == GPG_ERR_LEGACY_KEY) - err = keydb_search_next (hd); - return err; + return keydb_search (hd, &desc, 1, NULL); } gpg_error_t keydb_search_next (KEYDB_HANDLE hd) { - gpg_error_t err; KEYDB_SEARCH_DESC desc; - do - { - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_NEXT; - err = keydb_search (hd, &desc, 1, NULL); - } - while (gpg_err_code (err) == GPG_ERR_LEGACY_KEY); - - return err; + memset (&desc, 0, sizeof desc); + desc.mode = KEYDB_SEARCH_MODE_NEXT; + return keydb_search (hd, &desc, 1, NULL); } gpg_error_t @@ -1815,17 +1807,10 @@ keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) gpg_error_t keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr) { - gpg_error_t err; KEYDB_SEARCH_DESC desc; memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_FPR; memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN); - do - { - err = keydb_search (hd, &desc, 1, NULL); - } - while (gpg_err_code (err) == GPG_ERR_LEGACY_KEY); - - return err; + return keydb_search (hd, &desc, 1, NULL); } diff --git a/g10/keydb.h b/g10/keydb.h index 203c7ecbf..1848316b9 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -296,7 +296,8 @@ unsigned long keydb_get_skipped_counter (KEYDB_HANDLE hd); (Currently, this function always returns 0 if HD is valid.) */ gpg_error_t keydb_search_reset (KEYDB_HANDLE hd); -/* Search the database for keys matching the search description. +/* Search the database for keys matching the search description. If + the DB contains any legacy keys, these are silently ignored. DESC is an array of search terms with NDESC entries. The search terms are or'd together. That is, the next entry in the DB that @@ -338,7 +339,7 @@ gpg_error_t keydb_search_next (KEYDB_HANDLE hd); gpg_error_t keydb_search_kid (KEYDB_HANDLE hd, u32 *kid); /* This is a convenience function for searching for keys with a long - (20 byte) fingerprint. This function ignores legacy keys. + (20 byte) fingerprint. Note: this function resumes searching where the last search left off. If you want to search the whole database, then you need to diff --git a/g10/keyring.c b/g10/keyring.c index cd569fd56..5ebea990b 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -429,7 +429,8 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) } else /* Upper layer needs to handle this. */ - ; + { + } break; } if (rc) { @@ -967,7 +968,7 @@ compare_name (int mode, const char *name, const char *uid, size_t uidlen) */ int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex) + size_t ndesc, size_t *descindex, int ignore_legacy) { int rc; PACKET pkt; @@ -1106,11 +1107,20 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, if (DBG_LOOKUP) log_debug ("%s: %ssearching from start of resource.\n", __func__, scanned_from_start ? "" : "not "); - while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid))) + while (1) { byte afp[MAX_FINGERPRINT_LEN]; size_t an; + rc = search_packet (hd->current.iobuf, &pkt, &offset, need_uid); + if (ignore_legacy && gpg_err_code (rc) == GPG_ERR_LEGACY_KEY) + { + free_packet (&pkt); + continue; + } + if (rc) + break; + if (pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_SECRET_KEY) { main_offset = offset; @@ -1486,8 +1496,8 @@ keyring_rebuild_cache (void *token,int noisy) for (;;) { - rc = keyring_search (hd, &desc, 1, NULL); - if (rc && gpg_err_code (rc) != GPG_ERR_LEGACY_KEY) + rc = keyring_search (hd, &desc, 1, NULL, 0); + if (rc) break; /* ready. */ desc.mode = KEYDB_SEARCH_MODE_NEXT; diff --git a/g10/keyring.h b/g10/keyring.h index d97bd4c21..14d9f426f 100644 --- a/g10/keyring.h +++ b/g10/keyring.h @@ -39,7 +39,7 @@ int keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb); int keyring_delete_keyblock (KEYRING_HANDLE hd); int keyring_search_reset (KEYRING_HANDLE hd); int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex); + size_t ndesc, size_t *descindex, int skip_legacy); int keyring_rebuild_cache (void *token,int noisy); #endif /*GPG_KEYRING_H*/ diff --git a/g10/keyserver.c b/g10/keyserver.c index 72c244a5d..ab0eb627c 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1229,21 +1229,16 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) for (;;) { rc = keydb_search (kdbhd, desc, ndesc, NULL); - if (rc && gpg_err_code (rc) != GPG_ERR_LEGACY_KEY) + if (rc) break; /* ready. */ if (!users) desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY) - continue; - /* read the keyblock */ rc = keydb_get_keyblock (kdbhd, &keyblock ); if( rc ) { - if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY) - continue; log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) ); goto leave; } diff --git a/g10/trustdb.c b/g10/trustdb.c index 943357c1d..386796c68 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1732,9 +1732,6 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust, { PKT_public_key *pk; - if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY) - continue; - rc = keydb_get_keyblock (hd, &keyblock); if (rc) { @@ -1790,8 +1787,7 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust, release_kbnode (keyblock); keyblock = NULL; } - while (!(rc = keydb_search (hd, &desc, 1, NULL)) - || gpg_err_code (rc) == GPG_ERR_LEGACY_KEY); + while (!(rc = keydb_search (hd, &desc, 1, NULL))); if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND) {