Changes by Jose and Tommy.

This commit is contained in:
Werner Koch 2001-05-28 17:35:10 +00:00
parent 1a3db20121
commit 4c76d6dce1
10 changed files with 250 additions and 24 deletions

View File

@ -1,3 +1,26 @@
2001-05-28 Werner Koch <wk@gnupg.org>
* 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 <jose@jaimedelamo.eu.org>
* 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 <wk@gnupg.org>
* 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 <wk@gnupg.org> 2001-04-19 Werner Koch <wk@gnupg.org>
* keylist.c (parse_timestamp): Adjusted for the changed * 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 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 WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -195,9 +195,9 @@ gpgme_op_decrypt_start ( GpgmeCtx c,
c->out_of_core = 0; c->out_of_core = 0;
/* do some checks */ /* do some checks */
assert ( !c->gpg );
/* create a process object */ /* create a process object */
_gpgme_gpg_release ( c->gpg );
rc = _gpgme_gpg_new ( &c->gpg ); rc = _gpgme_gpg_new ( &c->gpg );
if (rc) if (rc)
goto leave; goto leave;

View File

@ -49,7 +49,6 @@ gpgme_op_encrypt_start ( GpgmeCtx c, GpgmeRecipients recp,
c->pending = 1; c->pending = 1;
/* do some checks */ /* do some checks */
assert ( !c->gpg );
if ( !gpgme_recipients_count ( recp ) ) { if ( !gpgme_recipients_count ( recp ) ) {
/* Fixme: In this case we should do symmentric encryption */ /* Fixme: In this case we should do symmentric encryption */
rc = mk_error (No_Recipients); rc = mk_error (No_Recipients);

View File

@ -31,6 +31,199 @@
#define ALLOC_CHUNK 1024 #define ALLOC_CHUNK 1024
#define my_isdigit(a) ( (a) >='0' && (a) <= '9' ) #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 * static const char *
pkalgo_to_string ( int algo ) pkalgo_to_string ( int algo )
@ -47,8 +240,6 @@ pkalgo_to_string ( int algo )
} }
static GpgmeError static GpgmeError
key_new ( GpgmeKey *r_key, int secret ) key_new ( GpgmeKey *r_key, int secret )
{ {

View File

@ -61,6 +61,11 @@ struct gpgme_key_s {
struct user_id_s *uids; 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_subkey (GpgmeKey key);
struct subkey_s *_gpgme_key_add_secret_subkey (GpgmeKey key); struct subkey_s *_gpgme_key_add_secret_subkey (GpgmeKey key);
GpgmeError _gpgme_key_append_name ( GpgmeKey key, const char *s ); GpgmeError _gpgme_key_append_name ( GpgmeKey key, const char *s );

View File

@ -341,10 +341,12 @@ finish_key ( GpgmeCtx ctx )
{ {
GpgmeKey key = ctx->tmp_key; GpgmeKey key = ctx->tmp_key;
struct key_queue_item_s *q, *q2; struct key_queue_item_s *q, *q2;
assert (key); assert (key);
ctx->tmp_key = NULL; ctx->tmp_key = NULL;
_gpgme_key_cache_add (key);
q = xtrymalloc ( sizeof *q ); q = xtrymalloc ( sizeof *q );
if ( !q ) { if ( !q ) {
gpgme_key_release (key); gpgme_key_release (key);

View File

@ -1094,7 +1094,6 @@ read_status ( GpgObject gpg )
if ( *p == '\n' ) { if ( *p == '\n' ) {
/* (we require that the last line is terminated by a LF) */ /* (we require that the last line is terminated by a LF) */
*p = 0; *p = 0;
fflush (stdout); fprintf (stderr, "read_status: `%s'\n", buffer);
if (!strncmp (buffer, "[GNUPG:] ", 9 ) if (!strncmp (buffer, "[GNUPG:] ", 9 )
&& buffer[9] >= 'A' && buffer[9] <= 'Z' ) { && buffer[9] >= 'A' && buffer[9] <= 'Z' ) {
struct status_table_s t, *r; struct status_table_s t, *r;

View File

@ -28,6 +28,7 @@
#include "util.h" #include "util.h"
#include "context.h" #include "context.h"
#include "ops.h" #include "ops.h"
#include "key.h"
struct verify_result_s { struct verify_result_s {
struct verify_result_s *next; struct verify_result_s *next;
@ -219,7 +220,7 @@ gpgme_op_verify_start ( GpgmeCtx c, GpgmeData sig, GpgmeData text )
{ {
int rc = 0; int rc = 0;
int i; int i;
int pipemode = !!text; /* use pipemode for detached sigs */ int pipemode = 0; /*!!text; use pipemode for detached sigs */
fail_on_pending_request( c ); fail_on_pending_request( c );
c->pending = 1; c->pending = 1;
@ -414,8 +415,7 @@ GpgmeError
gpgme_get_sig_key (GpgmeCtx c, int idx, GpgmeKey *r_key) gpgme_get_sig_key (GpgmeCtx c, int idx, GpgmeKey *r_key)
{ {
VerifyResult res; VerifyResult res;
GpgmeCtx listctx; GpgmeError err = 0;
GpgmeError err;
if (!c || !r_key) if (!c || !r_key)
return mk_error (Invalid_Value); 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 */ if (strlen(res->fpr) < 16) /* we have at least an key ID */
return mk_error (Invalid_Key); return mk_error (Invalid_Key);
/* Fixme: This can me optimized keeping *r_key = _gpgme_key_cache_get (res->fpr);
* an internal context used for such key listings */ if (!*r_key) {
if ( (err=gpgme_new (&listctx)) ) GpgmeCtx 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);
/* 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; return err;
} }

View File

@ -30,7 +30,7 @@
#include "rungpg.h" #include "rungpg.h"
#include "sema.h" #include "sema.h"
#include "util.h" #include "util.h"
#include "key.h" /* for key_cache_init */
static int lineno; static int lineno;
static char *tmp_engine_version; static char *tmp_engine_version;
@ -46,6 +46,7 @@ do_subsystem_inits (void)
if (done) if (done)
return; return;
_gpgme_sema_subsystem_init (); _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 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_major == rq_major && my_minor == rq_minor
&& my_micro > rq_micro) && my_micro > rq_micro)
|| (my_major == rq_major && my_minor == rq_minor || (my_major == rq_major && my_minor == rq_minor
&& my_micro == rq_micro && my_micro == rq_micro
@ -173,7 +174,7 @@ gpgme_check_engine ()
s = strstr (info, "<version>"); s = strstr (info, "<version>");
if (s) { if (s) {
s += 9; s += 9;
s2 = strchr (s, '>'); s2 = strchr (s, '<');
if (s2) { if (s2) {
char *ver = xtrymalloc (s2 - s + 1); char *ver = xtrymalloc (s2 - s + 1);
if (!ver) if (!ver)

View File

@ -132,6 +132,7 @@ main (int argc, char **argv )
GpgmeData sig, text; GpgmeData sig, text;
GpgmeSigStat status; GpgmeSigStat status;
char *nota; char *nota;
int n = 0;
err = gpgme_new (&ctx); err = gpgme_new (&ctx);
fail_if_err (err); fail_if_err (err);
@ -166,6 +167,7 @@ main (int argc, char **argv )
fail_if_err (err); fail_if_err (err);
gpgme_data_rewind ( sig ); gpgme_data_rewind ( sig );
err = gpgme_op_verify (ctx, sig, text, &status ); err = gpgme_op_verify (ctx, sig, text, &status );
print_sig_stat ( ctx, status ); print_sig_stat ( ctx, status );
fail_if_err (err); fail_if_err (err);
if ( (nota=gpgme_get_notation (ctx)) ) if ( (nota=gpgme_get_notation (ctx)) )
@ -174,7 +176,7 @@ main (int argc, char **argv )
gpgme_data_release (sig); gpgme_data_release (sig);
gpgme_data_release (text); gpgme_data_release (text);
} while ( argc > 1 && !strcmp( argv[1], "--loop" ) ); } while ( argc > 1 && !strcmp( argv[1], "--loop" ) && ++n < 20 );
gpgme_release (ctx); gpgme_release (ctx);
return 0; return 0;