Changes by Jose and Tommy.
This commit is contained in:
parent
1a3db20121
commit
4c76d6dce1
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
195
gpgme/key.c
195
gpgme/key.c
@ -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 )
|
||||||
{
|
{
|
||||||
|
@ -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 );
|
||||||
|
@ -345,6 +345,8 @@ finish_key ( GpgmeCtx ctx )
|
|||||||
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);
|
||||||
|
@ -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;
|
||||||
|
@ -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,7 +430,11 @@ 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);
|
||||||
|
if (!*r_key) {
|
||||||
|
GpgmeCtx listctx;
|
||||||
|
|
||||||
|
/* Fixme: This can be optimized by keeping
|
||||||
* an internal context used for such key listings */
|
* an internal context used for such key listings */
|
||||||
if ( (err=gpgme_new (&listctx)) )
|
if ( (err=gpgme_new (&listctx)) )
|
||||||
return err;
|
return err;
|
||||||
@ -438,7 +442,7 @@ gpgme_get_sig_key (GpgmeCtx c, int idx, GpgmeKey *r_key)
|
|||||||
if ( !(err=gpgme_op_keylist_start (listctx, res->fpr, 0 )) )
|
if ( !(err=gpgme_op_keylist_start (listctx, res->fpr, 0 )) )
|
||||||
err=gpgme_op_keylist_next ( listctx, r_key );
|
err=gpgme_op_keylist_next ( listctx, r_key );
|
||||||
gpgme_release (listctx);
|
gpgme_release (listctx);
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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)
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user