diff options
-rw-r--r-- | g10/keydb.c | 19 | ||||
-rw-r--r-- | kbx/keybox-search.c | 8 | ||||
-rw-r--r-- | kbx/keybox.h | 2 |
3 files changed, 28 insertions, 1 deletions
diff --git a/g10/keydb.c b/g10/keydb.c index d7c35deac..860187fde 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -81,6 +81,9 @@ struct keyblock_cache { u32 *sigstatus; int pk_no; int uid_no; + /* Offset of the record in the keybox. */ + int resource; + off_t offset; }; @@ -245,6 +248,8 @@ keyblock_cache_clear (struct keydb_handle *hd) hd->keyblock_cache.sigstatus = NULL; iobuf_close (hd->keyblock_cache.iobuf); hd->keyblock_cache.iobuf = NULL; + hd->keyblock_cache.resource = -1; + hd->keyblock_cache.offset = -1; } @@ -1701,7 +1706,13 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, && (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)) + && !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, 20) + /* Make sure the current file position occurs before the cached + result to avoid an infinite loop. */ + && (hd->current < hd->keyblock_cache.resource + || (hd->current == hd->keyblock_cache.resource + && (keybox_offset (hd->active[hd->current].u.kb) + <= hd->keyblock_cache.offset)))) { /* (DESCINDEX is already set). */ if (DBG_CLOCK) @@ -1772,6 +1783,12 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, && hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYBOX) { hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED; + hd->keyblock_cache.resource = hd->current; + /* The current offset is at the start of the next record. Since + a record is at least 1 byte, we just use offset - 1, which is + 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); } diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index 78e0c23b7..df959b67d 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -1188,3 +1188,11 @@ keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value) ec = get_flag_from_image (buffer, length, what, value); return ec? gpg_error (ec):0; } + +off_t +keybox_offset (KEYBOX_HANDLE hd) +{ + if (!hd->fp) + return 0; + return ftello (hd->fp); +} diff --git a/kbx/keybox.h b/kbx/keybox.h index 8c3114142..c91a28299 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -77,6 +77,8 @@ int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes); int keybox_lock (KEYBOX_HANDLE hd, int yes); +off_t keybox_offset (KEYBOX_HANDLE hd); + /*-- keybox-file.c --*/ /* Fixme: This function does not belong here: Provide a better interface to create a new keybox file. */ |