From 2ca90f78cee91c43b8d538d1cb92728f8e1452d5 Mon Sep 17 00:00:00 2001 From: Werner Koch <wk@gnupg.org> Date: Thu, 9 Oct 2014 21:01:49 +0200 Subject: [PATCH] gpg: Skip overlong keys and a print a warning. * kbx/keybox-search.c (keybox_search): Add arg r_skipped and skip too long blobs. * sm/keydb.c (keydb_search): Call keybox_search with a dummy param. * g10/keydb.c (struct keydb_handle): Add field skipped_long_blobs. (keydb_search_reset): Reset that field. (keydb_search): Update that field. (keydb_get_skipped_counter): New. * g10/keylist.c (list_all): Print count of skipped keys. Signed-off-by: Werner Koch <wk@gnupg.org> --- g10/keydb.c | 11 ++++++++++- g10/keydb.h | 1 + g10/keylist.c | 3 +++ kbx/keybox-search.c | 13 +++++++++++-- kbx/keybox.h | 2 +- sm/keydb.c | 4 +++- 6 files changed, 29 insertions(+), 5 deletions(-) diff --git a/g10/keydb.c b/g10/keydb.c index a38795120..a9a975378 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -67,6 +67,7 @@ struct keydb_handle { int locked; int found; + unsigned long skipped_long_blobs; int current; int used; /* Number of items in ACTIVE. */ struct resource_item active[MAX_KEYDB_RESOURCES]; @@ -1289,6 +1290,13 @@ keydb_rebuild_caches (int noisy) } +/* Return the number of skipped blocks since the last search reset. */ +unsigned long +keydb_get_skipped_counter (KEYDB_HANDLE hd) +{ + return hd ? hd->skipped_long_blobs : 0; +} + /* * Start the next search on this handle right at the beginning @@ -1307,6 +1315,7 @@ keydb_search_reset (KEYDB_HANDLE hd) if (DBG_CLOCK) log_clock ("keydb_search_reset"); + hd->skipped_long_blobs = 0; hd->current = 0; hd->found = -1; /* Now reset all resources. */ @@ -1424,7 +1433,7 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, break; case KEYDB_RESOURCE_TYPE_KEYBOX: rc = keybox_search (hd->active[hd->current].u.kb, desc, - ndesc, descindex); + ndesc, descindex, &hd->skipped_long_blobs); break; } if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) diff --git a/g10/keydb.h b/g10/keydb.h index 23d0bcc26..78d151a51 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -142,6 +142,7 @@ gpg_error_t keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb); gpg_error_t keydb_delete_keyblock (KEYDB_HANDLE hd); gpg_error_t keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved); void keydb_rebuild_caches (int noisy); +unsigned long keydb_get_skipped_counter (KEYDB_HANDLE hd); gpg_error_t keydb_search_reset (KEYDB_HANDLE hd); gpg_error_t keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc, size_t *descindex); diff --git a/g10/keylist.c b/g10/keylist.c index 4a028205a..b5ea84d1c 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -499,6 +499,9 @@ list_all (int secret, int mark_secret) es_fflush (es_stdout); if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND) log_error ("keydb_search_next failed: %s\n", g10_errstr (rc)); + if (keydb_get_skipped_counter (hd)) + log_info (_("Warning: %lu key(s) skipped due to their large size\n"), + keydb_get_skipped_counter (hd)); if (opt.check_sigs && !opt.with_colons) print_signature_stats (&stats); diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index ba284f9b5..bf47042a3 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -718,10 +718,12 @@ keybox_search_reset (KEYBOX_HANDLE hd) /* Note: When in ephemeral mode the search function does visit all - blobs but in standard mode, blobs flagged as ephemeral are ignored. */ + blobs but in standard mode, blobs flagged as ephemeral are ignored. + The value at R_SKIPPED is updated by the number of skipped long + records (counts PGP and X.509). */ int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, - size_t *r_descindex) + size_t *r_descindex, unsigned long *r_skipped) { int rc; size_t n; @@ -852,6 +854,13 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, _keybox_release_blob (blob); blob = NULL; rc = _keybox_read_blob (&blob, hd->fp); + if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE + && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX) + { + ++*r_skipped; + continue; /* Skip too large records. */ + } + if (rc) break; diff --git a/kbx/keybox.h b/kbx/keybox.h index 9067fb8a4..b44f1b2ba 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -87,7 +87,7 @@ int keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value); int keybox_search_reset (KEYBOX_HANDLE hd); int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, - size_t *r_descindex); + size_t *r_descindex, unsigned long *r_skipped); /*-- keybox-update.c --*/ diff --git a/sm/keydb.c b/sm/keydb.c index fb0947a93..83e573f28 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -958,6 +958,7 @@ int keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) { int rc = -1; + unsigned long skipped; if (!hd) return gpg_error (GPG_ERR_INV_VALUE); @@ -970,7 +971,8 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) BUG(); /* we should never see it here */ break; case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc, NULL); + rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc, + NULL, &skipped); break; } if (rc == -1) /* EOF -> switch to next resource */