mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-21 10:09:57 +01:00
New key db.
This commit is contained in:
parent
641df615da
commit
3ad5c815fd
@ -29,7 +29,7 @@ include $(top_srcdir)/am/cmacros.am
|
||||
AM_CFLAGS = $(SQLITE3_CFLAGS) $(LIBGCRYPT_CFLAGS) \
|
||||
$(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
|
||||
|
||||
needed_libs = ../kbx/libkeybox.a $(libcommon)
|
||||
needed_libs = ../kbx/libkeybox.a $(libcommon) $(SQLITE3_LIBS)
|
||||
|
||||
bin_PROGRAMS = gpg2
|
||||
if !HAVE_W32CE_SYSTEM
|
||||
@ -57,7 +57,7 @@ trust_source = trustdb.c trustdb.h tdbdump.c tdbio.c tdbio.h
|
||||
endif
|
||||
|
||||
if USE_TOFU
|
||||
tofu_source = tofu.h tofu.c sqlite.c sqlite.h
|
||||
tofu_source = tofu.h tofu.c
|
||||
else
|
||||
tofu_source =
|
||||
endif
|
||||
@ -101,7 +101,9 @@ common_source = \
|
||||
sig-check.c \
|
||||
keylist.c \
|
||||
pkglue.c pkglue.h \
|
||||
ecdh.c
|
||||
ecdh.c \
|
||||
kdb.c kdb.h \
|
||||
sqlite.c sqlite.h
|
||||
|
||||
gpg2_SOURCES = gpg.c \
|
||||
server.c \
|
||||
@ -147,7 +149,7 @@ gpgv2_SOURCES = gpgv.c \
|
||||
|
||||
LDADD = $(needed_libs) ../common/libgpgrl.a \
|
||||
$(ZLIBS) $(LIBINTL) $(CAPLIBS) $(NETLIBS)
|
||||
gpg2_LDADD = $(LDADD) $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) $(LIBREADLINE) \
|
||||
gpg2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) $(LIBREADLINE) \
|
||||
$(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
|
||||
$(LIBICONV) $(resource_objs) $(extra_sys_libs)
|
||||
gpg2_LDFLAGS = $(extra_bin_ldflags)
|
||||
|
@ -1154,6 +1154,9 @@ import_one (ctrl_t ctrl,
|
||||
goto leave;
|
||||
}
|
||||
|
||||
assert (strcmp (keystr_from_pk(keyblock_orig->pkt->pkt.public_key),
|
||||
keystr_from_pk(pk)) == 0);
|
||||
|
||||
/* Make sure the original direct key sigs are all sane. */
|
||||
n_sigs_cleaned = fix_bad_direct_key_sigs (keyblock_orig, keyid);
|
||||
if (n_sigs_cleaned)
|
||||
|
29
g10/kdb.h
Normal file
29
g10/kdb.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef GNUPG_KDB_H
|
||||
#define GNUPG_KDB_H
|
||||
|
||||
#include "keydb.h"
|
||||
|
||||
typedef struct keydb_handle *KDB_HANDLE;
|
||||
|
||||
gpg_error_t kdb_register_file (const char *fname, int read_only, void **ptr);
|
||||
int kdb_is_writable (void *token);
|
||||
|
||||
KDB_HANDLE kdb_new (void *token);
|
||||
void kdb_release (KDB_HANDLE hd);
|
||||
void kdb_push_found_state (KDB_HANDLE hd);
|
||||
void kdb_pop_found_state (KDB_HANDLE hd);
|
||||
const char *kdb_get_resource_name (KDB_HANDLE hd);
|
||||
int kdb_lock (KDB_HANDLE hd, int yes);
|
||||
int kdb_get_keyblock (KDB_HANDLE hd, iobuf_t *iobuf,
|
||||
int *pk_no, int *uid_no, u32 **sigstatus);
|
||||
int kdb_update_keyblock (KDB_HANDLE hd, kbnode_t kb,
|
||||
const void *image, size_t imagelen);
|
||||
gpg_error_t kdb_insert_keyblock (KDB_HANDLE hd, kbnode_t kb,
|
||||
const void *image, size_t imagelen,
|
||||
u32 *sigstatus);
|
||||
int kdb_delete (KDB_HANDLE hd);
|
||||
int kdb_search_reset (KDB_HANDLE hd);
|
||||
int kdb_search (KDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
size_t ndesc, size_t *descindex);
|
||||
|
||||
#endif
|
205
g10/keydb.c
205
g10/keydb.c
@ -37,6 +37,7 @@
|
||||
#include "../kbx/keybox.h"
|
||||
#include "keydb.h"
|
||||
#include "i18n.h"
|
||||
#include "kdb.h"
|
||||
|
||||
static int active_handles;
|
||||
|
||||
@ -44,7 +45,8 @@ typedef enum
|
||||
{
|
||||
KEYDB_RESOURCE_TYPE_NONE = 0,
|
||||
KEYDB_RESOURCE_TYPE_KEYRING,
|
||||
KEYDB_RESOURCE_TYPE_KEYBOX
|
||||
KEYDB_RESOURCE_TYPE_KEYBOX,
|
||||
KEYDB_RESOURCE_TYPE_KEYDB
|
||||
} KeydbResourceType;
|
||||
#define MAX_KEYDB_RESOURCES 40
|
||||
|
||||
@ -54,6 +56,7 @@ struct resource_item
|
||||
union {
|
||||
KEYRING_HANDLE kr;
|
||||
KEYBOX_HANDLE kb;
|
||||
KDB_HANDLE kdb;
|
||||
} u;
|
||||
void *token;
|
||||
};
|
||||
@ -251,13 +254,14 @@ keyblock_cache_clear (struct keydb_handle *hd)
|
||||
/* Handle the creation of a keyring or a keybox if it does not yet
|
||||
exist. Take into account that other processes might have the
|
||||
keyring/keybox already locked. This lock check does not work if
|
||||
the directory itself is not yet available. If IS_BOX is true the
|
||||
filename is expected to refer to a keybox. If FORCE_CREATE is true
|
||||
the keyring or keybox will be created.
|
||||
the directory itself is not yet available. RT is the type of
|
||||
resource being created. If FORCE_CREATE is true the keyring or
|
||||
keybox will be created.
|
||||
|
||||
Return 0 if it is okay to access the specified file. */
|
||||
static int
|
||||
maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
|
||||
maybe_create_resource (char *filename, KeydbResourceType rt,
|
||||
int force_create)
|
||||
{
|
||||
dotlock_t lockhd = NULL;
|
||||
IOBUF iobuf;
|
||||
@ -361,12 +365,25 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
|
||||
if (!iobuf)
|
||||
{
|
||||
rc = gpg_error_from_syserror ();
|
||||
if (is_box)
|
||||
log_error (_("error creating keybox '%s': %s\n"),
|
||||
filename, gpg_strerror (rc));
|
||||
else
|
||||
log_error (_("error creating keyring '%s': %s\n"),
|
||||
filename, gpg_strerror (rc));
|
||||
switch (rt)
|
||||
{
|
||||
case KEYDB_RESOURCE_TYPE_NONE:
|
||||
log_fatal ("Bad value for resource type: %d\n", rt);
|
||||
break;
|
||||
|
||||
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||
log_error (_("error creating keyring '%s': %s\n"),
|
||||
filename, gpg_strerror (rc));
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
log_error (_("error creating keybox '%s': %s\n"),
|
||||
filename, gpg_strerror (rc));
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
log_error (_("error creating keydb '%s': %s\n"),
|
||||
filename, gpg_strerror (rc));
|
||||
break;
|
||||
}
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -376,7 +393,7 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
|
||||
|
||||
/* Make sure that at least one record is in a new keybox file, so
|
||||
that the detection magic will work the next time it is used. */
|
||||
if (is_box)
|
||||
if (rt == KEYDB_RESOURCE_TYPE_KEYBOX)
|
||||
{
|
||||
FILE *fp = fopen (filename, "w");
|
||||
if (!fp)
|
||||
@ -388,22 +405,29 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
if (is_box)
|
||||
log_error (_("error creating keybox '%s': %s\n"),
|
||||
filename, gpg_strerror (rc));
|
||||
else
|
||||
log_error (_("error creating keyring '%s': %s\n"),
|
||||
filename, gpg_strerror (rc));
|
||||
log_error (_("error creating keybox '%s': %s\n"),
|
||||
filename, gpg_strerror (rc));
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
if (!opt.quiet)
|
||||
{
|
||||
if (is_box)
|
||||
log_info (_("keybox '%s' created\n"), filename);
|
||||
else
|
||||
log_info (_("keyring '%s' created\n"), filename);
|
||||
switch (rt)
|
||||
{
|
||||
case KEYDB_RESOURCE_TYPE_NONE:
|
||||
log_fatal ("Bad value for resource type: %d\n", rt);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||
log_info (_("keyring '%s' created\n"), filename);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
log_info (_("keybox '%s' created\n"), filename);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
log_info (_("keydb '%s' created\n"), filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -445,6 +469,8 @@ rt_from_file (const char *filename, int *r_found, int *r_openpgp)
|
||||
{
|
||||
if (magic == 0x13579ace || magic == 0xce9a5713)
|
||||
; /* GDBM magic - not anymore supported. */
|
||||
else if (memcmp (&magic, "SQLi", 4) == 0)
|
||||
rt = KEYDB_RESOURCE_TYPE_KEYDB;
|
||||
else if (fread (&verbuf, 4, 1, fp) == 1
|
||||
&& verbuf[0] == 1
|
||||
&& fread (&magic, 4, 1, fp) == 1
|
||||
@ -497,6 +523,11 @@ keydb_add_resource (const char *url, unsigned int flags)
|
||||
rt = KEYDB_RESOURCE_TYPE_KEYBOX;
|
||||
resname += 10;
|
||||
}
|
||||
else if (strlen (resname) > 10 && !strncmp (resname, "gnupg-kdb:", 10) )
|
||||
{
|
||||
rt = KEYDB_RESOURCE_TYPE_KEYDB;
|
||||
resname += 10;
|
||||
}
|
||||
#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
|
||||
else if (strchr (resname, ':'))
|
||||
{
|
||||
@ -600,7 +631,8 @@ keydb_add_resource (const char *url, unsigned int flags)
|
||||
goto leave;
|
||||
|
||||
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||
rc = maybe_create_keyring_or_box (filename, 0, create);
|
||||
rc = maybe_create_resource (filename, KEYDB_RESOURCE_TYPE_KEYRING,
|
||||
create);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
@ -630,7 +662,8 @@ keydb_add_resource (const char *url, unsigned int flags)
|
||||
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
{
|
||||
rc = maybe_create_keyring_or_box (filename, 1, create);
|
||||
rc = maybe_create_resource (filename, KEYDB_RESOURCE_TYPE_KEYBOX,
|
||||
create);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
@ -665,6 +698,36 @@ keydb_add_resource (const char *url, unsigned int flags)
|
||||
}
|
||||
break;
|
||||
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
{
|
||||
rc = maybe_create_resource (filename, KEYDB_RESOURCE_TYPE_KEYDB, create);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
rc = kdb_register_file (filename, read_only, &token);
|
||||
if (rc == 0)
|
||||
{
|
||||
if (used_resources >= MAX_KEYDB_RESOURCES)
|
||||
rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
|
||||
else
|
||||
{
|
||||
/* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */
|
||||
/* primary_keyring = token; */
|
||||
all_resources[used_resources].type = rt;
|
||||
all_resources[used_resources].u.kb = NULL; /* Not used here */
|
||||
all_resources[used_resources].token = token;
|
||||
|
||||
used_resources++;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: How to mark this as a primary if it was already
|
||||
registered. */
|
||||
/* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */
|
||||
/* primary_keyring = token; */
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error ("resource type of '%s' not supported\n", url);
|
||||
rc = gpg_error (GPG_ERR_GENERAL);
|
||||
@ -730,6 +793,14 @@ keydb_new (void)
|
||||
die = 1;
|
||||
j++;
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
hd->active[j].type = all_resources[i].type;
|
||||
hd->active[j].token = all_resources[i].token;
|
||||
hd->active[j].u.kdb = kdb_new (all_resources[i].token);
|
||||
if (!hd->active[j].u.kdb)
|
||||
die = 1;
|
||||
j++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hd->used = j;
|
||||
@ -769,6 +840,9 @@ keydb_release (KEYDB_HANDLE hd)
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
keybox_release (hd->active[i].u.kb);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
kdb_release (hd->active[i].u.kdb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -811,6 +885,9 @@ keydb_get_resource_name (KEYDB_HANDLE hd)
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
s = keybox_get_resource_name (hd->active[idx].u.kb);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
s = kdb_get_resource_name (hd->active[idx].u.kdb);
|
||||
break;
|
||||
}
|
||||
|
||||
return s? s: "";
|
||||
@ -842,6 +919,9 @@ lock_all (KEYDB_HANDLE hd)
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
rc = keybox_lock (hd->active[i].u.kb, 1);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
rc = kdb_lock (hd->active[i].u.kdb, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -860,6 +940,9 @@ lock_all (KEYDB_HANDLE hd)
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
rc = keybox_lock (hd->active[i].u.kb, 0);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
rc = kdb_lock (hd->active[i].u.kdb, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -890,6 +973,9 @@ unlock_all (KEYDB_HANDLE hd)
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
keybox_lock (hd->active[i].u.kb, 0);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
kdb_lock (hd->active[i].u.kdb, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
hd->locked = 0;
|
||||
@ -919,6 +1005,9 @@ keydb_push_found_state (KEYDB_HANDLE hd)
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
keybox_push_found_state (hd->active[hd->found].u.kb);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
kdb_push_found_state (hd->active[hd->found].u.kdb);
|
||||
break;
|
||||
}
|
||||
|
||||
hd->saved_found = hd->found;
|
||||
@ -947,6 +1036,9 @@ keydb_pop_found_state (KEYDB_HANDLE hd)
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
keybox_pop_found_state (hd->active[hd->found].u.kb);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
kdb_pop_found_state (hd->active[hd->found].u.kdb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1192,6 +1284,23 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
{
|
||||
iobuf_t iobuf;
|
||||
u32 *sigstatus;
|
||||
int pk_no, uid_no;
|
||||
|
||||
err = kdb_get_keyblock (hd->active[hd->found].u.kdb, &iobuf,
|
||||
&pk_no, &uid_no, &sigstatus);
|
||||
if (!err)
|
||||
{
|
||||
err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus,
|
||||
ret_kb);
|
||||
xfree (sigstatus);
|
||||
iobuf_close (iobuf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hd->keyblock_cache.state != KEYBLOCK_CACHE_FILLED)
|
||||
@ -1337,6 +1446,20 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
{
|
||||
iobuf_t iobuf;
|
||||
|
||||
err = build_keyblock_image (kb, &iobuf, NULL);
|
||||
if (!err)
|
||||
{
|
||||
err = kdb_update_keyblock (hd->active[hd->found].u.kdb, kb,
|
||||
iobuf_get_temp_buffer (iobuf),
|
||||
iobuf_get_temp_length (iobuf));
|
||||
iobuf_close (iobuf);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
unlock_all (hd);
|
||||
@ -1398,6 +1521,23 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
{
|
||||
iobuf_t iobuf;
|
||||
u32 *sigstatus;
|
||||
|
||||
err = build_keyblock_image (kb, &iobuf, &sigstatus);
|
||||
if (!err)
|
||||
{
|
||||
err = kdb_insert_keyblock (hd->active[idx].u.kdb, kb,
|
||||
iobuf_get_temp_buffer (iobuf),
|
||||
iobuf_get_temp_length (iobuf),
|
||||
sigstatus);
|
||||
xfree (sigstatus);
|
||||
iobuf_close (iobuf);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
unlock_all (hd);
|
||||
@ -1437,6 +1577,9 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
rc = keybox_delete (hd->active[hd->found].u.kb);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
rc = kdb_delete (hd->active[hd->found].u.kdb);
|
||||
break;
|
||||
}
|
||||
|
||||
unlock_all (hd);
|
||||
@ -1491,6 +1634,10 @@ keydb_locate_writable (KEYDB_HANDLE hd)
|
||||
if (keybox_is_writable (hd->active[hd->current].token))
|
||||
return 0; /* found (hd->current is set to it) */
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
if (kdb_is_writable (hd->active[hd->current].token))
|
||||
return 0; /* found (hd->current is set to it) */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1519,6 +1666,9 @@ keydb_rebuild_caches (int noisy)
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
/* N/A. */
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
/* N/A. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1564,6 +1714,9 @@ keydb_search_reset (KEYDB_HANDLE hd)
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
rc = keybox_search_reset (hd->active[i].u.kb);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
rc = kdb_search_reset (hd->active[i].u.kdb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
hd->is_reset = 1;
|
||||
@ -1682,6 +1835,10 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
ndesc, KEYBOX_BLOBTYPE_PGP,
|
||||
descindex, &hd->skipped_long_blobs);
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYDB:
|
||||
rc = kdb_search (hd->active[hd->current].u.kdb, desc,
|
||||
ndesc, descindex);
|
||||
break;
|
||||
}
|
||||
if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
|
||||
{
|
||||
|
@ -1722,7 +1722,8 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
|
||||
desc.skipfnc = search_skipfnc;
|
||||
desc.skipfncvalue = full_trust;
|
||||
rc = keydb_search (hd, &desc, 1, NULL);
|
||||
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
|
||||
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND
|
||||
|| gpg_err_code (rc) == GPG_ERR_EOF)
|
||||
{
|
||||
keys[nkeys].keyblock = NULL;
|
||||
return keys;
|
||||
|
Loading…
x
Reference in New Issue
Block a user