aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2001-05-28 17:35:10 +0000
committerWerner Koch <[email protected]>2001-05-28 17:35:10 +0000
commit4c76d6dce1113750f220e9730b83efc7329668bb (patch)
tree46d8a45b82c654defc07a87b937377259a26c9c6
parentAdjusted for changes --fixed-list-mode in 1.0.4h (diff)
downloadgpgme-4c76d6dce1113750f220e9730b83efc7329668bb.tar.gz
gpgme-4c76d6dce1113750f220e9730b83efc7329668bb.zip
Changes by Jose and Tommy.
Diffstat (limited to '')
-rw-r--r--gpgme/ChangeLog25
-rw-r--r--gpgme/decrypt.c4
-rw-r--r--gpgme/encrypt.c1
-rw-r--r--gpgme/key.c195
-rw-r--r--gpgme/key.h5
-rw-r--r--gpgme/keylist.c6
-rw-r--r--gpgme/rungpg.c1
-rw-r--r--gpgme/verify.c28
-rw-r--r--gpgme/version.c7
-rw-r--r--tests/t-verify.c4
10 files changed, 251 insertions, 25 deletions
diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog
index 017ab28b..a8242e5b 100644
--- a/gpgme/ChangeLog
+++ b/gpgme/ChangeLog
@@ -1,3 +1,26 @@
+2001-05-28 Werner Koch <[email protected]>
+
+ * version.c (gpgme_check_engine): Stop version number parsing at
+ the opening angle and not the closing one. By Tommy Reynolds.
+
+2001-05-01 Jos� Carlos Garc�a Sogo <[email protected]>
+
+ * encrypt.c (gpgme_op_encrypt_start): Deleted the assert ( !c->gpg )
+ line, because it gave an error if another operation had been made
+ before using the same context.
+
+ * decrypt.c (gpgme_op_decrypt_start): The same as above. Also added
+ one line to release the gpg object in the context (if any).
+
+2001-04-26 Werner Koch <[email protected]>
+
+ * key.c, key.h (_gpgme_key_cache_init): New.
+ (_gpgme_key_cache_add): New.
+ (_gpgme_key_cache_get): New.
+ * version.c (do_subsystem_inits): Init the cache.
+ * keylist.c (finish_key): Put key into the cache
+ * verify.c (gpgme_get_sig_key): First look into the cache.
+
2001-04-19 Werner Koch <[email protected]>
* keylist.c (parse_timestamp): Adjusted for the changed
@@ -208,4 +231,4 @@
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- \ No newline at end of file
+
diff --git a/gpgme/decrypt.c b/gpgme/decrypt.c
index 526a8156..5982301b 100644
--- a/gpgme/decrypt.c
+++ b/gpgme/decrypt.c
@@ -195,9 +195,9 @@ gpgme_op_decrypt_start ( GpgmeCtx c,
c->out_of_core = 0;
/* do some checks */
- assert ( !c->gpg );
-
+
/* create a process object */
+ _gpgme_gpg_release ( c->gpg );
rc = _gpgme_gpg_new ( &c->gpg );
if (rc)
goto leave;
diff --git a/gpgme/encrypt.c b/gpgme/encrypt.c
index 5234cc8b..3fe60a62 100644
--- a/gpgme/encrypt.c
+++ b/gpgme/encrypt.c
@@ -49,7 +49,6 @@ gpgme_op_encrypt_start ( GpgmeCtx c, GpgmeRecipients recp,
c->pending = 1;
/* do some checks */
- assert ( !c->gpg );
if ( !gpgme_recipients_count ( recp ) ) {
/* Fixme: In this case we should do symmentric encryption */
rc = mk_error (No_Recipients);
diff --git a/gpgme/key.c b/gpgme/key.c
index f61d2c1c..966675e3 100644
--- a/gpgme/key.c
+++ b/gpgme/key.c
@@ -31,6 +31,199 @@
#define ALLOC_CHUNK 1024
#define my_isdigit(a) ( (a) >='0' && (a) <= '9' )
+#if SIZEOF_UNSIGNED_INT < 4
+#error unsigned int too short to be used as a hash value
+#endif
+
+struct key_cache_item_s {
+ struct key_cache_item_s *next;
+ GpgmeKey key;
+};
+
+static int key_cache_initialized;
+static struct key_cache_item_s **key_cache;
+static size_t key_cache_size;
+static size_t key_cache_max_chain_length;
+static struct key_cache_item_s *key_cache_unused_items;
+
+static int
+hextobyte ( const byte *s )
+{
+ int c;
+
+ if ( *s >= '0' && *s <= '9' )
+ c = 16 * (*s - '0');
+ else if ( *s >= 'A' && *s <= 'F' )
+ c = 16 * (10 + *s - 'A');
+ else if ( *s >= 'a' && *s <= 'f' )
+ c = 16 * (10 + *s - 'a');
+ else
+ return -1;
+ s++;
+ if ( *s >= '0' && *s <= '9' )
+ c += *s - '0';
+ else if ( *s >= 'A' && *s <= 'F' )
+ c += 10 + *s - 'A';
+ else if ( *s >= 'a' && *s <= 'f' )
+ c += 10 + *s - 'a';
+ else
+ return -1;
+ return c;
+}
+
+static int
+hash_key (const char *fpr, unsigned int *rhash)
+{
+ unsigned int hash;
+ int c;
+
+ if ( !fpr ) return -1;
+ if ( (c = hextobyte(fpr)) == -1 ) return -1;
+ hash = c;
+ if ( (c = hextobyte(fpr+2)) == -1 ) return -1;
+ hash |= c << 8;
+ if ( (c = hextobyte(fpr+4)) == -1 ) return -1;
+ hash |= c << 16;
+ if ( (c = hextobyte(fpr+6)) == -1 ) return -1;
+ hash |= c << 24;
+
+ *rhash = hash;
+ return 0;
+}
+
+void
+_gpgme_key_cache_init (void)
+{
+ if (key_cache_initialized)
+ return;
+ key_cache_size = 503;
+ key_cache = xtrycalloc (key_cache_size, sizeof *key_cache);
+ if (!key_cache) {
+ key_cache_size = 0;
+ key_cache_initialized = 1;
+ return;
+ }
+ /*
+ * The upper bound for our cache size is
+ * key_cache_max_chain_length * key_cache_size
+ */
+ key_cache_max_chain_length = 10;
+ key_cache_initialized = 1;
+}
+
+
+void
+_gpgme_key_cache_add (GpgmeKey key)
+{
+ struct subkey_s *k;
+#warning debug code
+ if (!key || getenv("gpgme_no_cache") )
+ return;
+
+ /* FIXME: add locking */
+ if (!key_cache_initialized)
+ _gpgme_key_cache_init ();
+ if (!key_cache_size)
+ return; /* cache was not enabled */
+
+ /* 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)
+ break; /* already in cache */
+ /* 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);
+ 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;
+
+ assert (last->next == item);
+ 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 = xtrymalloc (sizeof *item);
+ if (!item)
+ return; /* out of core */
+ }
+
+ item->key = key;
+ gpgme_key_ref (key);
+ item->next = key_cache[hash];
+ key_cache[hash] = item;
+ }
+}
+
+
+GpgmeKey
+_gpgme_key_cache_get (const char *fpr)
+{
+ struct key_cache_item_s *item;
+ unsigned int hash;
+
+ if (!key_cache_size)
+ return NULL; /* cache not (yet) enabled */
+
+ if (hash_key (fpr, &hash))
+ 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);
+ return item->key;
+ }
+ }
+ }
+ return NULL;
+}
+
static const char *
pkalgo_to_string ( int algo )
@@ -47,8 +240,6 @@ pkalgo_to_string ( int algo )
}
-
-
static GpgmeError
key_new ( GpgmeKey *r_key, int secret )
{
diff --git a/gpgme/key.h b/gpgme/key.h
index 60244e97..003821a5 100644
--- a/gpgme/key.h
+++ b/gpgme/key.h
@@ -61,6 +61,11 @@ struct gpgme_key_s {
struct user_id_s *uids;
};
+void _gpgme_key_cache_init (void);
+void _gpgme_key_cache_add (GpgmeKey key);
+GpgmeKey _gpgme_key_cache_get (const char *fpr);
+
+
struct subkey_s *_gpgme_key_add_subkey (GpgmeKey key);
struct subkey_s *_gpgme_key_add_secret_subkey (GpgmeKey key);
GpgmeError _gpgme_key_append_name ( GpgmeKey key, const char *s );
diff --git a/gpgme/keylist.c b/gpgme/keylist.c
index 9d7824bb..11e10cf2 100644
--- a/gpgme/keylist.c
+++ b/gpgme/keylist.c
@@ -341,10 +341,12 @@ finish_key ( GpgmeCtx ctx )
{
GpgmeKey key = ctx->tmp_key;
struct key_queue_item_s *q, *q2;
-
+
assert (key);
ctx->tmp_key = NULL;
-
+
+ _gpgme_key_cache_add (key);
+
q = xtrymalloc ( sizeof *q );
if ( !q ) {
gpgme_key_release (key);
diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c
index 6f731e51..708b2781 100644
--- a/gpgme/rungpg.c
+++ b/gpgme/rungpg.c
@@ -1094,7 +1094,6 @@ read_status ( GpgObject gpg )
if ( *p == '\n' ) {
/* (we require that the last line is terminated by a LF) */
*p = 0;
- fflush (stdout); fprintf (stderr, "read_status: `%s'\n", buffer);
if (!strncmp (buffer, "[GNUPG:] ", 9 )
&& buffer[9] >= 'A' && buffer[9] <= 'Z' ) {
struct status_table_s t, *r;
diff --git a/gpgme/verify.c b/gpgme/verify.c
index 0d50b8a9..3b2174b6 100644
--- a/gpgme/verify.c
+++ b/gpgme/verify.c
@@ -28,6 +28,7 @@
#include "util.h"
#include "context.h"
#include "ops.h"
+#include "key.h"
struct verify_result_s {
struct verify_result_s *next;
@@ -219,7 +220,7 @@ gpgme_op_verify_start ( GpgmeCtx c, GpgmeData sig, GpgmeData text )
{
int rc = 0;
int i;
- int pipemode = !!text; /* use pipemode for detached sigs */
+ int pipemode = 0; /*!!text; use pipemode for detached sigs */
fail_on_pending_request( c );
c->pending = 1;
@@ -414,8 +415,7 @@ GpgmeError
gpgme_get_sig_key (GpgmeCtx c, int idx, GpgmeKey *r_key)
{
VerifyResult res;
- GpgmeCtx listctx;
- GpgmeError err;
+ GpgmeError err = 0;
if (!c || !r_key)
return mk_error (Invalid_Value);
@@ -430,15 +430,19 @@ gpgme_get_sig_key (GpgmeCtx c, int idx, GpgmeKey *r_key)
if (strlen(res->fpr) < 16) /* we have at least an key ID */
return mk_error (Invalid_Key);
- /* Fixme: This can me optimized keeping
- * an internal context used for such key listings */
- if ( (err=gpgme_new (&listctx)) )
- return err;
- gpgme_set_keylist_mode( listctx, c->keylist_mode );
- if ( !(err=gpgme_op_keylist_start (listctx, res->fpr, 0 )) )
- err=gpgme_op_keylist_next ( listctx, r_key );
- gpgme_release (listctx);
-
+ *r_key = _gpgme_key_cache_get (res->fpr);
+ if (!*r_key) {
+ GpgmeCtx listctx;
+
+ /* Fixme: This can be optimized by keeping
+ * an internal context used for such key listings */
+ if ( (err=gpgme_new (&listctx)) )
+ return err;
+ gpgme_set_keylist_mode( listctx, c->keylist_mode );
+ if ( !(err=gpgme_op_keylist_start (listctx, res->fpr, 0 )) )
+ err=gpgme_op_keylist_next ( listctx, r_key );
+ gpgme_release (listctx);
+ }
return err;
}
diff --git a/gpgme/version.c b/gpgme/version.c
index 0d8e5a7c..74b6576d 100644
--- a/gpgme/version.c
+++ b/gpgme/version.c
@@ -30,7 +30,7 @@
#include "rungpg.h"
#include "sema.h"
#include "util.h"
-
+#include "key.h" /* for key_cache_init */
static int lineno;
static char *tmp_engine_version;
@@ -46,6 +46,7 @@ do_subsystem_inits (void)
if (done)
return;
_gpgme_sema_subsystem_init ();
+ _gpgme_key_cache_init ();
}
@@ -104,7 +105,7 @@ compare_versions ( const char *my_version, const char *req_version )
if ( my_major > rq_major
|| (my_major == rq_major && my_minor > rq_minor)
- || (my_major == rq_major && my_minor == rq_minor
+ || (my_major == rq_major && my_minor == rq_minor
&& my_micro > rq_micro)
|| (my_major == rq_major && my_minor == rq_minor
&& my_micro == rq_micro
@@ -173,7 +174,7 @@ gpgme_check_engine ()
s = strstr (info, "<version>");
if (s) {
s += 9;
- s2 = strchr (s, '>');
+ s2 = strchr (s, '<');
if (s2) {
char *ver = xtrymalloc (s2 - s + 1);
if (!ver)
diff --git a/tests/t-verify.c b/tests/t-verify.c
index b315d1f1..524a203e 100644
--- a/tests/t-verify.c
+++ b/tests/t-verify.c
@@ -132,6 +132,7 @@ main (int argc, char **argv )
GpgmeData sig, text;
GpgmeSigStat status;
char *nota;
+ int n = 0;
err = gpgme_new (&ctx);
fail_if_err (err);
@@ -166,6 +167,7 @@ main (int argc, char **argv )
fail_if_err (err);
gpgme_data_rewind ( sig );
err = gpgme_op_verify (ctx, sig, text, &status );
+
print_sig_stat ( ctx, status );
fail_if_err (err);
if ( (nota=gpgme_get_notation (ctx)) )
@@ -174,7 +176,7 @@ main (int argc, char **argv )
gpgme_data_release (sig);
gpgme_data_release (text);
-} while ( argc > 1 && !strcmp( argv[1], "--loop" ) );
+} while ( argc > 1 && !strcmp( argv[1], "--loop" ) && ++n < 20 );
gpgme_release (ctx);
return 0;