mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Merge branch 'wk-gpg-keybox'
This commit is contained in:
commit
c36deeea8b
@ -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>
|
||||
|
||||
* import.c (import_secret_one): Leave all checks to import_one.
|
||||
|
@ -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:
|
||||
|
10
g10/getkey.c
10
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);
|
||||
|
645
g10/keydb.c
645
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;
|
||||
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;
|
||||
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;
|
||||
/* 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);
|
||||
else
|
||||
filename = xstrdup (resname);
|
||||
|
||||
if (!force && !read_only)
|
||||
force = !any_public;
|
||||
if (!force && !read_only)
|
||||
force = !any_public;
|
||||
|
||||
/* See whether we can determine the filetype. */
|
||||
if (rt == KEYDB_RESOURCE_TYPE_NONE) {
|
||||
FILE *fp = fopen( filename, "rb" );
|
||||
/* See whether we can determine the filetype. */
|
||||
if (rt == KEYDB_RESOURCE_TYPE_NONE)
|
||||
{
|
||||
FILE *fp = fopen (filename, "rb");
|
||||
|
||||
if (fp) {
|
||||
u32 magic;
|
||||
if (fp)
|
||||
{
|
||||
u32 magic;
|
||||
|
||||
if (fread( &magic, 4, 1, fp) == 1 ) {
|
||||
if (magic == 0x13579ace || magic == 0xce9a5713)
|
||||
; /* GDBM magic - no more support */
|
||||
else
|
||||
rt = KEYDB_RESOURCE_TYPE_KEYRING;
|
||||
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;
|
||||
int i;
|
||||
|
||||
if (!hd)
|
||||
return;
|
||||
assert (active_handles > 0);
|
||||
active_handles--;
|
||||
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;
|
||||
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;
|
||||
int idx;
|
||||
const char *s = NULL;
|
||||
|
||||
if (!hd)
|
||||
return 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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
int i;
|
||||
|
||||
if (!hd->locked)
|
||||
return;
|
||||
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;
|
||||
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;
|
||||
int rc;
|
||||
int idx;
|
||||
|
||||
if (!hd)
|
||||
return G10ERR_INV_ARG;
|
||||
if (!hd)
|
||||
return gpg_error (GPG_ERR_INV_ARG);
|
||||
|
||||
if( opt.dry_run )
|
||||
return 0;
|
||||
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;
|
||||
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);
|
||||
|
||||
rc = lock_all (hd);
|
||||
if (rc)
|
||||
return rc;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
gpg_error_t rc = 0;
|
||||
int i;
|
||||
|
||||
if (!hd)
|
||||
return G10ERR_INV_ARG;
|
||||
if (!hd)
|
||||
return gpg_error (GPG_ERR_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;
|
||||
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;
|
||||
gpg_error_t rc;
|
||||
|
||||
if (!hd)
|
||||
return G10ERR_INV_ARG;
|
||||
if (!hd)
|
||||
return gpg_error (GPG_ERR_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;
|
||||
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);
|
||||
}
|
||||
|
27
g10/keydb.h
27
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 );
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
||||
* 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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user