summaryrefslogtreecommitdiffstats
path: root/g10/keydb.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2019-09-27 15:44:23 +0200
committerWerner Koch <wk@gnupg.org>2019-09-27 15:44:23 +0200
commit9698761933f7ade732178b45df2a8763e5801763 (patch)
tree5454a013e219a64dfd0feaf701285a65b7cfa431 /g10/keydb.c
parentbuild: Build gpg-pair-tool only when there is newer libgcrypt. (diff)
parentkbx: Fix error code return in keyboxd. (diff)
downloadgnupg2-9698761933f7ade732178b45df2a8763e5801763.tar.xz
gnupg2-9698761933f7ade732178b45df2a8763e5801763.zip
Merge branch 'switch-to-gpgk' into master
-- Resolved Conflicts: * common/asshelp.c: Keep the new code in master for spawing under Windows. * g10/Makefile.am: Keep all new file. * g10/photoid.c: Pass CTRL to pct_expando. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'g10/keydb.c')
-rw-r--r--g10/keydb.c252
1 files changed, 66 insertions, 186 deletions
diff --git a/g10/keydb.c b/g10/keydb.c
index 92e5faae8..aeb62abfc 100644
--- a/g10/keydb.c
+++ b/g10/keydb.c
@@ -37,25 +37,10 @@
#include "keydb.h"
#include "../common/i18n.h"
-static int active_handles;
+#include "keydb-private.h" /* For struct keydb_handle_s */
-typedef enum
- {
- KEYDB_RESOURCE_TYPE_NONE = 0,
- KEYDB_RESOURCE_TYPE_KEYRING,
- KEYDB_RESOURCE_TYPE_KEYBOX
- } KeydbResourceType;
-#define MAX_KEYDB_RESOURCES 40
+static int active_handles;
-struct resource_item
-{
- KeydbResourceType type;
- union {
- KEYRING_HANDLE kr;
- KEYBOX_HANDLE kb;
- } u;
- void *token;
-};
static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
static int used_resources;
@@ -67,74 +52,6 @@ static void *primary_keydb;
/* Whether we have successfully registered any resource. */
static int any_registered;
-/* This is a simple cache used to return the last result of a
- successful fingerprint search. This works only for keybox resources
- because (due to lack of a copy_keyblock function) we need to store
- an image of the keyblock which is fortunately instantly available
- for keyboxes. */
-enum keyblock_cache_states {
- KEYBLOCK_CACHE_EMPTY,
- KEYBLOCK_CACHE_PREPARED,
- KEYBLOCK_CACHE_FILLED
-};
-
-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;
- /* Offset of the record in the keybox. */
- int resource;
- off_t offset;
-};
-
-
-struct keydb_handle
-{
- /* When we locked all of the resources in ACTIVE (using keyring_lock
- / keybox_lock, as appropriate). */
- int locked;
-
- /* If this flag is set a lock will only be released by
- * keydb_release. */
- int keep_lock;
-
- /* The index into ACTIVE of the resources in which the last search
- result was found. Initially -1. */
- int found;
-
- /* Initially -1 (invalid). This is used to save a search result and
- later restore it as the selected result. */
- int saved_found;
-
- /* The number of skipped long blobs since the last search
- (keydb_search_reset). */
- unsigned long skipped_long_blobs;
-
- /* If set, this disables the use of the keyblock cache. */
- int no_caching;
-
- /* Whether the next search will be from the beginning of the
- database (and thus consider all records). */
- int is_reset;
-
- /* The "file position." In our case, this is index of the current
- resource in ACTIVE. */
- int current;
-
- /* The number of resources in ACTIVE. */
- int used;
-
- /* Cache of the last found and parsed key block (only used for
- keyboxes, not keyrings). */
- struct keyblock_cache keyblock_cache;
-
- /* Copy of ALL_RESOURCES when keydb_new is called. */
- struct resource_item active[MAX_KEYDB_RESOURCES];
-};
-
/* Looking up keys is expensive. To hide the cost, we cache whether
keys exist in the key database. Then, if we know a key does not
exist, we don't have to spend time looking it up. This
@@ -273,7 +190,7 @@ kid_not_found_flush (void)
static void
-keyblock_cache_clear (struct keydb_handle *hd)
+keyblock_cache_clear (struct keydb_handle_s *hd)
{
hd->keyblock_cache.state = KEYBLOCK_CACHE_EMPTY;
iobuf_close (hd->keyblock_cache.iobuf);
@@ -448,7 +365,7 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
rc = gpg_error_from_syserror ();
else
{
- rc = _keybox_write_header_blob (fp, 1);
+ rc = _keybox_write_header_blob (fp, NULL, 1);
fclose (fp);
}
if (rc)
@@ -539,6 +456,10 @@ keydb_search_desc_dump (struct keydb_search_desc *desc)
char b[MAX_FORMATTED_FINGERPRINT_LEN + 1];
char fpr[2 * MAX_FINGERPRINT_LEN + 1];
+#if MAX_FINGERPRINT_LEN < 20
+#error MAX_FINGERPRINT_LEN shorter than GRIP and UBID length/
+#endif
+
switch (desc->mode)
{
case KEYDB_SEARCH_MODE_EXACT:
@@ -578,7 +499,11 @@ keydb_search_desc_dump (struct keydb_search_desc *desc)
case KEYDB_SEARCH_MODE_SUBJECT:
return xasprintf ("SUBJECT: '%s'", desc->u.name);
case KEYDB_SEARCH_MODE_KEYGRIP:
- return xasprintf ("KEYGRIP: %s", desc->u.grip);
+ bin2hex (desc[0].u.grip, 20, fpr);
+ return xasprintf ("KEYGRIP: %s", fpr);
+ case KEYDB_SEARCH_MODE_UBID:
+ bin2hex (desc[0].u.ubid, 20, fpr);
+ return xasprintf ("UBID: %s", fpr);
case KEYDB_SEARCH_MODE_FIRST:
return xasprintf ("FIRST");
case KEYDB_SEARCH_MODE_NEXT:
@@ -888,26 +813,17 @@ keydb_dump_stats (void)
}
-/* Create a new database handle. A database handle is similar to a
- file handle: it contains a local file position. This is used when
- searching: subsequent searches resume where the previous search
- left off. To rewind the position, use keydb_search_reset(). This
- function returns NULL on error, sets ERRNO, and prints an error
- diagnostic. */
-KEYDB_HANDLE
-keydb_new (void)
+/* keydb_new diverts to here in non-keyboxd mode. HD is just the
+ * calloced structure with the handle type intialized. */
+gpg_error_t
+internal_keydb_init (KEYDB_HANDLE hd)
{
- KEYDB_HANDLE hd;
+ gpg_error_t err = 0;
int i, j;
int die = 0;
int reterrno;
- if (DBG_CLOCK)
- log_clock ("keydb_new");
-
- hd = xtrycalloc (1, sizeof *hd);
- if (!hd)
- goto leave;
+ log_assert (!hd->use_keyboxd);
hd->found = -1;
hd->saved_found = -1;
hd->is_reset = 1;
@@ -949,28 +865,21 @@ keydb_new (void)
keydb_stats.handles++;
if (die)
- {
- keydb_release (hd);
- gpg_err_set_errno (reterrno);
- hd = NULL;
- }
-
- leave:
- if (!hd)
- log_error (_("error opening key DB: %s\n"),
- gpg_strerror (gpg_error_from_syserror()));
+ err = gpg_error_from_errno (reterrno);
- return hd;
+ return err;
}
+/* Free all non-keyboxd resources owned by the database handle.
+ * keydb_release diverts to here. */
void
-keydb_release (KEYDB_HANDLE hd)
+internal_keydb_deinit (KEYDB_HANDLE hd)
{
int i;
- if (!hd)
- return;
+ log_assert (!hd->use_keyboxd);
+
log_assert (active_handles > 0);
active_handles--;
@@ -992,19 +901,17 @@ keydb_release (KEYDB_HANDLE hd)
}
keyblock_cache_clear (hd);
- xfree (hd);
}
/* Take a lock on the files immediately and not only during insert or
* update. This lock is released with keydb_release. */
gpg_error_t
-keydb_lock (KEYDB_HANDLE hd)
+internal_keydb_lock (KEYDB_HANDLE hd)
{
gpg_error_t err;
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
+ log_assert (!hd->use_keyboxd);
err = lock_all (hd);
if (!err)
@@ -1020,7 +927,7 @@ keydb_lock (KEYDB_HANDLE hd)
void
keydb_disable_caching (KEYDB_HANDLE hd)
{
- if (hd)
+ if (hd && !hd->use_keyboxd)
hd->no_caching = 1;
}
@@ -1042,6 +949,9 @@ keydb_get_resource_name (KEYDB_HANDLE hd)
if (!hd)
return NULL;
+ if (!hd->use_keyboxd)
+ return "[keyboxd]";
+
if ( hd->found >= 0 && hd->found < hd->used)
idx = hd->found;
else if ( hd->current >= 0 && hd->current < hd->used)
@@ -1165,6 +1075,8 @@ unlock_all (KEYDB_HANDLE hd)
* Note: it is only possible to save a single save state at a time.
* In other words, the save stack only has room for a single
* instance of the state. */
+/* FIXME(keyboxd): This function is used only at one place - see how
+ * we can avoid it. */
void
keydb_push_found_state (KEYDB_HANDLE hd)
{
@@ -1196,6 +1108,8 @@ keydb_push_found_state (KEYDB_HANDLE hd)
/* Restore the previous save state. If the saved state is NULL or
invalid, this is a NOP. */
+/* FIXME(keyboxd): This function is used only at one place - see how
+ * we can avoid it. */
void
keydb_pop_found_state (KEYDB_HANDLE hd)
{
@@ -1360,6 +1274,7 @@ parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
/* Return the keyblock last found by keydb_search() in *RET_KB.
+ * keydb_get_keyblock divert to here in the non-keyboxd mode.
*
* On success, the function returns 0 and the caller must free *RET_KB
* using release_kbnode(). Otherwise, the function returns an error
@@ -1369,17 +1284,11 @@ parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
* with the public key used to locate the keyblock or flag bit 1 set
* for the user ID node. */
gpg_error_t
-keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
+internal_keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
{
gpg_error_t err = 0;
- *ret_kb = NULL;
-
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
-
- if (DBG_CLOCK)
- log_clock ("keydb_get_keybock enter");
+ log_assert (!hd->use_keyboxd);
if (hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED)
{
@@ -1398,8 +1307,7 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
if (err)
keyblock_cache_clear (hd);
if (DBG_CLOCK)
- log_clock (err? "keydb_get_keyblock leave (cached, failed)"
- : "keydb_get_keyblock leave (cached)");
+ log_clock ("%s leave (cached mode)", __func__);
return err;
}
}
@@ -1447,9 +1355,6 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
if (!err)
keydb_stats.get_keyblocks++;
- if (DBG_CLOCK)
- log_clock (err? "keydb_get_keyblock leave (failed)"
- : "keydb_get_keyblock leave");
return err;
}
@@ -1498,6 +1403,7 @@ build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf)
/* Update the keyblock KB (i.e., extract the fingerprint and find the
* corresponding keyblock in the keyring).
+ * keydb_update_keyblock diverts to here in the non-keyboxd mode.
*
* This doesn't do anything if --dry-run was specified.
*
@@ -1512,20 +1418,16 @@ build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf)
* you should use keydb_push_found_state and keydb_pop_found_state to
* save and restore it. */
gpg_error_t
-keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
+internal_keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
{
gpg_error_t err;
PKT_public_key *pk;
KEYDB_SEARCH_DESC desc;
size_t len;
- log_assert (kb);
- log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY);
+ log_assert (!hd->use_keyboxd);
pk = kb->pkt->pkt.public_key;
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
-
kid_not_found_flush ();
keyblock_cache_clear (hd);
@@ -1588,6 +1490,7 @@ keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
/* Insert a keyblock into one of the underlying keyrings or keyboxes.
+ * keydb_insert_keyblock diverts to here in the non-keyboxd mode.
*
* Be default, the keyring / keybox from which the last search result
* came is used. If there was no previous search result (or
@@ -1598,13 +1501,12 @@ keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
*
* Returns 0 on success. Otherwise, it returns an error code. */
gpg_error_t
-keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
+internal_keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
{
gpg_error_t err;
int idx;
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
+ log_assert (!hd->use_keyboxd);
kid_not_found_flush ();
keyblock_cache_clear (hd);
@@ -1663,12 +1565,11 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
*
* Returns 0 on success or an error code, if an error occurs. */
gpg_error_t
-keydb_delete_keyblock (KEYDB_HANDLE hd)
+internal_keydb_delete_keyblock (KEYDB_HANDLE hd)
{
gpg_error_t rc;
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
+ log_assert (!hd->use_keyboxd);
kid_not_found_flush ();
keyblock_cache_clear (hd);
@@ -1721,6 +1622,9 @@ keydb_locate_writable (KEYDB_HANDLE hd)
if (!hd)
return GPG_ERR_INV_ARG;
+ if (hd->use_keyboxd)
+ return 0; /* No need for this here. */
+
rc = keydb_search_reset (hd); /* this does reset hd->current */
if (rc)
return rc;
@@ -1772,6 +1676,9 @@ keydb_rebuild_caches (ctrl_t ctrl, int noisy)
{
int i, rc;
+ if (opt.use_keyboxd)
+ return; /* No need for this here. */
+
for (i=0; i < used_resources; i++)
{
if (!keyring_is_writable (all_resources[i].token))
@@ -1794,38 +1701,33 @@ keydb_rebuild_caches (ctrl_t ctrl, int noisy)
}
-/* Return the number of skipped blocks (because they were to large to
+/* Return the number of skipped blocks (because they were too large to
read from a keybox) since the last search reset. */
unsigned long
keydb_get_skipped_counter (KEYDB_HANDLE hd)
{
- return hd ? hd->skipped_long_blobs : 0;
+ /*FIXME(keyboxd): Do we need this? */
+ return hd && !hd->use_keyboxd? hd->skipped_long_blobs : 0;
}
/* Clears the current search result and resets the handle's position
* so that the next search starts at the beginning of the database
* (the start of the first resource).
+ * keydb_search_reset diverts to here in the non-keyboxd mode.
*
* Returns 0 on success and an error code if an error occurred.
* (Currently, this function always returns 0 if HD is valid.) */
gpg_error_t
-keydb_search_reset (KEYDB_HANDLE hd)
+internal_keydb_search_reset (KEYDB_HANDLE hd)
{
gpg_error_t rc = 0;
int i;
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
+ log_assert (!hd->use_keyboxd);
keyblock_cache_clear (hd);
- if (DBG_CLOCK)
- log_clock ("keydb_search_reset");
-
- if (DBG_CACHE)
- log_debug ("keydb_search: reset (hd=%p)", hd);
-
hd->skipped_long_blobs = 0;
hd->current = 0;
hd->found = -1;
@@ -1853,6 +1755,7 @@ keydb_search_reset (KEYDB_HANDLE hd)
/* Search the database for keys matching the search description. If
* the DB contains any legacy keys, these are silently ignored.
+ * keydb_search diverts to here in the non-keyboxd mode.
*
* 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
@@ -1870,21 +1773,16 @@ keydb_search_reset (KEYDB_HANDLE hd)
* The returned key is considered to be selected and the raw data can,
* for instance, be returned by calling keydb_get_keyblock(). */
gpg_error_t
-keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
- size_t ndesc, size_t *descindex)
+internal_keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
+ size_t ndesc, size_t *descindex)
{
- int i;
gpg_error_t rc;
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. */
-
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
+ log_assert (!hd->use_keyboxd);
if (!any_registered)
{
@@ -1892,26 +1790,11 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
return gpg_error (GPG_ERR_NOT_FOUND);
}
- if (DBG_CLOCK)
- log_clock ("keydb_search enter");
-
- if (DBG_LOOKUP)
- {
- log_debug ("%s: %zd search descriptions:\n", __func__, ndesc);
- for (i = 0; i < ndesc; i ++)
- {
- char *t = keydb_search_desc_dump (&desc[i]);
- log_debug ("%s %d: %s\n", __func__, i, t);
- xfree (t);
- }
- }
-
-
if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID
&& (already_in_cache = kid_not_found_p (desc[0].u.kid)) == 1 )
{
if (DBG_CLOCK)
- log_clock ("keydb_search leave (not found, cached)");
+ log_clock ("%s leave (not found, cached)", __func__);
keydb_stats.notfound_cached++;
return gpg_error (GPG_ERR_NOT_FOUND);
}
@@ -1939,7 +1822,7 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
{
/* (DESCINDEX is already set). */
if (DBG_CLOCK)
- log_clock ("keydb_search leave (cached)");
+ log_clock ("%s leave (cached)", __func__);
hd->current = hd->keyblock_cache.resource;
/* HD->KEYBLOCK_CACHE.OFFSET is the last byte in the record.
@@ -2029,9 +1912,6 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
&& !already_in_cache)
kid_not_found_insert (desc[0].u.kid);
- if (DBG_CLOCK)
- log_clock (rc? "keydb_search leave (not found)"
- : "keydb_search leave (found)");
if (!rc)
keydb_stats.found++;
else