mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
kbx: First take on a cache for the keyboxd.
* kbx/backend.h (enum database_types): Add DB_TYPE_CACHE. (struct db_request_part_s): Add seqno fields. (struct db_request_s): Add infos for the cache backend. * kbx/backend-support.c (struct backend_handle_s): Add 'backend_id'. (strdbtype): Support DB_TYPE_CACHE. (be_generic_release_backend): Ditto. (be_find_request_part): New. (be_return_pubkey): New arg UBID and chnage status name. * kbx/backend-cache.c: New. * kbx/backend-kbx.c (be_kbx_init_request_part): New. (be_kbx_search): Factor some code out to a support function. (be_kbx_seek): New. * kbx/frontend.c (kbxd_add_resource): Support DB_TYPE_CACHE. (kbxd_search): Support the NEXR operation with the cache. * kbx/keybox-search-desc.h (KEYDB_SEARCH_MODE_UBID): New. (struct keydb_search_desc): Add field u.ubid. * kbx/keybox-search.c (has_ubid): New. (keybox_search): Support the UBID search. -- This adds a caching backend to the keyboxd. This tries to accommodate for duplicate use of fingerprints and thus be correct in case a fingerprint is used in several keys. It also turned out that we need to have a unique identifier (UBID) to identify a keyblock or X.509 certificate. In particular with an OpenPGP keyblob we can't easily use the primary fingerprint as an identifier because that fingerprint may also be used as subkey in another key. Thus using a hash of the entire keyblock is a better identifier to be used to address a keyblock for restarting a search or for identifying the keyblock to be updated. Note that this new UBID is not a permanent identifier because it changes with all keyblock update; it should be viewed as a handle to the keyblock or X509 cert.
This commit is contained in:
parent
d38f877bd8
commit
280e9c9cfa
9 changed files with 1421 additions and 45 deletions
|
@ -34,7 +34,7 @@
|
|||
struct backend_handle_s
|
||||
{
|
||||
enum database_types db_type; /* Always DB_TYPE_KBX. */
|
||||
unsigned int backend_id; /* Id of this backend. */
|
||||
unsigned int backend_id; /* Always the id of the backend. */
|
||||
|
||||
void *token; /* Used to create a new KEYBOX_HANDLE. */
|
||||
char filename[1];
|
||||
|
@ -226,6 +226,17 @@ be_kbx_release_kbx_hd (KEYBOX_HANDLE kbx_hd)
|
|||
}
|
||||
|
||||
|
||||
/* Helper for be_find_request_part to initialize a kbx request part. */
|
||||
gpg_error_t
|
||||
be_kbx_init_request_part (backend_handle_t backend_hd, db_request_part_t part)
|
||||
{
|
||||
part->kbx_hd = keybox_new_openpgp (backend_hd->token, 0);
|
||||
if (!part->kbx_hd)
|
||||
return gpg_error_from_syserror ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Search for the keys described by (DESC,NDESC) and return them to
|
||||
* the caller. BACKEND_HD is the handle for this backend and REQUEST
|
||||
* is the current database request object. */
|
||||
|
@ -242,28 +253,9 @@ be_kbx_search (ctrl_t ctrl, backend_handle_t backend_hd, db_request_t request,
|
|||
log_assert (request);
|
||||
|
||||
/* Find the specific request part or allocate it. */
|
||||
for (part = request->part; part; part = part->next)
|
||||
if (part->backend_id == backend_hd->backend_id)
|
||||
break;
|
||||
if (!part)
|
||||
{
|
||||
part = xtrycalloc (1, sizeof *part);
|
||||
if (!part)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
part->backend_id = backend_hd->backend_id;
|
||||
part->kbx_hd = keybox_new_openpgp (backend_hd->token, 0);
|
||||
if (!part->kbx_hd)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
xfree (part);
|
||||
goto leave;
|
||||
}
|
||||
part->next = request->part;
|
||||
request->part = part;
|
||||
}
|
||||
err = be_find_request_part (backend_hd, request, &part);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
if (!desc)
|
||||
err = keybox_search_reset (part->kbx_hd);
|
||||
|
@ -279,14 +271,56 @@ be_kbx_search (ctrl_t ctrl, backend_handle_t backend_hd, db_request_t request,
|
|||
void *buffer;
|
||||
size_t buflen;
|
||||
enum pubkey_types pubkey_type;
|
||||
unsigned char blobid[20];
|
||||
|
||||
err = keybox_get_data (part->kbx_hd, &buffer, &buflen, &pubkey_type);
|
||||
if (err)
|
||||
goto leave;
|
||||
/* Note: be_return_pubkey always takes ownership of BUFFER. */
|
||||
err = be_return_pubkey (ctrl, buffer, buflen, pubkey_type);
|
||||
gcry_md_hash_buffer (GCRY_MD_SHA1, blobid, buffer, buflen);
|
||||
err = be_return_pubkey (ctrl, buffer, buflen, pubkey_type, blobid);
|
||||
if (!err)
|
||||
be_cache_pubkey (ctrl, blobid, buffer, buflen, pubkey_type);
|
||||
xfree (buffer);
|
||||
}
|
||||
|
||||
leave:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Seek in the keybox to the given UBID. BACKEND_HD is the handle for
|
||||
* this backend and REQUEST is the current database request object.
|
||||
* This does a dummy read so that the next search operation starts
|
||||
* right after that UBID. */
|
||||
gpg_error_t
|
||||
be_kbx_seek (ctrl_t ctrl, backend_handle_t backend_hd,
|
||||
db_request_t request, unsigned char *ubid)
|
||||
{
|
||||
gpg_error_t err;
|
||||
db_request_part_t part;
|
||||
size_t descindex;
|
||||
unsigned long skipped_long_blobs;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
|
||||
log_assert (backend_hd && backend_hd->db_type == DB_TYPE_KBX);
|
||||
log_assert (request);
|
||||
|
||||
memset (&desc, 0, sizeof desc);
|
||||
desc.mode = KEYDB_SEARCH_MODE_UBID;
|
||||
memcpy (desc.u.ubid, ubid, 20);
|
||||
|
||||
/* Find the specific request part or allocate it. */
|
||||
err = be_find_request_part (backend_hd, request, &part);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
err = keybox_search_reset (part->kbx_hd);
|
||||
if (!err)
|
||||
err = keybox_search (part->kbx_hd, &desc, 1, 0,
|
||||
&descindex, &skipped_long_blobs);
|
||||
if (err == -1)
|
||||
err = gpg_error (GPG_ERR_EOF);
|
||||
|
||||
leave:
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue