2003-04-29  Marcus Brinkmann  <marcus@g10code.de>

	* gpgme.texi (Listing Keys): Remove force_update argument from
	gpgme_get_key.

gpgme/
2003-04-29  Marcus Brinkmann  <marcus@g10code.de>

	* 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.
This commit is contained in:
Marcus Brinkmann 2003-04-29 22:24:37 +00:00
parent 5533982d79
commit 984d611a43
10 changed files with 59 additions and 277 deletions

4
NEWS
View File

@ -103,6 +103,9 @@ Noteworthy changes in version 0.4.1 (unreleased)
available through gpgme_trust_item_ref and gpgme_trust_item_unref available through gpgme_trust_item_ref and gpgme_trust_item_unref
(the gpgme_trust_item_release alias for the latter is deprecated). (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: * Interface changes relative to the 0.4.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GpgmeIOCb CHANGED: Return type from void to GpgmeError. 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_release DEPRECATED: Use gpgme_trust_item_unref.
gpgme_trust_item_get_string_attr DEPRECATED gpgme_trust_item_get_string_attr DEPRECATED
gpgme_trust_item_get_ulong_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) Noteworthy changes in version 0.4.0 (2002-12-23)

View File

@ -1,5 +1,8 @@
2003-04-29 Marcus Brinkmann <marcus@g10code.de> 2003-04-29 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Listing Keys): Remove force_update argument from
gpgme_get_key.
* gpgme.texi (Trust Item Management): Add data members of * gpgme.texi (Trust Item Management): Add data members of
GpgmeTrustItem type. GpgmeTrustItem type.
(Information About Trust Items): Add note about obsoleteness. (Information About Trust Items): Add note about obsoleteness.

View File

@ -1917,15 +1917,13 @@ if (err)
In a simple program, for which a blocking operation is acceptable, the In a simple program, for which a blocking operation is acceptable, the
following function can be used to retrieve a single key. 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 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 (or key ID) @var{fpr} from the crypto backend and return it in
and return it in @var{r_key}. If @var{force_update} is true, force a @var{r_key}. If @var{force_update} is true, force a refresh of the
refresh of the key from the crypto backend and replace the key in the key from the crypto backend and replace the key in the cache, if any.
cache, if any. If @var{secret} is true, get the secret key. If @var{secret} is true, get the secret key. The currently active
keylist mode is used to retrieve the key.
If the @code{GPGME_KEYLIST_MODE_SIGS} mode is active, the key will be
retrieved with the key signatures (and updated if necessary).
The function returns @code{GPGME_Invalid_Value} if @var{ctx} or The function returns @code{GPGME_Invalid_Value} if @var{ctx} or
@var{r_key} is not a valid pointer, @code{GPGME_Invalid_Key} if @var{r_key} is not a valid pointer, @code{GPGME_Invalid_Key} if

View File

@ -1,5 +1,16 @@
2003-04-29 Marcus Brinkmann <marcus@g10code.de> 2003-04-29 Marcus Brinkmann <marcus@g10code.de>
* 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. * gpgme.h (struct _gpgme_trust_item): New structure.
(GpgmeTrustItem): New type. (GpgmeTrustItem): New type.
(gpgme_trust_item_ref, gpgme_trust_item_unref): New prototypes. (gpgme_trust_item_ref, gpgme_trust_item_unref): New prototypes.

View File

@ -77,7 +77,7 @@ libgpgme_la_SOURCES = \
op-support.c \ op-support.c \
encrypt.c encrypt-sign.c decrypt.c decrypt-verify.c verify.c \ encrypt.c encrypt-sign.c decrypt.c decrypt-verify.c verify.c \
sign.c passphrase.c progress.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 \ import.c export.c genkey.c delete.c edit.c \
engine.h engine-backend.h engine.c rungpg.c status-table.h \ engine.h engine-backend.h engine.c rungpg.c status-table.h \
${gpgsm_components} sema.h io.h ${system_components} \ ${gpgsm_components} sema.h io.h ${system_components} \

View File

@ -680,12 +680,10 @@ GpgmeError gpgme_data_rewind (GpgmeData dh);
/* Key and trust functions. */ /* Key and trust functions. */
/* Get the key with the fingerprint FPR from the key cache or from the /* Get the key with the fingerprint FPR from the crypto backend. If
crypto backend. If FORCE_UPDATE is true, force a refresh of the SECRET is true, get the secret key. */
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, GpgmeError gpgme_get_key (GpgmeCtx ctx, const char *fpr, GpgmeKey *r_key,
int secret, int force_update); int secret);
/* Acquire a reference to KEY. */ /* Acquire a reference to KEY. */
void gpgme_key_ref (GpgmeKey key); void gpgme_key_ref (GpgmeKey key);

View File

@ -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 <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#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;
}

View File

@ -688,8 +688,6 @@ _gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data)
assert (type == GPGME_EVENT_NEXT_KEY); assert (type == GPGME_EVENT_NEXT_KEY);
_gpgme_key_cache_add (key);
q = malloc (sizeof *q); q = malloc (sizeof *q);
if (!q) if (!q)
{ {
@ -862,3 +860,33 @@ gpgme_op_keylist_end (GpgmeCtx ctx)
return 0; 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;
}

View File

@ -119,16 +119,6 @@ GpgmeError _gpgme_progress_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args); 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 --*/ /*-- keylist.c --*/
void _gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data); void _gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data);

View File

@ -582,7 +582,7 @@ gpgme_get_sig_key (GpgmeCtx ctx, int idx, GpgmeKey *r_key)
if (!sig || idx) if (!sig || idx)
return GPGME_EOF; return GPGME_EOF;
return gpgme_get_key (ctx, sig->fpr, r_key, 0, 0); return gpgme_get_key (ctx, sig->fpr, r_key, 0);
} }