1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-29 02:22:45 +02:00

Merge branch 'wk-gpg-keybox'

This commit is contained in:
Werner Koch 2011-04-29 15:10:36 +02:00
commit c36deeea8b
11 changed files with 466 additions and 391 deletions

View File

@ -1,3 +1,16 @@
2011-04-29 Werner Koch <wk@g10code.com>
* 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 <marcus@g10code.com> 2011-04-29 Marcus Brinkmann <marcus@g10code.com>
* import.c (import_secret_one): Leave all checks to import_one. * import.c (import_secret_one): Leave all checks to import_one.

View File

@ -1185,7 +1185,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
iobuf_put (out, ')'); iobuf_put (out, ')');
iobuf_put (out, '\n'); iobuf_put (out, '\n');
} }
if (err == -1) if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
err = 0; err = 0;
leave: leave:

View File

@ -431,7 +431,7 @@ get_pubkey_fast (PKT_public_key * pk, u32 * keyid)
hd = keydb_new (); hd = keydb_new ();
rc = keydb_search_kid (hd, keyid); rc = keydb_search_kid (hd, keyid);
if (rc == -1) if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
{ {
keydb_release (hd); keydb_release (hd);
return G10ERR_NO_PUBKEY; return G10ERR_NO_PUBKEY;
@ -992,7 +992,7 @@ get_pubkey_byfprint_fast (PKT_public_key * pk,
hd = keydb_new (); hd = keydb_new ();
rc = keydb_search_fpr (hd, fprbuf); rc = keydb_search_fpr (hd, fprbuf);
if (rc == -1) if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
{ {
keydb_release (hd); keydb_release (hd);
return G10ERR_NO_PUBKEY; return G10ERR_NO_PUBKEY;
@ -2488,7 +2488,7 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret)
} }
found: 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)); log_error ("keydb_search failed: %s\n", g10_errstr (rc));
if (!rc) if (!rc)
@ -2496,9 +2496,9 @@ found:
*ret_keyblock = ctx->keyblock; /* Return the keyblock. */ *ret_keyblock = ctx->keyblock; /* Return the keyblock. */
ctx->keyblock = NULL; 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; 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; rc = want_secret? G10ERR_NO_SECKEY : G10ERR_NO_PUBKEY;
release_kbnode (ctx->keyblock); release_kbnode (ctx->keyblock);

View File

@ -1,6 +1,6 @@
/* keydb.c - key database dispatcher /* keydb.c - key database dispatcher
* Copyright (C) 2001, 2002, 2003, 2004, 2005, * 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. * This file is part of GnuPG.
* *
@ -39,10 +39,11 @@
static int active_handles; static int active_handles;
typedef enum { typedef enum
{
KEYDB_RESOURCE_TYPE_NONE = 0, KEYDB_RESOURCE_TYPE_NONE = 0,
KEYDB_RESOURCE_TYPE_KEYRING KEYDB_RESOURCE_TYPE_KEYRING
} KeydbResourceType; } KeydbResourceType;
#define MAX_KEYDB_RESOURCES 40 #define MAX_KEYDB_RESOURCES 40
struct resource_item struct resource_item
@ -58,11 +59,12 @@ static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
static int used_resources; static int used_resources;
static void *primary_keyring=NULL; static void *primary_keyring=NULL;
struct keydb_handle { struct keydb_handle
{
int locked; int locked;
int found; int found;
int current; int current;
int used; /* items in active */ int used; /* Number of items in ACTIVE. */
struct resource_item active[MAX_KEYDB_RESOURCES]; struct resource_item active[MAX_KEYDB_RESOURCES];
}; };
@ -212,7 +214,7 @@ maybe_create_keyring (char *filename, int force)
* Flag 4 - This is a default resources. * Flag 4 - This is a default resources.
* Flag 8 - Open as read-only. * Flag 8 - Open as read-only.
*/ */
int gpg_error_t
keydb_add_resource (const char *url, int flags) keydb_add_resource (const char *url, int flags)
{ {
static int any_public; static int any_public;
@ -231,21 +233,26 @@ keydb_add_resource (const char *url, int flags)
* gnupg-ring:filename := this is a plain keyring * gnupg-ring:filename := this is a plain keyring
* filename := See what is is, but create as plain keyring. * filename := See what is is, but create as plain keyring.
*/ */
if (strlen (resname) > 11) { if (strlen (resname) > 11)
if (!strncmp( resname, "gnupg-ring:", 11) ) { {
if (!strncmp( resname, "gnupg-ring:", 11) )
{
rt = KEYDB_RESOURCE_TYPE_KEYRING; rt = KEYDB_RESOURCE_TYPE_KEYRING;
resname += 11; resname += 11;
} }
#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__) #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
else if (strchr (resname, ':')) { else if (strchr (resname, ':'))
{
log_error ("invalid key resource URL `%s'\n", url ); log_error ("invalid key resource URL `%s'\n", url );
rc = G10ERR_GENERAL; rc = gpg_error (GPG_ERR_GENERAL);
goto leave; goto leave;
} }
#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
} }
if (*resname != DIRSEP_C ) { /* do tilde expansion etc */ if (*resname != DIRSEP_C )
{
/* Do tilde expansion etc. */
if (strchr(resname, DIRSEP_C) ) if (strchr(resname, DIRSEP_C) )
filename = make_filename (resname, NULL); filename = make_filename (resname, NULL);
else else
@ -258,30 +265,35 @@ keydb_add_resource (const char *url, int flags)
force = !any_public; force = !any_public;
/* See whether we can determine the filetype. */ /* See whether we can determine the filetype. */
if (rt == KEYDB_RESOURCE_TYPE_NONE) { if (rt == KEYDB_RESOURCE_TYPE_NONE)
FILE *fp = fopen( filename, "rb" ); {
FILE *fp = fopen (filename, "rb");
if (fp) { if (fp)
{
u32 magic; u32 magic;
if (fread( &magic, 4, 1, fp) == 1 ) { if (fread( &magic, 4, 1, fp) == 1 )
{
if (magic == 0x13579ace || magic == 0xce9a5713) if (magic == 0x13579ace || magic == 0xce9a5713)
; /* GDBM magic - no more support */ ; /* GDBM magic - not anymore supported. */
else else
rt = KEYDB_RESOURCE_TYPE_KEYRING; rt = KEYDB_RESOURCE_TYPE_KEYRING;
} }
else /* maybe empty: assume ring */ else /* Maybe empty: assume keyring. */
rt = KEYDB_RESOURCE_TYPE_KEYRING; rt = KEYDB_RESOURCE_TYPE_KEYRING;
fclose( fp ); fclose( fp );
} }
else /* no file yet: create ring */ else /* No file yet: create keyring. */
rt = KEYDB_RESOURCE_TYPE_KEYRING; rt = KEYDB_RESOURCE_TYPE_KEYRING;
} }
switch (rt) { switch (rt)
{
case KEYDB_RESOURCE_TYPE_NONE: case KEYDB_RESOURCE_TYPE_NONE:
log_error ("unknown type of key resource `%s'\n", url ); log_error ("unknown type of key resource `%s'\n", url );
rc = G10ERR_GENERAL; rc = gpg_error (GPG_ERR_GENERAL);
goto leave; goto leave;
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
@ -289,14 +301,14 @@ keydb_add_resource (const char *url, int flags)
if (rc) if (rc)
goto leave; goto leave;
if(keyring_register_filename (filename, read_only, &token)) if (keyring_register_filename (filename, read_only, &token))
{ {
if (used_resources >= MAX_KEYDB_RESOURCES) if (used_resources >= MAX_KEYDB_RESOURCES)
rc = G10ERR_RESOURCE_LIMIT; rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
else else
{ {
if(flags&2) if (flags&2)
primary_keyring=token; primary_keyring = token;
all_resources[used_resources].type = rt; all_resources[used_resources].type = rt;
all_resources[used_resources].u.kr = NULL; /* Not used here */ all_resources[used_resources].u.kr = NULL; /* Not used here */
all_resources[used_resources].token = token; all_resources[used_resources].token = token;
@ -308,14 +320,14 @@ keydb_add_resource (const char *url, int flags)
/* This keyring was already registered, so ignore it. /* This keyring was already registered, so ignore it.
However, we can still mark it as primary even if it was However, we can still mark it as primary even if it was
already registered. */ already registered. */
if(flags&2) if (flags&2)
primary_keyring=token; primary_keyring = token;
} }
break; break;
default: default:
log_error ("resource type of `%s' not supported\n", url); log_error ("resource type of `%s' not supported\n", url);
rc = G10ERR_GENERAL; rc = gpg_error (GPG_ERR_GENERAL);
goto leave; goto leave;
} }
@ -323,7 +335,7 @@ keydb_add_resource (const char *url, int flags)
leave: leave:
if (rc) if (rc)
log_error (_("keyblock resource `%s': %s\n"), filename, g10_errstr(rc)); log_error (_("keyblock resource `%s': %s\n"), filename, gpg_strerror (rc));
else else
any_public = 1; any_public = 1;
xfree (filename); xfree (filename);
@ -378,8 +390,10 @@ keydb_release (KEYDB_HANDLE hd)
active_handles--; active_handles--;
unlock_all (hd); unlock_all (hd);
for (i=0; i < hd->used; i++) { for (i=0; i < hd->used; i++)
switch (hd->active[i].type) { {
switch (hd->active[i].type)
{
case KEYDB_RESOURCE_TYPE_NONE: case KEYDB_RESOURCE_TYPE_NONE:
break; break;
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
@ -416,7 +430,8 @@ keydb_get_resource_name (KEYDB_HANDLE hd)
else else
idx = 0; idx = 0;
switch (hd->active[idx].type) { switch (hd->active[idx].type)
{
case KEYDB_RESOURCE_TYPE_NONE: case KEYDB_RESOURCE_TYPE_NONE:
s = NULL; s = NULL;
break; break;
@ -435,8 +450,10 @@ lock_all (KEYDB_HANDLE hd)
{ {
int i, rc = 0; int i, rc = 0;
for (i=0; !rc && i < hd->used; i++) { for (i=0; !rc && i < hd->used; i++)
switch (hd->active[i].type) { {
switch (hd->active[i].type)
{
case KEYDB_RESOURCE_TYPE_NONE: case KEYDB_RESOURCE_TYPE_NONE:
break; break;
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
@ -445,10 +462,13 @@ lock_all (KEYDB_HANDLE hd)
} }
} }
if (rc) { if (rc)
/* revert the already set locks */ {
for (i--; i >= 0; i--) { /* Revert the already set locks. */
switch (hd->active[i].type) { for (i--; i >= 0; i--)
{
switch (hd->active[i].type)
{
case KEYDB_RESOURCE_TYPE_NONE: case KEYDB_RESOURCE_TYPE_NONE:
break; break;
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
@ -463,6 +483,7 @@ lock_all (KEYDB_HANDLE hd)
return rc; return rc;
} }
static void static void
unlock_all (KEYDB_HANDLE hd) unlock_all (KEYDB_HANDLE hd)
{ {
@ -471,8 +492,10 @@ unlock_all (KEYDB_HANDLE hd)
if (!hd->locked) if (!hd->locked)
return; return;
for (i=hd->used-1; i >= 0; i--) { for (i=hd->used-1; i >= 0; i--)
switch (hd->active[i].type) { {
switch (hd->active[i].type)
{
case KEYDB_RESOURCE_TYPE_NONE: case KEYDB_RESOURCE_TYPE_NONE:
break; break;
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
@ -490,53 +513,55 @@ unlock_all (KEYDB_HANDLE hd)
* the public key used to locate the keyblock or flag bit 1 set for * the public key used to locate the keyblock or flag bit 1 set for
* the user ID node. * the user ID node.
*/ */
int gpg_error_t
keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
{ {
int rc = 0; gpg_error_t err = 0;
if (!hd) if (!hd)
return G10ERR_INV_ARG; return gpg_error (GPG_ERR_INV_ARG);
if ( hd->found < 0 || hd->found >= hd->used) if (hd->found < 0 || hd->found >= hd->used)
return -1; /* nothing found */ return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
switch (hd->active[hd->found].type) { switch (hd->active[hd->found].type)
{
case KEYDB_RESOURCE_TYPE_NONE: case KEYDB_RESOURCE_TYPE_NONE:
rc = G10ERR_GENERAL; /* oops */ err = gpg_error (GPG_ERR_GENERAL); /* oops */
break; break;
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
rc = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb); err = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
break; break;
} }
return rc; return err;
} }
/* /*
* update the current keyblock with KB * Update the current keyblock with the keyblock KB
*/ */
int gpg_error_t
keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb) keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
{ {
int rc = 0; gpg_error_t rc;
if (!hd) if (!hd)
return G10ERR_INV_ARG; return gpg_error (GPG_ERR_INV_ARG);
if ( hd->found < 0 || hd->found >= hd->used) if (hd->found < 0 || hd->found >= hd->used)
return -1; /* nothing found */ return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
if( opt.dry_run ) if (opt.dry_run)
return 0; return 0;
rc = lock_all (hd); rc = lock_all (hd);
if (rc) if (rc)
return rc; return rc;
switch (hd->active[hd->found].type) { switch (hd->active[hd->found].type)
{
case KEYDB_RESOURCE_TYPE_NONE: case KEYDB_RESOURCE_TYPE_NONE:
rc = G10ERR_GENERAL; /* oops */ rc = gpg_error (GPG_ERR_GENERAL); /* oops */
break; break;
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb); rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
@ -551,32 +576,33 @@ keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
/* /*
* Insert a new KB into one of the resources. * Insert a new KB into one of the resources.
*/ */
int gpg_error_t
keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb) keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
{ {
int rc = -1; int rc;
int idx; int idx;
if (!hd) if (!hd)
return G10ERR_INV_ARG; return gpg_error (GPG_ERR_INV_ARG);
if( opt.dry_run ) if (opt.dry_run)
return 0; return 0;
if ( hd->found >= 0 && hd->found < hd->used) if (hd->found >= 0 && hd->found < hd->used)
idx = hd->found; idx = hd->found;
else if ( hd->current >= 0 && hd->current < hd->used) else if (hd->current >= 0 && hd->current < hd->used)
idx = hd->current; idx = hd->current;
else else
return G10ERR_GENERAL; return gpg_error (GPG_ERR_GENERAL);
rc = lock_all (hd); rc = lock_all (hd);
if (rc) if (rc)
return rc; return rc;
switch (hd->active[idx].type) { switch (hd->active[idx].type)
{
case KEYDB_RESOURCE_TYPE_NONE: case KEYDB_RESOURCE_TYPE_NONE:
rc = G10ERR_GENERAL; /* oops */ rc = gpg_error (GPG_ERR_GENERAL); /* oops */
break; break;
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb); rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
@ -589,29 +615,30 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
/* /*
* The current keyblock will be deleted. * Delete the current keyblock.
*/ */
int gpg_error_t
keydb_delete_keyblock (KEYDB_HANDLE hd) keydb_delete_keyblock (KEYDB_HANDLE hd)
{ {
int rc = -1; gpg_error_t rc;
if (!hd) if (!hd)
return G10ERR_INV_ARG; return gpg_error (GPG_ERR_INV_ARG);
if ( hd->found < 0 || hd->found >= hd->used) if (hd->found < 0 || hd->found >= hd->used)
return -1; /* nothing found */ return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
if( opt.dry_run ) if (opt.dry_run)
return 0; return 0;
rc = lock_all (hd); rc = lock_all (hd);
if (rc) if (rc)
return rc; return rc;
switch (hd->active[hd->found].type) { switch (hd->active[hd->found].type)
{
case KEYDB_RESOURCE_TYPE_NONE: case KEYDB_RESOURCE_TYPE_NONE:
rc = G10ERR_GENERAL; /* oops */ rc = gpg_error (GPG_ERR_GENERAL);
break; break;
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
rc = keyring_delete_keyblock (hd->active[hd->found].u.kr); rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
@ -622,16 +649,17 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
return rc; return rc;
} }
/* /*
* Locate the default writable key resource, so that the next * Locate the default writable key resource, so that the next
* operation (which is only relevant for inserts) will be done on this * operation (which is only relevant for inserts) will be done on this
* resource. * resource.
*/ */
int gpg_error_t
keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
{ {
int rc; gpg_error_t rc;
(void)reserved; (void)reserved;
@ -643,7 +671,7 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
return rc; return rc;
/* If we have a primary set, try that one first */ /* 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++) 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,19 +737,22 @@ keydb_rebuild_caches (int noisy)
/* /*
* Start the next search on this handle right at the beginning * Start the next search on this handle right at the beginning
*/ */
int gpg_error_t
keydb_search_reset (KEYDB_HANDLE hd) keydb_search_reset (KEYDB_HANDLE hd)
{ {
int i, rc = 0; gpg_error_t rc = 0;
int i;
if (!hd) if (!hd)
return G10ERR_INV_ARG; return gpg_error (GPG_ERR_INV_ARG);
hd->current = 0; hd->current = 0;
hd->found = -1; hd->found = -1;
/* and reset all resources */ /* Now reset all resources. */
for (i=0; !rc && i < hd->used; i++) { for (i=0; !rc && i < hd->used; i++)
switch (hd->active[i].type) { {
switch (hd->active[i].type)
{
case KEYDB_RESOURCE_TYPE_NONE: case KEYDB_RESOURCE_TYPE_NONE:
break; break;
case KEYDB_RESOURCE_TYPE_KEYRING: case KEYDB_RESOURCE_TYPE_KEYRING:
@ -734,20 +765,26 @@ keydb_search_reset (KEYDB_HANDLE hd)
/* /*
* Search through all keydb resources, starting at the current position, * Search through all keydb resources, starting at the current
* for a keyblock which contains one of the keys described in the DESC array. * 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, keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
size_t ndesc, size_t *descindex) size_t ndesc, size_t *descindex)
{ {
int rc = -1; gpg_error_t rc;
if (!hd) if (!hd)
return G10ERR_INV_ARG; return gpg_error (GPG_ERR_INV_ARG);
while (rc == -1 && hd->current >= 0 && hd->current < hd->used) { rc = -1;
switch (hd->active[hd->current].type) { 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: case KEYDB_RESOURCE_TYPE_NONE:
BUG(); /* we should never see it here */ BUG(); /* we should never see it here */
break; break;
@ -756,16 +793,22 @@ keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
ndesc, descindex); ndesc, descindex);
break; break;
} }
if (rc == -1) /* EOF -> switch to next resource */ if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
{
/* EOF -> switch to next resource */
hd->current++; hd->current++;
}
else if (!rc) else if (!rc)
hd->found = hd->current; 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_first (KEYDB_HANDLE hd)
{ {
KEYDB_SEARCH_DESC desc; KEYDB_SEARCH_DESC desc;
@ -775,7 +818,7 @@ keydb_search_first (KEYDB_HANDLE hd)
return keydb_search (hd, &desc, 1); return keydb_search (hd, &desc, 1);
} }
int gpg_error_t
keydb_search_next (KEYDB_HANDLE hd) keydb_search_next (KEYDB_HANDLE hd)
{ {
KEYDB_SEARCH_DESC desc; KEYDB_SEARCH_DESC desc;
@ -785,7 +828,7 @@ keydb_search_next (KEYDB_HANDLE hd)
return keydb_search (hd, &desc, 1); return keydb_search (hd, &desc, 1);
} }
int gpg_error_t
keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
{ {
KEYDB_SEARCH_DESC desc; KEYDB_SEARCH_DESC desc;
@ -797,7 +840,7 @@ keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
return keydb_search (hd, &desc, 1); return keydb_search (hd, &desc, 1);
} }
int gpg_error_t
keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr) keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
{ {
KEYDB_SEARCH_DESC desc; KEYDB_SEARCH_DESC desc;

View File

@ -132,25 +132,24 @@ union pref_hint
Flag 1 == force Flag 1 == force
Flag 2 == default 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); KEYDB_HANDLE keydb_new (void);
void keydb_release (KEYDB_HANDLE hd); void keydb_release (KEYDB_HANDLE hd);
const char *keydb_get_resource_name (KEYDB_HANDLE hd); const char *keydb_get_resource_name (KEYDB_HANDLE hd);
int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb); gpg_error_t keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb); gpg_error_t keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb);
int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb); gpg_error_t keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb);
int keydb_delete_keyblock (KEYDB_HANDLE hd); gpg_error_t keydb_delete_keyblock (KEYDB_HANDLE hd);
int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved); gpg_error_t keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved);
void keydb_rebuild_caches (int noisy); 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) #define keydb_search(a,b,c) keydb_search2((a),(b),(c),NULL)
int keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, gpg_error_t keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
size_t ndesc, size_t *descindex); size_t ndesc, size_t *descindex);
int keydb_search_first (KEYDB_HANDLE hd); gpg_error_t keydb_search_first (KEYDB_HANDLE hd);
int keydb_search_next (KEYDB_HANDLE hd); gpg_error_t keydb_search_next (KEYDB_HANDLE hd);
int keydb_search_kid (KEYDB_HANDLE hd, u32 *kid); gpg_error_t keydb_search_kid (KEYDB_HANDLE hd, u32 *kid);
int keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr); gpg_error_t keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr);
/*-- pkclist.c --*/ /*-- pkclist.c --*/
void show_revocation_reason( PKT_public_key *pk, int mode ); void show_revocation_reason( PKT_public_key *pk, int mode );

View File

@ -434,12 +434,12 @@ list_all (int secret)
hd = keydb_new (); hd = keydb_new ();
if (!hd) if (!hd)
rc = G10ERR_GENERAL; rc = gpg_error (GPG_ERR_GENERAL);
else else
rc = keydb_search_first (hd); rc = keydb_search_first (hd);
if (rc) 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)); log_error ("keydb_search_first failed: %s\n", g10_errstr (rc));
goto leave; goto leave;
} }
@ -479,7 +479,7 @@ list_all (int secret)
keyblock = NULL; keyblock = NULL;
} }
while (!(rc = keydb_search_next (hd))); 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)); log_error ("keydb_search_next failed: %s\n", g10_errstr (rc));
if (opt.check_sigs && !opt.with_colons) if (opt.check_sigs && !opt.with_colons)

View File

@ -1236,8 +1236,8 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
} }
} }
if(rc==-1) if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
rc=0; rc = 0;
leave: leave:
if(rc) if(rc)

View File

@ -2107,7 +2107,7 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
desc.skipfnc = search_skipfnc; desc.skipfnc = search_skipfnc;
desc.skipfncvalue = full_trust; desc.skipfncvalue = full_trust;
rc = keydb_search (hd, &desc, 1); rc = keydb_search (hd, &desc, 1);
if (rc == -1) if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
{ {
keys[nkeys].keyblock = NULL; keys[nkeys].keyblock = NULL;
return keys; return keys;
@ -2181,7 +2181,7 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
keyblock = NULL; keyblock = NULL;
} }
while ( !(rc = keydb_search (hd, &desc, 1)) ); 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)); log_error ("keydb_search_next failed: %s\n", g10_errstr(rc));
xfree (keys); xfree (keys);

View File

@ -1,3 +1,12 @@
2011-04-28 Werner Koch <wk@g10code.com>
* 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 <wk@g10code.com> 2010-07-23 Werner Koch <wk@g10code.com>
* keybox-blob.c (_keybox_create_x509_blob): Fix reallocation bug. * keybox-blob.c (_keybox_create_x509_blob): Fix reallocation bug.
@ -365,7 +374,7 @@
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 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 This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without unlimited permission to copy and/or distribute it, with or without

View File

@ -1,5 +1,5 @@
/* kbxutil.c - The Keybox utility /* 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. * This file is part of GnuPG.
* *
@ -389,9 +389,19 @@ import_openpgp (const char *filename)
{ {
if (gpg_err_code (err) == GPG_ERR_NO_DATA) if (gpg_err_code (err) == GPG_ERR_NO_DATA)
break; break;
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", log_info ("%s: failed to parse OpenPGP keyblock: %s\n",
filename, gpg_strerror (err)); filename, gpg_strerror (err));
} }
}
else else
{ {
dump_openpgp_key (&info, p); dump_openpgp_key (&info, p);

View File

@ -1,5 +1,5 @@
/* keybox-openpgp.c - OpenPGP key parsing /* 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. * This file is part of GnuPG.
* *
@ -35,41 +35,16 @@
#include <gcrypt.h> #include <gcrypt.h>
#include "../common/openpgpdefs.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 */
};
/* Assume a valid OpenPGP packet at the address pointed to by BUFBTR /* 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 information of that packet and advance the pointer stored at BUFPTR
to the next packet; also adjust the length stored at BUFLEN to to the next packet; also adjust the length stored at BUFLEN to
match the remaining bytes. If there are no more packets, store NULL match the remaining bytes. If there are no more packets, store NULL
at BUFPTR. Return an non-zero error code on failure or the 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_DATAPKT = Pointer to the begin of the packet data.
R_DATALEN = Length of this data. This has already been checked to fit R_DATALEN = Length of this data. This has already been checked to fit
@ -166,7 +141,7 @@ next_packet (unsigned char const **bufptr, size_t *buflen,
return gpg_error (GPG_ERR_UNEXPECTED); return gpg_error (GPG_ERR_UNEXPECTED);
} }
if (pktlen == 0xffffffff) if (pktlen == (unsigned long)(-1))
return gpg_error (GPG_ERR_INV_PACKET); return gpg_error (GPG_ERR_INV_PACKET);
if (pktlen > len) if (pktlen > len)
@ -201,6 +176,7 @@ parse_key (const unsigned char *data, size_t datalen,
const unsigned char *mpi_n = NULL; const unsigned char *mpi_n = NULL;
size_t mpi_n_len = 0, mpi_e_len = 0; size_t mpi_n_len = 0, mpi_e_len = 0;
gcry_md_hd_t md; gcry_md_hd_t md;
int is_ecc = 0;
if (datalen < 5) if (datalen < 5)
return gpg_error (GPG_ERR_INV_PACKET); 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); return gpg_error (GPG_ERR_INV_PACKET);
ndays = ((data[0]<<8)|(data[1])); ndays = ((data[0]<<8)|(data[1]));
data +=2; datalen -= 2; data +=2; datalen -= 2;
if (ndays)
expiredate = ndays? (timestamp + ndays * 86400L) : 0; expiredate = ndays? (timestamp + ndays * 86400L) : 0;
} }
else else
@ -245,9 +220,11 @@ parse_key (const unsigned char *data, size_t datalen,
break; break;
case 18: /* ECDH */ case 18: /* ECDH */
npkey = 3; npkey = 3;
is_ecc = 1;
break; break;
case 19: /* ECDSA */ case 19: /* ECDSA */
npkey = 2; npkey = 2;
is_ecc = 1;
break; break;
default: /* Unknown algorithm. */ default: /* Unknown algorithm. */
return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM); return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
@ -259,8 +236,21 @@ parse_key (const unsigned char *data, size_t datalen,
if (datalen < 2) if (datalen < 2)
return gpg_error (GPG_ERR_INV_PACKET); return gpg_error (GPG_ERR_INV_PACKET);
if (is_ecc && (i == 0 || i == 2))
{
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])); nbits = ((data[0]<<8)|(data[1]));
data += 2; datalen -=2; data += 2;
datalen -= 2;
nbytes = (nbits+7) / 8; nbytes = (nbits+7) / 8;
if (datalen < nbytes) if (datalen < nbytes)
return gpg_error (GPG_ERR_INV_PACKET); return gpg_error (GPG_ERR_INV_PACKET);
@ -273,6 +263,7 @@ parse_key (const unsigned char *data, size_t datalen,
} }
else if (i==1) else if (i==1)
mpi_e_len = nbytes; mpi_e_len = nbytes;
}
data += nbytes; datalen -= nbytes; data += nbytes; datalen -= nbytes;
} }
@ -297,7 +288,7 @@ parse_key (const unsigned char *data, size_t datalen,
if (mpi_n_len < 8) if (mpi_n_len < 8)
{ {
/* Moduli less than 64 bit are out of the specs scope. Zero /* 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); memset (ki->keyid, 0, 8);
} }
else 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 /* 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 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 have a scatter-gather enabled hash function. What we do here
is to use a static buffer if this one is large enough and 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. */ large enough. */
if ( 3 + n < sizeof hashbuffer ) 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 /* The caller must pass the address of an INFO structure which will
get filled on success with information pertaining to the OpenPGP get filled on success with information pertaining to the OpenPGP
keyblock IMAGE of length IMAGELEN. Note that a caller does only 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 success. If NPARSED is not NULL the actual number of bytes parsed
will be stored at this address. */ will be stored at this address. */
gpg_error_t gpg_error_t
_keybox_parse_openpgp (const unsigned char *image, size_t imagelen, _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
size_t *nparsed, size_t *nparsed, keybox_openpgp_info_t info)
keybox_openpgp_info_t info)
{ {
gpg_error_t err = 0; gpg_error_t err = 0;
const unsigned char *image_start, *data; const unsigned char *image_start, *data;
size_t n, datalen; size_t n, datalen;
int pkttype; int pkttype;
int first = 1; int first = 1;
int read_error = 0;
struct _keybox_openpgp_key_info *k, **ktail = NULL; struct _keybox_openpgp_key_info *k, **ktail = NULL;
struct _keybox_openpgp_uid_info *u, **utail = 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); err = next_packet (&image, &imagelen, &data, &datalen, &pkttype, &n);
if (err) if (err)
{
read_error = 1;
break; break;
}
if (first) if (first)
{ {
@ -380,6 +374,8 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
else else
{ {
err = gpg_error (GPG_ERR_UNEXPECTED); err = gpg_error (GPG_ERR_UNEXPECTED);
if (nparsed)
*nparsed += n;
break; break;
} }
first = 0; first = 0;
@ -439,9 +435,12 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
if (err) if (err)
{ {
info->nsubkeys--; info->nsubkeys--;
if (gpg_err_code (err) != GPG_ERR_UNKNOWN_ALGORITHM)
break;
/* We ignore subkeys with unknown algorithms. */ /* 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 else
ktail = &info->subkeys.next; ktail = &info->subkeys.next;
@ -459,9 +458,12 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
{ {
xfree (k); xfree (k);
info->nsubkeys--; info->nsubkeys--;
if (gpg_err_code (err) != GPG_ERR_UNKNOWN_ALGORITHM)
break;
/* We ignore subkeys with unknown algorithms. */ /* 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 else
{ {
@ -475,11 +477,10 @@ _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
if (err) if (err)
{ {
_keybox_destroy_openpgp_info (info); _keybox_destroy_openpgp_info (info);
if (!first if (!read_error)
&& (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM
|| gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM))
{ {
/* 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) while (image)
{ {
if (next_packet (&image, &imagelen, if (next_packet (&image, &imagelen,