aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2011-04-29 13:10:36 +0000
committerWerner Koch <[email protected]>2011-04-29 13:10:36 +0000
commitc36deeea8bb06ed62b33cfd23f57ea3bba8eddde (patch)
treeda8728c09089706dab6e44cf5c72bf9d00e05585
parentFix import stat counter and abort secret key import on merge-only error case. (diff)
parentRe-indentation of keydb.c and error code changes. (diff)
downloadgnupg-c36deeea8bb06ed62b33cfd23f57ea3bba8eddde.tar.gz
gnupg-c36deeea8bb06ed62b33cfd23f57ea3bba8eddde.zip
Merge branch 'wk-gpg-keybox'
-rw-r--r--g10/ChangeLog13
-rw-r--r--g10/export.c2
-rw-r--r--g10/getkey.c10
-rw-r--r--g10/keydb.c685
-rw-r--r--g10/keydb.h27
-rw-r--r--g10/keylist.c6
-rw-r--r--g10/keyserver.c4
-rw-r--r--g10/trustdb.c4
-rw-r--r--kbx/ChangeLog11
-rw-r--r--kbx/kbxutil.c16
-rw-r--r--kbx/keybox-openpgp.c119
11 files changed, 486 insertions, 411 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index cbd370614..b8d3232bb 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,16 @@
+2011-04-29 Werner Koch <[email protected]>
+
+ * keydb.c (keydb_get_keyblock, keydb_add_resource): Use gpg_error.
+ (keydb_get_keyblock): Return VALUE_NOT_FOUND instead of -1.
+ (keydb_update_keyblock, keydb_insert_keyblock)
+ (keydb_delete_keyblock): Ditto.
+ (keydb_locate_writable): Ditto.
+ (keydb_search_reset): Ditto.
+ (keydb_search2): Return GPG_ERR_NOT_FOUND instead of -1. Change
+ all callers.
+ (keydb_search_first, keydb_search_next, keydb_search_kid)
+ (keydb_search_fpr): Ditto.
+
2011-04-29 Marcus Brinkmann <[email protected]>
* import.c (import_secret_one): Leave all checks to import_one.
diff --git a/g10/export.c b/g10/export.c
index 2e35eea9f..1b575dd9e 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -1185,7 +1185,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
iobuf_put (out, ')');
iobuf_put (out, '\n');
}
- if (err == -1)
+ if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
err = 0;
leave:
diff --git a/g10/getkey.c b/g10/getkey.c
index 171f17781..b80695db4 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -431,7 +431,7 @@ get_pubkey_fast (PKT_public_key * pk, u32 * keyid)
hd = keydb_new ();
rc = keydb_search_kid (hd, keyid);
- if (rc == -1)
+ if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
{
keydb_release (hd);
return G10ERR_NO_PUBKEY;
@@ -992,7 +992,7 @@ get_pubkey_byfprint_fast (PKT_public_key * pk,
hd = keydb_new ();
rc = keydb_search_fpr (hd, fprbuf);
- if (rc == -1)
+ if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
{
keydb_release (hd);
return G10ERR_NO_PUBKEY;
@@ -2488,7 +2488,7 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret)
}
found:
- if (rc && rc != -1)
+ if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
log_error ("keydb_search failed: %s\n", g10_errstr (rc));
if (!rc)
@@ -2496,9 +2496,9 @@ found:
*ret_keyblock = ctx->keyblock; /* Return the keyblock. */
ctx->keyblock = NULL;
}
- else if (rc == -1 && no_suitable_key)
+ else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND && no_suitable_key)
rc = want_secret? G10ERR_UNU_SECKEY : G10ERR_UNU_PUBKEY;
- else if (rc == -1)
+ else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
rc = want_secret? G10ERR_NO_SECKEY : G10ERR_NO_PUBKEY;
release_kbnode (ctx->keyblock);
diff --git a/g10/keydb.c b/g10/keydb.c
index d9e01dced..f7642485a 100644
--- a/g10/keydb.c
+++ b/g10/keydb.c
@@ -1,6 +1,6 @@
/* keydb.c - key database dispatcher
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
- * 2008, 2009 Free Software Foundation, Inc.
+ * 2008, 2009, 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -39,10 +39,11 @@
static int active_handles;
-typedef enum {
+typedef enum
+ {
KEYDB_RESOURCE_TYPE_NONE = 0,
KEYDB_RESOURCE_TYPE_KEYRING
-} KeydbResourceType;
+ } KeydbResourceType;
#define MAX_KEYDB_RESOURCES 40
struct resource_item
@@ -58,11 +59,12 @@ static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
static int used_resources;
static void *primary_keyring=NULL;
-struct keydb_handle {
+struct keydb_handle
+{
int locked;
int found;
int current;
- int used; /* items in active */
+ int used; /* Number of items in ACTIVE. */
struct resource_item active[MAX_KEYDB_RESOURCES];
};
@@ -212,122 +214,132 @@ maybe_create_keyring (char *filename, int force)
* Flag 4 - This is a default resources.
* Flag 8 - Open as read-only.
*/
-int
+gpg_error_t
keydb_add_resource (const char *url, int flags)
{
- static int any_public;
- const char *resname = url;
- char *filename = NULL;
- int force = (flags&1);
- int read_only = !!(flags&8);
- int rc = 0;
- KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
- void *token;
-
- if (read_only)
- force = 0;
-
- /* Do we have an URL?
- * gnupg-ring:filename := this is a plain keyring
- * filename := See what is is, but create as plain keyring.
- */
- if (strlen (resname) > 11) {
- if (!strncmp( resname, "gnupg-ring:", 11) ) {
- rt = KEYDB_RESOURCE_TYPE_KEYRING;
- resname += 11;
+ static int any_public;
+ const char *resname = url;
+ char *filename = NULL;
+ int force = (flags&1);
+ int read_only = !!(flags&8);
+ int rc = 0;
+ KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
+ void *token;
+
+ if (read_only)
+ force = 0;
+
+ /* Do we have an URL?
+ * gnupg-ring:filename := this is a plain keyring
+ * filename := See what is is, but create as plain keyring.
+ */
+ if (strlen (resname) > 11)
+ {
+ if (!strncmp( resname, "gnupg-ring:", 11) )
+ {
+ rt = KEYDB_RESOURCE_TYPE_KEYRING;
+ resname += 11;
}
#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
- else if (strchr (resname, ':')) {
- log_error ("invalid key resource URL `%s'\n", url );
- rc = G10ERR_GENERAL;
- goto leave;
- }
+ else if (strchr (resname, ':'))
+ {
+ log_error ("invalid key resource URL `%s'\n", url );
+ rc = gpg_error (GPG_ERR_GENERAL);
+ goto leave;
+ }
#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
}
- if (*resname != DIRSEP_C ) { /* do tilde expansion etc */
- if (strchr(resname, DIRSEP_C) )
- filename = make_filename (resname, NULL);
- else
- filename = make_filename (opt.homedir, resname, NULL);
+ if (*resname != DIRSEP_C )
+ {
+ /* Do tilde expansion etc. */
+ if (strchr(resname, DIRSEP_C) )
+ filename = make_filename (resname, NULL);
+ else
+ filename = make_filename (opt.homedir, resname, NULL);
}
- else
- filename = xstrdup (resname);
-
- if (!force && !read_only)
- force = !any_public;
+ else
+ filename = xstrdup (resname);
- /* See whether we can determine the filetype. */
- if (rt == KEYDB_RESOURCE_TYPE_NONE) {
- FILE *fp = fopen( filename, "rb" );
+ if (!force && !read_only)
+ force = !any_public;
- if (fp) {
- u32 magic;
+ /* See whether we can determine the filetype. */
+ if (rt == KEYDB_RESOURCE_TYPE_NONE)
+ {
+ FILE *fp = fopen (filename, "rb");
- if (fread( &magic, 4, 1, fp) == 1 ) {
- if (magic == 0x13579ace || magic == 0xce9a5713)
- ; /* GDBM magic - no more support */
- else
- rt = KEYDB_RESOURCE_TYPE_KEYRING;
+ if (fp)
+ {
+ u32 magic;
+
+ if (fread( &magic, 4, 1, fp) == 1 )
+ {
+ if (magic == 0x13579ace || magic == 0xce9a5713)
+ ; /* GDBM magic - not anymore supported. */
+ else
+ rt = KEYDB_RESOURCE_TYPE_KEYRING;
}
- else /* maybe empty: assume ring */
- rt = KEYDB_RESOURCE_TYPE_KEYRING;
- fclose( fp );
+ else /* Maybe empty: assume keyring. */
+ rt = KEYDB_RESOURCE_TYPE_KEYRING;
+
+ fclose( fp );
}
- else /* no file yet: create ring */
- rt = KEYDB_RESOURCE_TYPE_KEYRING;
+ else /* No file yet: create keyring. */
+ rt = KEYDB_RESOURCE_TYPE_KEYRING;
}
- switch (rt) {
- case KEYDB_RESOURCE_TYPE_NONE:
- log_error ("unknown type of key resource `%s'\n", url );
- rc = G10ERR_GENERAL;
- goto leave;
+ switch (rt)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ log_error ("unknown type of key resource `%s'\n", url );
+ rc = gpg_error (GPG_ERR_GENERAL);
+ goto leave;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = maybe_create_keyring (filename, force);
- if (rc)
- goto leave;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ rc = maybe_create_keyring (filename, force);
+ if (rc)
+ goto leave;
- if(keyring_register_filename (filename, read_only, &token))
- {
- if (used_resources >= MAX_KEYDB_RESOURCES)
- rc = G10ERR_RESOURCE_LIMIT;
- else
- {
- if(flags&2)
- primary_keyring=token;
- all_resources[used_resources].type = rt;
- all_resources[used_resources].u.kr = NULL; /* Not used here */
- all_resources[used_resources].token = token;
- used_resources++;
- }
- }
- else
- {
- /* This keyring was already registered, so ignore it.
- However, we can still mark it as primary even if it was
- already registered. */
- if(flags&2)
- primary_keyring=token;
- }
- break;
+ if (keyring_register_filename (filename, read_only, &token))
+ {
+ if (used_resources >= MAX_KEYDB_RESOURCES)
+ rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
+ else
+ {
+ if (flags&2)
+ primary_keyring = token;
+ all_resources[used_resources].type = rt;
+ all_resources[used_resources].u.kr = NULL; /* Not used here */
+ all_resources[used_resources].token = token;
+ used_resources++;
+ }
+ }
+ else
+ {
+ /* This keyring was already registered, so ignore it.
+ However, we can still mark it as primary even if it was
+ already registered. */
+ if (flags&2)
+ primary_keyring = token;
+ }
+ break;
default:
log_error ("resource type of `%s' not supported\n", url);
- rc = G10ERR_GENERAL;
+ rc = gpg_error (GPG_ERR_GENERAL);
goto leave;
}
/* fixme: check directory permissions and print a warning */
- leave:
- if (rc)
- log_error (_("keyblock resource `%s': %s\n"), filename, g10_errstr(rc));
- else
- any_public = 1;
- xfree (filename);
- return rc;
+ leave:
+ if (rc)
+ log_error (_("keyblock resource `%s': %s\n"), filename, gpg_strerror (rc));
+ else
+ any_public = 1;
+ xfree (filename);
+ return rc;
}
@@ -370,25 +382,27 @@ keydb_new (void)
void
keydb_release (KEYDB_HANDLE hd)
{
- int i;
-
- if (!hd)
- return;
- assert (active_handles > 0);
- active_handles--;
-
- unlock_all (hd);
- for (i=0; i < hd->used; i++) {
- switch (hd->active[i].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- keyring_release (hd->active[i].u.kr);
- break;
+ int i;
+
+ if (!hd)
+ return;
+ assert (active_handles > 0);
+ active_handles--;
+
+ unlock_all (hd);
+ for (i=0; i < hd->used; i++)
+ {
+ switch (hd->active[i].type)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ break;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ keyring_release (hd->active[i].u.kr);
+ break;
}
}
- xfree (hd);
+ xfree (hd);
}
@@ -403,29 +417,30 @@ keydb_release (KEYDB_HANDLE hd)
const char *
keydb_get_resource_name (KEYDB_HANDLE hd)
{
- int idx;
- const char *s = NULL;
-
- if (!hd)
- return NULL;
-
- if ( hd->found >= 0 && hd->found < hd->used)
- idx = hd->found;
- else if ( hd->current >= 0 && hd->current < hd->used)
- idx = hd->current;
- else
- idx = 0;
-
- switch (hd->active[idx].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- s = NULL;
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- s = keyring_get_resource_name (hd->active[idx].u.kr);
- break;
+ int idx;
+ const char *s = NULL;
+
+ if (!hd)
+ return NULL;
+
+ if ( hd->found >= 0 && hd->found < hd->used)
+ idx = hd->found;
+ else if ( hd->current >= 0 && hd->current < hd->used)
+ idx = hd->current;
+ else
+ idx = 0;
+
+ switch (hd->active[idx].type)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ s = NULL;
+ break;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ s = keyring_get_resource_name (hd->active[idx].u.kr);
+ break;
}
- return s? s: "";
+ return s? s: "";
}
@@ -433,54 +448,62 @@ keydb_get_resource_name (KEYDB_HANDLE hd)
static int
lock_all (KEYDB_HANDLE hd)
{
- int i, rc = 0;
-
- for (i=0; !rc && i < hd->used; i++) {
- switch (hd->active[i].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_lock (hd->active[i].u.kr, 1);
- break;
+ int i, rc = 0;
+
+ for (i=0; !rc && i < hd->used; i++)
+ {
+ switch (hd->active[i].type)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ break;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ rc = keyring_lock (hd->active[i].u.kr, 1);
+ break;
}
}
- if (rc) {
- /* revert the already set locks */
- for (i--; i >= 0; i--) {
- switch (hd->active[i].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- keyring_lock (hd->active[i].u.kr, 0);
- break;
+ if (rc)
+ {
+ /* Revert the already set locks. */
+ for (i--; i >= 0; i--)
+ {
+ switch (hd->active[i].type)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ break;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ keyring_lock (hd->active[i].u.kr, 0);
+ break;
}
}
}
- else
- hd->locked = 1;
+ else
+ hd->locked = 1;
- return rc;
+ return rc;
}
+
static void
unlock_all (KEYDB_HANDLE hd)
{
- int i;
-
- if (!hd->locked)
- return;
-
- for (i=hd->used-1; i >= 0; i--) {
- switch (hd->active[i].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- keyring_lock (hd->active[i].u.kr, 0);
- break;
+ int i;
+
+ if (!hd->locked)
+ return;
+
+ for (i=hd->used-1; i >= 0; i--)
+ {
+ switch (hd->active[i].type)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ break;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ keyring_lock (hd->active[i].u.kr, 0);
+ break;
}
}
- hd->locked = 0;
+ hd->locked = 0;
}
@@ -490,148 +513,153 @@ unlock_all (KEYDB_HANDLE hd)
* the public key used to locate the keyblock or flag bit 1 set for
* the user ID node.
*/
-int
+gpg_error_t
keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
{
- int rc = 0;
+ gpg_error_t err = 0;
- if (!hd)
- return G10ERR_INV_ARG;
+ if (!hd)
+ return gpg_error (GPG_ERR_INV_ARG);
- if ( hd->found < 0 || hd->found >= hd->used)
- return -1; /* nothing found */
+ if (hd->found < 0 || hd->found >= hd->used)
+ return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
- switch (hd->active[hd->found].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- rc = G10ERR_GENERAL; /* oops */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
- break;
+ switch (hd->active[hd->found].type)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ err = gpg_error (GPG_ERR_GENERAL); /* oops */
+ break;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ err = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
+ break;
}
- return rc;
+ return err;
}
/*
- * update the current keyblock with KB
+ * Update the current keyblock with the keyblock KB
*/
-int
-keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
+gpg_error_t
+keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
{
- int rc = 0;
+ gpg_error_t rc;
- if (!hd)
- return G10ERR_INV_ARG;
+ if (!hd)
+ return gpg_error (GPG_ERR_INV_ARG);
- if ( hd->found < 0 || hd->found >= hd->used)
- return -1; /* nothing found */
+ if (hd->found < 0 || hd->found >= hd->used)
+ return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
- if( opt.dry_run )
- return 0;
+ if (opt.dry_run)
+ return 0;
- rc = lock_all (hd);
- if (rc)
- return rc;
+ rc = lock_all (hd);
+ if (rc)
+ return rc;
- switch (hd->active[hd->found].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- rc = G10ERR_GENERAL; /* oops */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
- break;
+ switch (hd->active[hd->found].type)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ rc = gpg_error (GPG_ERR_GENERAL); /* oops */
+ break;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
+ break;
}
- unlock_all (hd);
- return rc;
+ unlock_all (hd);
+ return rc;
}
/*
* Insert a new KB into one of the resources.
*/
-int
-keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
+gpg_error_t
+keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
{
- int rc = -1;
- int idx;
-
- if (!hd)
- return G10ERR_INV_ARG;
-
- if( opt.dry_run )
- return 0;
-
- if ( hd->found >= 0 && hd->found < hd->used)
- idx = hd->found;
- else if ( hd->current >= 0 && hd->current < hd->used)
- idx = hd->current;
- else
- return G10ERR_GENERAL;
-
- rc = lock_all (hd);
- if (rc)
- return rc;
-
- switch (hd->active[idx].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- rc = G10ERR_GENERAL; /* oops */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
- break;
- }
+ int rc;
+ int idx;
+
+ if (!hd)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ if (opt.dry_run)
+ return 0;
+
+ if (hd->found >= 0 && hd->found < hd->used)
+ idx = hd->found;
+ else if (hd->current >= 0 && hd->current < hd->used)
+ idx = hd->current;
+ else
+ return gpg_error (GPG_ERR_GENERAL);
- unlock_all (hd);
+ rc = lock_all (hd);
+ if (rc)
return rc;
+
+ switch (hd->active[idx].type)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ rc = gpg_error (GPG_ERR_GENERAL); /* oops */
+ break;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
+ break;
+ }
+
+ unlock_all (hd);
+ return rc;
}
/*
- * The current keyblock will be deleted.
+ * Delete the current keyblock.
*/
-int
+gpg_error_t
keydb_delete_keyblock (KEYDB_HANDLE hd)
{
- int rc = -1;
+ gpg_error_t rc;
- if (!hd)
- return G10ERR_INV_ARG;
+ if (!hd)
+ return gpg_error (GPG_ERR_INV_ARG);
- if ( hd->found < 0 || hd->found >= hd->used)
- return -1; /* nothing found */
+ if (hd->found < 0 || hd->found >= hd->used)
+ return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
- if( opt.dry_run )
- return 0;
+ if (opt.dry_run)
+ return 0;
- rc = lock_all (hd);
- if (rc)
- return rc;
+ rc = lock_all (hd);
+ if (rc)
+ return rc;
- switch (hd->active[hd->found].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- rc = G10ERR_GENERAL; /* oops */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
- break;
+ switch (hd->active[hd->found].type)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ rc = gpg_error (GPG_ERR_GENERAL);
+ break;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
+ break;
}
- unlock_all (hd);
- return rc;
+ unlock_all (hd);
+ return rc;
}
+
/*
* Locate the default writable key resource, so that the next
* operation (which is only relevant for inserts) will be done on this
* resource.
*/
-int
+gpg_error_t
keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
{
- int rc;
+ gpg_error_t rc;
(void)reserved;
@@ -643,7 +671,7 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
return rc;
/* If we have a primary set, try that one first */
- if(primary_keyring)
+ if (primary_keyring)
{
for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
{
@@ -675,7 +703,7 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
}
}
- return -1;
+ return gpg_error (GPG_ERR_NOT_FOUND);
}
/*
@@ -709,101 +737,116 @@ keydb_rebuild_caches (int noisy)
/*
* Start the next search on this handle right at the beginning
*/
-int
+gpg_error_t
keydb_search_reset (KEYDB_HANDLE hd)
{
- int i, rc = 0;
-
- if (!hd)
- return G10ERR_INV_ARG;
-
- hd->current = 0;
- hd->found = -1;
- /* and reset all resources */
- for (i=0; !rc && i < hd->used; i++) {
- switch (hd->active[i].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_search_reset (hd->active[i].u.kr);
- break;
+ gpg_error_t rc = 0;
+ int i;
+
+ if (!hd)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ hd->current = 0;
+ hd->found = -1;
+ /* Now reset all resources. */
+ for (i=0; !rc && i < hd->used; i++)
+ {
+ switch (hd->active[i].type)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ break;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ rc = keyring_search_reset (hd->active[i].u.kr);
+ break;
}
}
- return rc;
+ return rc;
}
/*
- * Search through all keydb resources, starting at the current position,
- * for a keyblock which contains one of the keys described in the DESC array.
+ * Search through all keydb resources, starting at the current
+ * position, for a keyblock which contains one of the keys described
+ * in the DESC array. Returns GPG_ERR_NOT_FOUND if no matching
+ * keyring was found.
*/
-int
+gpg_error_t
keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
size_t ndesc, size_t *descindex)
{
- int rc = -1;
-
- if (!hd)
- return G10ERR_INV_ARG;
-
- while (rc == -1 && hd->current >= 0 && hd->current < hd->used) {
- switch (hd->active[hd->current].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- BUG(); /* we should never see it here */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_search (hd->active[hd->current].u.kr, desc,
- ndesc, descindex);
- break;
+ gpg_error_t rc;
+
+ if (!hd)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ rc = -1;
+ while ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
+ && hd->current >= 0 && hd->current < hd->used)
+ {
+ switch (hd->active[hd->current].type)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ BUG(); /* we should never see it here */
+ break;
+ case KEYDB_RESOURCE_TYPE_KEYRING:
+ rc = keyring_search (hd->active[hd->current].u.kr, desc,
+ ndesc, descindex);
+ break;
}
- if (rc == -1) /* EOF -> switch to next resource */
- hd->current++;
- else if (!rc)
- hd->found = hd->current;
+ if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
+ {
+ /* EOF -> switch to next resource */
+ hd->current++;
+ }
+ else if (!rc)
+ hd->found = hd->current;
}
- return rc;
+ return ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
+ ? gpg_error (GPG_ERR_NOT_FOUND)
+ : rc);
}
-int
+
+gpg_error_t
keydb_search_first (KEYDB_HANDLE hd)
{
- KEYDB_SEARCH_DESC desc;
+ KEYDB_SEARCH_DESC desc;
- memset (&desc, 0, sizeof desc);
- desc.mode = KEYDB_SEARCH_MODE_FIRST;
- return keydb_search (hd, &desc, 1);
+ memset (&desc, 0, sizeof desc);
+ desc.mode = KEYDB_SEARCH_MODE_FIRST;
+ return keydb_search (hd, &desc, 1);
}
-int
+gpg_error_t
keydb_search_next (KEYDB_HANDLE hd)
{
- KEYDB_SEARCH_DESC desc;
+ KEYDB_SEARCH_DESC desc;
- memset (&desc, 0, sizeof desc);
- desc.mode = KEYDB_SEARCH_MODE_NEXT;
- return keydb_search (hd, &desc, 1);
+ memset (&desc, 0, sizeof desc);
+ desc.mode = KEYDB_SEARCH_MODE_NEXT;
+ return keydb_search (hd, &desc, 1);
}
-int
+gpg_error_t
keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
{
- KEYDB_SEARCH_DESC desc;
+ KEYDB_SEARCH_DESC desc;
- memset (&desc, 0, sizeof desc);
- desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
- desc.u.kid[0] = kid[0];
- desc.u.kid[1] = kid[1];
- return keydb_search (hd, &desc, 1);
+ memset (&desc, 0, sizeof desc);
+ desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
+ desc.u.kid[0] = kid[0];
+ desc.u.kid[1] = kid[1];
+ return keydb_search (hd, &desc, 1);
}
-int
+gpg_error_t
keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
{
- KEYDB_SEARCH_DESC desc;
+ KEYDB_SEARCH_DESC desc;
- memset (&desc, 0, sizeof desc);
- desc.mode = KEYDB_SEARCH_MODE_FPR;
- memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
- return keydb_search (hd, &desc, 1);
+ memset (&desc, 0, sizeof desc);
+ desc.mode = KEYDB_SEARCH_MODE_FPR;
+ memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
+ return keydb_search (hd, &desc, 1);
}
diff --git a/g10/keydb.h b/g10/keydb.h
index f3a95297a..22c2b673e 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -132,25 +132,24 @@ union pref_hint
Flag 1 == force
Flag 2 == default
*/
-int keydb_add_resource (const char *url, int flags);
+gpg_error_t keydb_add_resource (const char *url, int flags);
KEYDB_HANDLE keydb_new (void);
void keydb_release (KEYDB_HANDLE hd);
const char *keydb_get_resource_name (KEYDB_HANDLE hd);
-int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
-int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb);
-int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb);
-int keydb_delete_keyblock (KEYDB_HANDLE hd);
-int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved);
+gpg_error_t keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
+gpg_error_t keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb);
+gpg_error_t keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb);
+gpg_error_t keydb_delete_keyblock (KEYDB_HANDLE hd);
+gpg_error_t keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved);
void keydb_rebuild_caches (int noisy);
-int keydb_search_reset (KEYDB_HANDLE hd);
+gpg_error_t keydb_search_reset (KEYDB_HANDLE hd);
#define keydb_search(a,b,c) keydb_search2((a),(b),(c),NULL)
-int keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
- size_t ndesc, size_t *descindex);
-int keydb_search_first (KEYDB_HANDLE hd);
-int keydb_search_next (KEYDB_HANDLE hd);
-int keydb_search_kid (KEYDB_HANDLE hd, u32 *kid);
-int keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr);
-
+gpg_error_t keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
+ size_t ndesc, size_t *descindex);
+gpg_error_t keydb_search_first (KEYDB_HANDLE hd);
+gpg_error_t keydb_search_next (KEYDB_HANDLE hd);
+gpg_error_t keydb_search_kid (KEYDB_HANDLE hd, u32 *kid);
+gpg_error_t keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr);
/*-- pkclist.c --*/
void show_revocation_reason( PKT_public_key *pk, int mode );
diff --git a/g10/keylist.c b/g10/keylist.c
index db7467d3d..f6b8cffb2 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -434,12 +434,12 @@ list_all (int secret)
hd = keydb_new ();
if (!hd)
- rc = G10ERR_GENERAL;
+ rc = gpg_error (GPG_ERR_GENERAL);
else
rc = keydb_search_first (hd);
if (rc)
{
- if (rc != -1)
+ if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
log_error ("keydb_search_first failed: %s\n", g10_errstr (rc));
goto leave;
}
@@ -479,7 +479,7 @@ list_all (int secret)
keyblock = NULL;
}
while (!(rc = keydb_search_next (hd)));
- if (rc && rc != -1)
+ if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
log_error ("keydb_search_next failed: %s\n", g10_errstr (rc));
if (opt.check_sigs && !opt.with_colons)
diff --git a/g10/keyserver.c b/g10/keyserver.c
index 5cc7438ad..68dd15567 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -1236,8 +1236,8 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
}
}
- if(rc==-1)
- rc=0;
+ if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
+ rc = 0;
leave:
if(rc)
diff --git a/g10/trustdb.c b/g10/trustdb.c
index c6ff6922d..006db04f4 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -2107,7 +2107,7 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
desc.skipfnc = search_skipfnc;
desc.skipfncvalue = full_trust;
rc = keydb_search (hd, &desc, 1);
- if (rc == -1)
+ if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
{
keys[nkeys].keyblock = NULL;
return keys;
@@ -2181,7 +2181,7 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
keyblock = NULL;
}
while ( !(rc = keydb_search (hd, &desc, 1)) );
- if (rc && rc != -1)
+ if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
{
log_error ("keydb_search_next failed: %s\n", g10_errstr(rc));
xfree (keys);
diff --git a/kbx/ChangeLog b/kbx/ChangeLog
index 947aaaa43..9e77118a5 100644
--- a/kbx/ChangeLog
+++ b/kbx/ChangeLog
@@ -1,3 +1,12 @@
+2011-04-28 Werner Koch <[email protected]>
+
+ * keybox-openpgp.c: Include ../common/openpgpdefs.h.
+ (enum packet_types): Remove.
+ (_keybox_parse_openpgp): Update NPARSED also on errors.
+ (parse_key): Take care of ecc algorithms.
+ * kbxutil.c (import_openpgp): Do not print an error for non-RSA v3
+ packets.
+
2010-07-23 Werner Koch <[email protected]>
* keybox-blob.c (_keybox_create_x509_blob): Fix reallocation bug.
@@ -365,7 +374,7 @@
Copyright 2001, 2002, 2003, 2004, 2005, 2006,
- 2007, 2008 Free Software Foundation, Inc.
+ 2007, 2008, 2011 Free Software Foundation, Inc.
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c
index b1fd3348d..333c28695 100644
--- a/kbx/kbxutil.c
+++ b/kbx/kbxutil.c
@@ -1,5 +1,5 @@
/* kbxutil.c - The Keybox utility
- * Copyright (C) 2000, 2001, 2004, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2000, 2001, 2004, 2007, 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -389,8 +389,18 @@ import_openpgp (const char *filename)
{
if (gpg_err_code (err) == GPG_ERR_NO_DATA)
break;
- log_info ("%s: failed to parse OpenPGP keyblock: %s\n",
- filename, gpg_strerror (err));
+ if (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
+ {
+ /* This is likely a v3 key packet with a non-RSA
+ algorithm. These are keys from very early versions
+ of GnuPG (pre-OpenPGP). */
+ }
+ else
+ {
+ fflush (stdout);
+ log_info ("%s: failed to parse OpenPGP keyblock: %s\n",
+ filename, gpg_strerror (err));
+ }
}
else
{
diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c
index 30f99ecc8..4306ed1b0 100644
--- a/kbx/keybox-openpgp.c
+++ b/kbx/keybox-openpgp.c
@@ -1,5 +1,5 @@
/* keybox-openpgp.c - OpenPGP key parsing
- * Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -35,41 +35,16 @@
#include <gcrypt.h>
-
-enum packet_types
- {
- PKT_NONE =0,
- PKT_PUBKEY_ENC =1, /* public key encrypted packet */
- PKT_SIGNATURE =2, /* secret key encrypted packet */
- PKT_SYMKEY_ENC =3, /* session key packet (OpenPGP)*/
- PKT_ONEPASS_SIG =4, /* one pass sig packet (OpenPGP)*/
- PKT_SECRET_KEY =5, /* secret key */
- PKT_PUBLIC_KEY =6, /* public key */
- PKT_SECRET_SUBKEY =7, /* secret subkey (OpenPGP) */
- PKT_COMPRESSED =8, /* compressed data packet */
- PKT_ENCRYPTED =9, /* conventional encrypted data */
- PKT_MARKER =10, /* marker packet (OpenPGP) */
- PKT_PLAINTEXT =11, /* plaintext data with filename and mode */
- PKT_RING_TRUST =12, /* keyring trust packet */
- PKT_USER_ID =13, /* user id packet */
- PKT_PUBLIC_SUBKEY =14, /* public subkey (OpenPGP) */
- PKT_OLD_COMMENT =16, /* comment packet from an OpenPGP draft */
- PKT_ATTRIBUTE =17, /* PGP's attribute packet */
- PKT_ENCRYPTED_MDC =18, /* integrity protected encrypted data */
- PKT_MDC =19, /* manipulation detection code packet */
- PKT_COMMENT =61, /* new comment packet (private) */
- PKT_GPG_CONTROL =63 /* internal control packet */
- };
-
+#include "../common/openpgpdefs.h"
/* Assume a valid OpenPGP packet at the address pointed to by BUFBTR
- which is of amaximum length as stored at BUFLEN. Return the header
+ which has a maximum length as stored at BUFLEN. Return the header
information of that packet and advance the pointer stored at BUFPTR
to the next packet; also adjust the length stored at BUFLEN to
match the remaining bytes. If there are no more packets, store NULL
at BUFPTR. Return an non-zero error code on failure or the
- follwing data on success:
+ following data on success:
R_DATAPKT = Pointer to the begin of the packet data.
R_DATALEN = Length of this data. This has already been checked to fit
@@ -166,8 +141,8 @@ next_packet (unsigned char const **bufptr, size_t *buflen,
return gpg_error (GPG_ERR_UNEXPECTED);
}
- if (pktlen == 0xffffffff)
- return gpg_error (GPG_ERR_INV_PACKET);
+ if (pktlen == (unsigned long)(-1))
+ return gpg_error (GPG_ERR_INV_PACKET);
if (pktlen > len)
return gpg_error (GPG_ERR_INV_PACKET); /* Packet length header too long. */
@@ -201,6 +176,7 @@ parse_key (const unsigned char *data, size_t datalen,
const unsigned char *mpi_n = NULL;
size_t mpi_n_len = 0, mpi_e_len = 0;
gcry_md_hd_t md;
+ int is_ecc = 0;
if (datalen < 5)
return gpg_error (GPG_ERR_INV_PACKET);
@@ -219,7 +195,6 @@ parse_key (const unsigned char *data, size_t datalen,
return gpg_error (GPG_ERR_INV_PACKET);
ndays = ((data[0]<<8)|(data[1]));
data +=2; datalen -= 2;
- if (ndays)
expiredate = ndays? (timestamp + ndays * 86400L) : 0;
}
else
@@ -245,9 +220,11 @@ parse_key (const unsigned char *data, size_t datalen,
break;
case 18: /* ECDH */
npkey = 3;
+ is_ecc = 1;
break;
case 19: /* ECDSA */
npkey = 2;
+ is_ecc = 1;
break;
default: /* Unknown algorithm. */
return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
@@ -259,20 +236,34 @@ parse_key (const unsigned char *data, size_t datalen,
if (datalen < 2)
return gpg_error (GPG_ERR_INV_PACKET);
- nbits = ((data[0]<<8)|(data[1]));
- data += 2; datalen -=2;
- nbytes = (nbits+7) / 8;
- if (datalen < nbytes)
- return gpg_error (GPG_ERR_INV_PACKET);
- /* For use by v3 fingerprint calculation we need to know the RSA
- modulus and exponent. */
- if (i==0)
+
+ if (is_ecc && (i == 0 || i == 2))
{
- mpi_n = data;
- mpi_n_len = nbytes;
+ nbytes = data[0];
+ if (nbytes < 2 || nbytes > 254)
+ return gpg_error (GPG_ERR_INV_PACKET);
+ nbytes++; /* The size byte itself. */
+ if (datalen < nbytes)
+ return gpg_error (GPG_ERR_INV_PACKET);
+ }
+ else
+ {
+ nbits = ((data[0]<<8)|(data[1]));
+ data += 2;
+ datalen -= 2;
+ nbytes = (nbits+7) / 8;
+ if (datalen < nbytes)
+ return gpg_error (GPG_ERR_INV_PACKET);
+ /* For use by v3 fingerprint calculation we need to know the RSA
+ modulus and exponent. */
+ if (i==0)
+ {
+ mpi_n = data;
+ mpi_n_len = nbytes;
+ }
+ else if (i==1)
+ mpi_e_len = nbytes;
}
- else if (i==1)
- mpi_e_len = nbytes;
data += nbytes; datalen -= nbytes;
}
@@ -297,7 +288,7 @@ parse_key (const unsigned char *data, size_t datalen,
if (mpi_n_len < 8)
{
/* Moduli less than 64 bit are out of the specs scope. Zero
- them out becuase this is what gpg does too. */
+ them out because this is what gpg does too. */
memset (ki->keyid, 0, 8);
}
else
@@ -307,10 +298,10 @@ parse_key (const unsigned char *data, size_t datalen,
{
/* Its a pitty that we need to prefix the buffer with the tag
and a length header: We can't simply pass it to the fast
- hashing fucntion for that reason. It might be a good idea to
+ hashing function for that reason. It might be a good idea to
have a scatter-gather enabled hash function. What we do here
is to use a static buffer if this one is large enough and
- only use the regular hash fucntions if this buffer is not
+ only use the regular hash functions if this buffer is not
large enough. */
if ( 3 + n < sizeof hashbuffer )
{
@@ -344,19 +335,19 @@ parse_key (const unsigned char *data, size_t datalen,
/* The caller must pass the address of an INFO structure which will
get filled on success with information pertaining to the OpenPGP
keyblock IMAGE of length IMAGELEN. Note that a caller does only
- need to release this INFO structure when the function returns
+ need to release this INFO structure if the function returns
success. If NPARSED is not NULL the actual number of bytes parsed
will be stored at this address. */
gpg_error_t
_keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
- size_t *nparsed,
- keybox_openpgp_info_t info)
+ size_t *nparsed, keybox_openpgp_info_t info)
{
gpg_error_t err = 0;
const unsigned char *image_start, *data;
size_t n, datalen;
int pkttype;
int first = 1;
+ int read_error = 0;
struct _keybox_openpgp_key_info *k, **ktail = NULL;
struct _keybox_openpgp_uid_info *u, **utail = NULL;
@@ -369,7 +360,10 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
{
err = next_packet (&image, &imagelen, &data, &datalen, &pkttype, &n);
if (err)
- break;
+ {
+ read_error = 1;
+ break;
+ }
if (first)
{
@@ -380,6 +374,8 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
else
{
err = gpg_error (GPG_ERR_UNEXPECTED);
+ if (nparsed)
+ *nparsed += n;
break;
}
first = 0;
@@ -439,9 +435,12 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
if (err)
{
info->nsubkeys--;
- if (gpg_err_code (err) != GPG_ERR_UNKNOWN_ALGORITHM)
- break;
/* We ignore subkeys with unknown algorithms. */
+ if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM
+ || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
+ err = 0;
+ if (err)
+ break;
}
else
ktail = &info->subkeys.next;
@@ -459,9 +458,12 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
{
xfree (k);
info->nsubkeys--;
- if (gpg_err_code (err) != GPG_ERR_UNKNOWN_ALGORITHM)
- break;
/* We ignore subkeys with unknown algorithms. */
+ if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM
+ || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
+ err = 0;
+ if (err)
+ break;
}
else
{
@@ -475,11 +477,10 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
if (err)
{
_keybox_destroy_openpgp_info (info);
- if (!first
- && (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM
- || gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM))
+ if (!read_error)
{
- /* We are able to skip to the end of this keyblock. */
+ /* Packet parsing worked, thus we should be able to skip the
+ rest of the keyblock. */
while (image)
{
if (next_packet (&image, &imagelen,