From 984d611a438768f07b27a5af8202d9f7739be1ab Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 29 Apr 2003 22:24:37 +0000 Subject: [PATCH] doc/ 2003-04-29 Marcus Brinkmann * gpgme.texi (Listing Keys): Remove force_update argument from gpgme_get_key. gpgme/ 2003-04-29 Marcus Brinkmann * gpgme.h (gpgme_get_key): Remove force_update argument. * key-cache.c: File removed. * Makefile.am (libgpgme_la_SOURCES): Remove key-cache.c. * ops.h (_gpgme_key_cache_add, _gpgme_key_cache_get): Remove prototypes. * keylist.c (_gpgme_op_keylist_event_cb): Don't call _gpgme_key_cache_add. (gpgme_get_key): New function. * verify.c (gpgme_get_sig_key): Remove last argument to gpgme_get_key invocation. --- NEWS | 4 + doc/ChangeLog | 3 + doc/gpgme.texi | 14 ++- gpgme/ChangeLog | 11 ++ gpgme/Makefile.am | 2 +- gpgme/gpgme.h | 8 +- gpgme/key-cache.c | 250 ---------------------------------------------- gpgme/keylist.c | 32 +++++- gpgme/ops.h | 10 -- gpgme/verify.c | 2 +- 10 files changed, 59 insertions(+), 277 deletions(-) delete mode 100644 gpgme/key-cache.c diff --git a/NEWS b/NEWS index bebd129b..92f38555 100644 --- a/NEWS +++ b/NEWS @@ -103,6 +103,9 @@ Noteworthy changes in version 0.4.1 (unreleased) available through gpgme_trust_item_ref and gpgme_trust_item_unref (the gpgme_trust_item_release alias for the latter is deprecated). + * Keys are not cached internally anymore, so the force_update argument + to gpgme_get_key has been removed. + * Interface changes relative to the 0.4.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GpgmeIOCb CHANGED: Return type from void to GpgmeError. @@ -159,6 +162,7 @@ gpgme_trust_item_unref NEW gpgme_trust_item_release DEPRECATED: Use gpgme_trust_item_unref. gpgme_trust_item_get_string_attr DEPRECATED gpgme_trust_item_get_ulong_attr DEPRECATED +gpgme_get_key CHANGED: Removed force_update argument. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Noteworthy changes in version 0.4.0 (2002-12-23) diff --git a/doc/ChangeLog b/doc/ChangeLog index a7430878..6d69fa7a 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,8 @@ 2003-04-29 Marcus Brinkmann + * gpgme.texi (Listing Keys): Remove force_update argument from + gpgme_get_key. + * gpgme.texi (Trust Item Management): Add data members of GpgmeTrustItem type. (Information About Trust Items): Add note about obsoleteness. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 838a262b..6ba91632 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -1917,15 +1917,13 @@ if (err) In a simple program, for which a blocking operation is acceptable, the following function can be used to retrieve a single key. -@deftypefun GpgmeError gpgme_get_key (@w{GpgmeCtx @var{ctx}}, @w{const char *@var{fpr}}, @w{GpgmeKey *@var{r_key}}, @w{int @var{secret}}, @w{int @var{force_update}}) +@deftypefun GpgmeError gpgme_get_key (@w{GpgmeCtx @var{ctx}}, @w{const char *@var{fpr}}, @w{GpgmeKey *@var{r_key}}, @w{int @var{secret}}) The function @code{gpgme_get_key} gets the key with the fingerprint -(or key ID) @var{fpr} from the key cache or from the crypto backend -and return it in @var{r_key}. If @var{force_update} is true, force a -refresh of the key from the crypto backend and replace the key in the -cache, if any. If @var{secret} is true, get the secret key. - -If the @code{GPGME_KEYLIST_MODE_SIGS} mode is active, the key will be -retrieved with the key signatures (and updated if necessary). +(or key ID) @var{fpr} from the crypto backend and return it in +@var{r_key}. If @var{force_update} is true, force a refresh of the +key from the crypto backend and replace the key in the cache, if any. +If @var{secret} is true, get the secret key. The currently active +keylist mode is used to retrieve the key. The function returns @code{GPGME_Invalid_Value} if @var{ctx} or @var{r_key} is not a valid pointer, @code{GPGME_Invalid_Key} if diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index b6399c77..c9c47708 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,5 +1,16 @@ 2003-04-29 Marcus Brinkmann + * gpgme.h (gpgme_get_key): Remove force_update argument. + * key-cache.c: File removed. + * Makefile.am (libgpgme_la_SOURCES): Remove key-cache.c. + * ops.h (_gpgme_key_cache_add, _gpgme_key_cache_get): Remove + prototypes. + * keylist.c (_gpgme_op_keylist_event_cb): Don't call + _gpgme_key_cache_add. + (gpgme_get_key): New function. + * verify.c (gpgme_get_sig_key): Remove last argument to + gpgme_get_key invocation. + * gpgme.h (struct _gpgme_trust_item): New structure. (GpgmeTrustItem): New type. (gpgme_trust_item_ref, gpgme_trust_item_unref): New prototypes. diff --git a/gpgme/Makefile.am b/gpgme/Makefile.am index 7a8a79c0..7eecd746 100644 --- a/gpgme/Makefile.am +++ b/gpgme/Makefile.am @@ -77,7 +77,7 @@ libgpgme_la_SOURCES = \ op-support.c \ encrypt.c encrypt-sign.c decrypt.c decrypt-verify.c verify.c \ sign.c passphrase.c progress.c \ - key.c key-cache.c keylist.c trust-item.c trustlist.c \ + key.c keylist.c trust-item.c trustlist.c \ import.c export.c genkey.c delete.c edit.c \ engine.h engine-backend.h engine.c rungpg.c status-table.h \ ${gpgsm_components} sema.h io.h ${system_components} \ diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index b5813fdf..b119360d 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -680,12 +680,10 @@ GpgmeError gpgme_data_rewind (GpgmeData dh); /* Key and trust functions. */ -/* Get the key with the fingerprint FPR from the key cache or from the - crypto backend. If FORCE_UPDATE is true, force a refresh of the - key from the crypto backend and replace the key in the cache, if - any. If SECRET is true, get the secret key. */ +/* Get the key with the fingerprint FPR from the crypto backend. If + SECRET is true, get the secret key. */ GpgmeError gpgme_get_key (GpgmeCtx ctx, const char *fpr, GpgmeKey *r_key, - int secret, int force_update); + int secret); /* Acquire a reference to KEY. */ void gpgme_key_ref (GpgmeKey key); diff --git a/gpgme/key-cache.c b/gpgme/key-cache.c deleted file mode 100644 index 0322ef22..00000000 --- a/gpgme/key-cache.c +++ /dev/null @@ -1,250 +0,0 @@ -/* key-cache.c - Key cache routines. - Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003 g10 Code GmbH - - This file is part of GPGME. - - GPGME is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GPGME is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GPGME; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if HAVE_CONFIG_H -#include -#endif -#include -#include - -#include "gpgme.h" -#include "util.h" -#include "ops.h" -#include "sema.h" -#include "key.h" - -#if SIZEOF_UNSIGNED_INT < 4 -#error unsigned int too short to be used as a hash value -#endif - -#define KEY_CACHE_SIZE 503 -#define KEY_CACHE_MAX_CHAIN_LENGTH 10 - -struct key_cache_item_s -{ - struct key_cache_item_s *next; - GpgmeKey key; -}; - -/* Protects key_cache and key_cache_unused_items. */ -DEFINE_STATIC_LOCK (key_cache_lock); -static struct key_cache_item_s *key_cache[KEY_CACHE_SIZE]; -static struct key_cache_item_s *key_cache_unused_items; - - -/* We use the first 4 digits to calculate the hash. */ -static int -hash_key (const char *fpr, unsigned int *rhash) -{ - unsigned int hash; - int c; - - if (!fpr) - return -1; - if ((c = _gpgme_hextobyte (fpr)) == -1) - return -1; - hash = c; - if ((c = _gpgme_hextobyte (fpr+2)) == -1) - return -1; - hash |= c << 8; - if ((c = _gpgme_hextobyte (fpr+4)) == -1) - return -1; - hash |= c << 16; - if ((c = _gpgme_hextobyte (fpr+6)) == -1) - return -1; - hash |= c << 24; - - *rhash = hash; - return 0; -} - - -/* Acquire a reference to KEY and add it to the key cache. */ -void -_gpgme_key_cache_add (GpgmeKey key) -{ - struct subkey_s *k; - - LOCK (key_cache_lock); - /* Put the key under each fingerprint into the cache. We use the - first 4 digits to calculate the hash. */ - for (k = &key->keys; k; k = k->next) - { - size_t n; - unsigned int hash; - struct key_cache_item_s *item; - - if (hash_key (k->fingerprint, &hash)) - continue; - - hash %= KEY_CACHE_SIZE; - for (item = key_cache[hash], n=0; item; item = item->next, n++) - { - struct subkey_s *k2; - if (item->key == key) - /* Already in cache. */ - break; - /* Now do a deeper check. */ - for (k2 = &item->key->keys; k2; k2 = k2->next) - { - if (k2->fingerprint && !strcmp (k->fingerprint, k2->fingerprint)) - { - /* Okay, replace it with the new copy. */ - gpgme_key_unref (item->key); - item->key = key; - gpgme_key_ref (item->key); - UNLOCK (key_cache_lock); - return; - } - } - } - if (item) - continue; - - if (n > KEY_CACHE_MAX_CHAIN_LENGTH) - { - /* Remove the last entries. */ - struct key_cache_item_s *last = NULL; - - for (item = key_cache[hash]; - item && n < KEY_CACHE_MAX_CHAIN_LENGTH; - last = item, item = item->next, n++) - ; - - if (last) - { - struct key_cache_item_s *next; - - last->next = NULL; - for (; item; item = next) - { - next = item->next; - gpgme_key_unref (item->key); - item->key = NULL; - item->next = key_cache_unused_items; - key_cache_unused_items = item; - } - } - } - - item = key_cache_unused_items; - if (item) - { - key_cache_unused_items = item->next; - item->next = NULL; - } - else - { - item = malloc (sizeof *item); - if (!item) - { - UNLOCK (key_cache_lock); - return; - } - } - - item->key = key; - gpgme_key_ref (key); - item->next = key_cache[hash]; - key_cache[hash] = item; - } - UNLOCK (key_cache_lock); -} - - -GpgmeKey -_gpgme_key_cache_get (const char *fpr) -{ - struct key_cache_item_s *item; - unsigned int hash; - - LOCK (key_cache_lock); - if (hash_key (fpr, &hash)) - { - UNLOCK (key_cache_lock); - return NULL; - } - - hash %= KEY_CACHE_SIZE; - for (item = key_cache[hash]; item; item = item->next) - { - struct subkey_s *k; - - for (k = &item->key->keys; k; k = k->next) - { - if (k->fingerprint && !strcmp (k->fingerprint, fpr)) - { - gpgme_key_ref (item->key); - UNLOCK (key_cache_lock); - return item->key; - } - } - } - UNLOCK (key_cache_lock); - return NULL; -} - - -/* Get the key with the fingerprint FPR from the key cache or from the - crypto backend. If FORCE_UPDATE is true, force a refresh of the - key from the crypto backend and replace the key in the cache, if - any. If SECRET is true, get the secret key. */ -GpgmeError -gpgme_get_key (GpgmeCtx ctx, const char *fpr, GpgmeKey *r_key, - int secret, int force_update) -{ - GpgmeCtx listctx; - GpgmeError err; - - if (!ctx || !r_key) - return GPGME_Invalid_Value; - - if (strlen (fpr) < 16) /* We have at least a key ID. */ - return GPGME_Invalid_Key; - - if (!force_update) - { - *r_key = _gpgme_key_cache_get (fpr); - if (*r_key) - { - /* If the primary UID (if available) has no signatures, and - we are in the signature listing keylist mode, then try to - update the key below before returning. */ - if (!((ctx->keylist_mode & GPGME_KEYLIST_MODE_SIGS) - && (*r_key)->uids && !(*r_key)->uids->certsigs)) - return 0; - } - } - - /* We need our own context because we have to avoid the user's I/O - callback handlers. */ - /* Fixme: This can be optimized by keeping an internal context - used for such key listings. */ - err = gpgme_new (&listctx); - if (err) - return err; - gpgme_set_protocol (listctx, gpgme_get_protocol (ctx)); - gpgme_set_keylist_mode (listctx, ctx->keylist_mode); - err = gpgme_op_keylist_start (listctx, fpr, secret); - if (!err) - err = gpgme_op_keylist_next (listctx, r_key); - gpgme_release (listctx); - return err; -} diff --git a/gpgme/keylist.c b/gpgme/keylist.c index 85f1ff37..54ce4a97 100644 --- a/gpgme/keylist.c +++ b/gpgme/keylist.c @@ -688,8 +688,6 @@ _gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data) assert (type == GPGME_EVENT_NEXT_KEY); - _gpgme_key_cache_add (key); - q = malloc (sizeof *q); if (!q) { @@ -862,3 +860,33 @@ gpgme_op_keylist_end (GpgmeCtx ctx) return 0; } + + +/* Get the key with the fingerprint FPR from the crypto backend. If + SECRET is true, get the secret key. */ +GpgmeError +gpgme_get_key (GpgmeCtx ctx, const char *fpr, GpgmeKey *r_key, + int secret) +{ + GpgmeCtx listctx; + GpgmeError err; + + if (!ctx || !r_key) + return GPGME_Invalid_Value; + + if (strlen (fpr) < 16) /* We have at least a key ID. */ + return GPGME_Invalid_Key; + + /* FIXME: We use our own context because we have to avoid the user's + I/O callback handlers. */ + err = gpgme_new (&listctx); + if (err) + return err; + gpgme_set_protocol (listctx, gpgme_get_protocol (ctx)); + gpgme_set_keylist_mode (listctx, ctx->keylist_mode); + err = gpgme_op_keylist_start (listctx, fpr, secret); + if (!err) + err = gpgme_op_keylist_next (listctx, r_key); + gpgme_release (listctx); + return err; +} diff --git a/gpgme/ops.h b/gpgme/ops.h index ffc2bdbe..d1131604 100644 --- a/gpgme/ops.h +++ b/gpgme/ops.h @@ -119,16 +119,6 @@ GpgmeError _gpgme_progress_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args); -/* From key-cache.c. */ - -/* Acquire a reference to KEY and add it to the key cache. */ -void _gpgme_key_cache_add (GpgmeKey key); - -/* Look up a key with fingerprint FPR in the key cache. If such a key - is found, a reference is acquired for it and it is returned. - Otherwise, NULL is returned. */ -GpgmeKey _gpgme_key_cache_get (const char *fpr); - /*-- keylist.c --*/ void _gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data); diff --git a/gpgme/verify.c b/gpgme/verify.c index 42341e0f..e94232cb 100644 --- a/gpgme/verify.c +++ b/gpgme/verify.c @@ -582,7 +582,7 @@ gpgme_get_sig_key (GpgmeCtx ctx, int idx, GpgmeKey *r_key) if (!sig || idx) return GPGME_EOF; - return gpgme_get_key (ctx, sig->fpr, r_key, 0, 0); + return gpgme_get_key (ctx, sig->fpr, r_key, 0); }