summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2000-10-06 14:28:44 +0200
committerWerner Koch <wk@gnupg.org>2000-10-06 14:28:44 +0200
commit14974bc5d70604577b7088a39e7eb175cafd418a (patch)
treeae5aa26daa1342b77a7ceb0f0295950dff3b3557
parentSee ChangeLog: Wed Oct 4 13:16:18 CEST 2000 Werner Koch (diff)
downloadgnupg2-14974bc5d70604577b7088a39e7eb175cafd418a.tar.xz
gnupg2-14974bc5d70604577b7088a39e7eb175cafd418a.zip
See ChangeLog: Fri Oct 6 14:29:16 CEST 2000 Werner Koch
-rw-r--r--NEWS4
-rw-r--r--configure.in17
-rw-r--r--g10/ChangeLog34
-rw-r--r--g10/delkey.c13
-rw-r--r--g10/export.c11
-rw-r--r--g10/getkey.c246
-rw-r--r--g10/import.c26
-rw-r--r--g10/keydb.h75
-rw-r--r--g10/keyedit.c27
-rw-r--r--g10/keygen.c4
-rw-r--r--g10/keyid.c65
-rw-r--r--g10/mainproc.c2
-rw-r--r--g10/packet.h7
-rw-r--r--g10/parse-packet.c10
-rw-r--r--g10/pkclist.c2
-rw-r--r--g10/revoke.c13
-rw-r--r--g10/ringedit.c1240
-rw-r--r--g10/skclist.c4
18 files changed, 469 insertions, 1331 deletions
diff --git a/NEWS b/NEWS
index 66d650a2a..3354d3905 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ Noteworthy changes in the current CVS HEAD
* Add Rijndael (AES) support.
+ * Removed gdbm support.
+
* Fixed problems with piping to/from other MS-Windows software
* Expiration time of the primary key can be changed again.
@@ -28,8 +30,6 @@ Noteworthy changes in the current CVS HEAD
* Twofish and MDC enhanced encryption is now used. PGP 7 supports
this. Older versions of GnuPG don't support it, so they should be
upgraded to at least 1.0.2
-
-
Noteworthy changes in version 1.1.1
diff --git a/configure.in b/configure.in
index 38d2c94db..133e65b13 100644
--- a/configure.in
+++ b/configure.in
@@ -184,7 +184,6 @@ MPI_OPT_FLAGS=""
try_gettext=yes
-try_gdbm=yes
case "${target}" in
*-*-mingw32*)
# special stuff for Windoze NT
@@ -194,7 +193,6 @@ case "${target}" in
AC_DEFINE(HAVE_DOSISH_SYSTEM)
AC_DEFINE(USE_SIMPLE_GETTEXT)
try_gettext="no"
- try_gdbm="no"
;;
i?86-emx-os2 | i?86-*-os2*emx )
# OS/2 with the EMX environment
@@ -202,7 +200,6 @@ case "${target}" in
AC_DEFINE(HAVE_DRIVE_LETTERS)
AC_DEFINE(HAVE_DOSISH_SYSTEM)
try_gettext="no"
- try_gdbm="no"
;;
i?86-*-msdosdjgpp*)
@@ -211,7 +208,6 @@ case "${target}" in
AC_DEFINE(HAVE_DRIVE_LETTERS)
AC_DEFINE(HAVE_DOSISH_SYSTEM)
try_gettext="no"
- try_gdbm="no"
;;
*-*-freebsd*)
@@ -331,19 +327,6 @@ fi
AM_CONDITIONAL(COMPILE_AGENT, test x$compile_agent = xyes)
-
-dnl
-dnl There are lot of misconfigured systems. We include
-dnl gdbm support only if the lib and the header is installed.
-dnl
-if test "$try_gdbm" = yes; then
-AC_CHECK_HEADERS(gdbm.h)
-if test "$ac_cv_header_gdbm_h" = yes ; then
- AC_CHECK_LIB(gdbm,gdbm_firstkey)
-fi
-fi
-
-
dnl Solaris needs -lsocket and -lnsl. Unisys system includes
dnl gethostbyname in libsocket but needs libnsl for socket.
AC_CHECK_LIB(nsl, gethostbyname)
diff --git a/g10/ChangeLog b/g10/ChangeLog
index fb25e7fdc..127e54fa9 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,37 @@
+Fri Oct 6 14:29:16 CEST 2000 Werner Koch <wk@openit.de>
+
+ Started to rework the whole getkey/ringedit stuff to make
+ it simpler, correcter and faster.
+
+ * parse-packet.c (parse_packet): Add a 3rd arg to return the filepos.
+ Changed all callers.
+ * getkey.c (classify_user_id): Add new mode 21.
+ (find_by_fpr): Find using this new mode.
+ (get_seckey_byname): New arg to return the context. Changed all
+ callers.
+ * keyid.c (unified_fingerprint_from_pk): New.
+ (unified_fingerprint_from_sk): New.
+ * ringedit.c (find_keyblock_bypk): Changed to use the unified
+ fingerprint for lookup. I can't see a reason why we did compare
+ the entire public key.
+ (find_keyblock_bysk): Ditto.
+ (search,cmp_pubkey,cmp_seckey): Removed.
+ (keyring_search, do_kbxf_search): Removed.
+ (locate_keyblock_by_fpr,locate_keyblock_by_keyid): Removed.
+ (find_keyblock_byname): Removed use o search function.
+ (find_secret_keyblock_byname): Ditto.
+ (merge_public_with_secret): Fixed removing subkeys.
+ (premerge_public_with_secret): New.
+
+ * ringedit.c: Removed all GDBM support
+
+ * ringedit.c (read_keyblock): Removed.
+ * ringedit.c (find_keyblock_byname,find_secret_keyblock_byname,
+ find_keyblock_bypk,find_keyblock_bysk): Moved from here to ....
+ * getkey.c: ... here. Changed first arg to return a keyblock and
+ changed all callers to merge the old read_keyblock() with these
+ functions.
+
Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
* getkey.c (merge_selfsigs_main): Fixed for v3 keys.
diff --git a/g10/delkey.c b/g10/delkey.c
index 0c64d41a3..91413edd8 100644
--- a/g10/delkey.c
+++ b/g10/delkey.c
@@ -58,21 +58,14 @@ delete_key( const char *username, int secret )
int yes;
/* search the userid */
- rc = secret? find_secret_keyblock_byname( &kbpos, username )
- : find_keyblock_byname( &kbpos, username );
+ rc = secret? find_secret_keyblock_byname( &keyblock, username )
+ : find_keyblock_byname( &keyblock, username );
if( rc ) {
- log_error(_("%s: user not found\n"), username );
+ log_error(_("%s: user not found: %s\n"), username, gpg_errstr(rc) );
write_status_text( STATUS_DELETE_PROBLEM, "1" );
goto leave;
}
- /* read the keyblock */
- rc = read_keyblock( &kbpos, &keyblock );
- if( rc ) {
- log_error("%s: read problem: %s\n", username, gpg_errstr(rc) );
- goto leave;
- }
-
/* get the keyid from the keyblock */
node = find_kbnode( keyblock, secret? PKT_SECRET_KEY:PKT_PUBLIC_KEY );
if( !node ) {
diff --git a/g10/export.c b/g10/export.c
index ddcc971d9..8b8ba489a 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -147,22 +147,15 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
}
else {
/* search the userid */
- rc = secret? find_secret_keyblock_byname( &kbpos, sl->d )
- : find_keyblock_byname( &kbpos, sl->d );
+ rc = secret? find_secret_keyblock_byname( &keyblock, sl->d )
+ : find_keyblock_byname( &keyblock, sl->d );
if( rc ) {
log_error(_("%s: user not found: %s\n"), sl->d, gpg_errstr(rc));
rc = 0;
continue;
}
- /* read the keyblock */
- rc = read_keyblock( &kbpos, &keyblock );
}
- if( rc ) {
- log_error(_("certificate read problem: %s\n"), gpg_errstr(rc));
- goto leave;
- }
-
/* do not export keys which are incompatible with rfc2440 */
if( onlyrfc && (node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) {
diff --git a/g10/getkey.c b/g10/getkey.c
index aa32dff74..a0fa44580 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -112,10 +112,6 @@ struct getkey_ctx_s {
getkey_item_t items[1];
};
-
-
-
-
#if 0
static struct {
int any;
@@ -595,6 +591,8 @@ hextobyte( const byte *s )
* 12 = it is a trustdb index (keyid is looked up)
* 16 = it is a 16 byte fingerprint
* 20 = it is a 20 byte fingerprint
+ * 21 = Unified fingerprint :fpr:pk_algo:
+ * (We don't use pk_algo yet)
*
* if fprint is not NULL, it should be an array of at least 20 bytes.
*
@@ -606,6 +604,8 @@ hextobyte( const byte *s )
* must be in the range 0..9), this is considered a fingerprint.
* - If the username starts with a left angle, we assume it is a complete
* email address and look only at this part.
+ * - If the username starts with a colon we assume it is a unified
+ * key specfification.
* - If the username starts with a '.', we assume it is the ending
* part of an email address
* - If the username starts with an '@', we assume it is a part of an
@@ -674,7 +674,32 @@ classify_user_id( const char *name, u32 *keyid, byte *fprint,
keyid[0] = keyid[1] = 0;
}
break;
-
+
+ case ':': /*Unified fingerprint */
+ {
+ const char *se, *si;
+ int i;
+
+ se = strchr( ++s,':');
+ if ( !se )
+ return 0;
+ for (i=0,si=s; si < se; si++, i++ ) {
+ if ( !strchr("01234567890abcdefABCDEF", *si ) )
+ return 0; /* invalid digit */
+ }
+ if (i != 32 && i != 40)
+ return 0; /* invalid length of fpr*/
+ if (fprint) {
+ for (i=0,si=s; si < se; i++, si +=2)
+ fprint[i] = hextobyte(si);
+ for ( ; i < 20; i++)
+ fprint[i]= 0;
+ }
+ s = se + 1;
+ mode = 21;
+ }
+ break;
+
default:
if (s[0] == '0' && s[1] == 'x') {
hexprefix = 1;
@@ -803,7 +828,8 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
/* if we don't use one of the exact key specifications, we assume that
* the primary key is requested */
- if ( mode != 10 && mode != 11 && mode != 16 && mode == 20 )
+ if ( mode != 10 && mode != 11
+ && mode != 16 && mode == 20 && mode != 21 )
ctx->primary = 1;
ctx->items[n].mode = mode;
@@ -836,6 +862,10 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
}
}
+ if (!rc )
+ log_debug ( "pk_byname: kbpos %s %lu %p\n",
+ ctx->kbpos.valid? "valid":"",
+ ctx->kbpos.offset, ctx->kbpos.fp );
release_kbnode ( help_kb );
if( retctx ) /* caller wants the context */
@@ -883,6 +913,7 @@ get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock )
return rc;
}
+
void
get_pubkey_end( GETKEY_CTX ctx )
{
@@ -897,8 +928,66 @@ get_pubkey_end( GETKEY_CTX ctx )
}
}
+
+
+/****************
+ * Combined function to search for a username and get the position
+ * of the keyblock.
+ */
+int
+find_keyblock_byname( KBNODE *retblock, const char *username )
+{
+ PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
+ int rc;
+
+ rc = get_pubkey_byname( NULL, pk, username, retblock );
+ free_public_key(pk);
+ return rc;
+}
+
+
+/****************
+ * Combined function to search for a key and get the position
+ * of the keyblock. Used for merging while importing keys.
+ */
+int
+find_keyblock_bypk( KBNODE *retblock, PKT_public_key *pk )
+{
+ char ufpr[50];
+
+ unified_fingerprint_from_pk( pk, ufpr, sizeof ufpr );
+ return find_keyblock_byname( retblock, ufpr );
+}
+
+int
+find_kblocation_bypk( void *re_opaque, PKT_public_key *pk )
+{
+ PKT_public_key *dummy_pk = gcry_xcalloc( 1, sizeof *pk );
+ char ufpr[50];
+ GETKEY_CTX ctx;
+ int rc;
+
+ unified_fingerprint_from_pk( pk, ufpr, sizeof ufpr );
+ /* FIXME: There is no need to return any informaton, we just
+ * wnat to know the location. Using the general lookup function
+ * has the problem that we might not get the key becuase it has expired
+ * or due to some similar probelm. A solotion would be a locate-only
+ * flag in the ctx */
+ rc = get_pubkey_byname( &ctx, dummy_pk, ufpr, NULL );
+ free_public_key(dummy_pk);
+ if ( !rc )
+ ringedit_copy_kbpos( re_opaque, &ctx->kbpos );
+ get_pubkey_end( ctx );
+
+ return rc;
+}
+
+
/****************
* Search for a key with the given fingerprint.
+ * FIXME:
+ * We should replace this with the _byname function. Thiscsan be done
+ * by creating a userID conforming to the unified fingerprint style.
*/
int
get_pubkey_byfprint( PKT_public_key *pk,
@@ -988,19 +1077,23 @@ get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid )
* If NAME is NULL use the default key
*/
int
-get_seckey_byname( PKT_secret_key *sk, const char *name, int unprotect )
+get_seckey_byname( GETKEY_CTX *retctx,
+ PKT_secret_key *sk, const char *name, int unprotect,
+ KBNODE *retblock )
{
STRLIST namelist = NULL;
int rc;
if( !name && opt.def_secret_key && *opt.def_secret_key ) {
add_to_strlist( &namelist, opt.def_secret_key );
- rc = key_byname( NULL, namelist, NULL, sk, NULL );
+ rc = key_byname( retctx, namelist, NULL, sk, retblock );
}
else if( !name ) { /* use the first one as default key */
struct getkey_ctx_s ctx;
KBNODE kb = NULL;
+ assert (!retctx ); /* do we need this at all */
+ assert (!retblock);
memset( &ctx, 0, sizeof ctx );
ctx.not_allocated = 1;
ctx.primary = 1;
@@ -1014,7 +1107,7 @@ get_seckey_byname( PKT_secret_key *sk, const char *name, int unprotect )
}
else {
add_to_strlist( &namelist, name );
- rc = key_byname( NULL, namelist, NULL, sk, NULL );
+ rc = key_byname( retctx, namelist, NULL, sk, retblock );
}
free_strlist( namelist );
@@ -1045,6 +1138,7 @@ get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock )
return rc;
}
+
void
get_seckey_end( GETKEY_CTX ctx )
{
@@ -1052,6 +1146,57 @@ get_seckey_end( GETKEY_CTX ctx )
}
+
+/****************
+ * Combined function to search for a username and get the position
+ * of the keyblock. This function does not unprotect the secret key.
+ */
+int
+find_secret_keyblock_byname( KBNODE *retblock, const char *username )
+{
+ PKT_secret_key *sk = gcry_xcalloc( 1, sizeof *sk );
+ int rc;
+
+ rc = get_seckey_byname( NULL, sk, username, 0, retblock );
+ free_secret_key(sk);
+ return rc;
+}
+
+
+
+/****************
+ * Combined function to search for a key and get the position
+ * of the keyblock.
+ */
+int
+find_keyblock_bysk( KBNODE *retblock, PKT_secret_key *sk )
+{
+ char ufpr[50];
+
+ unified_fingerprint_from_sk( sk, ufpr, sizeof ufpr );
+ return find_secret_keyblock_byname( retblock, ufpr );
+}
+
+int
+find_kblocation_bysk( void *re_opaque, PKT_secret_key *sk )
+{
+ PKT_secret_key *dummy_sk = gcry_xcalloc( 1, sizeof *sk );
+ char ufpr[50];
+ GETKEY_CTX ctx;
+ int rc;
+
+ unified_fingerprint_from_sk( sk, ufpr, sizeof ufpr );
+ rc = get_seckey_byname( &ctx, dummy_sk, ufpr, 0, NULL );
+ free_secret_key(dummy_sk);
+ if ( !rc )
+ ringedit_copy_kbpos( re_opaque, &ctx->kbpos );
+ get_seckey_end( ctx );
+
+ return rc;
+}
+
+
+
/*******************************************************
************** compare functions **********************
@@ -1728,8 +1873,6 @@ void
merge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
{
KBNODE pub;
- int deleting = 0;
- int any_deleted = 0;
assert ( pubblock->pkt->pkttype == PKT_PUBLIC_KEY );
assert ( secblock->pkt->pkttype == PKT_SECRET_KEY );
@@ -1750,7 +1893,6 @@ merge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
KBNODE sec;
PKT_public_key *pk = pub->pkt->pkt.public_key;
- deleting = 0;
/* this is more complicated: it may happen that the sequence
* of the subkeys dosn't match, so we have to find the
* appropriate secret key */
@@ -1766,26 +1908,57 @@ merge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
}
}
}
+ if ( !sec )
+ BUG(); /* already checked in premerge */
+ }
+ }
+}
+
+/* This function checks that for every public subkey a corresponding
+ * secret subkey is avalable and deletes the public subkey otherwise.
+ * We need this function becuase we can'tdelete it later when we
+ * actually merge the secret parts into the pubring.
+ */
+void
+premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
+{
+ KBNODE last, pub;
+
+ assert ( pubblock->pkt->pkttype == PKT_PUBLIC_KEY );
+ assert ( secblock->pkt->pkttype == PKT_SECRET_KEY );
+
+ for (pub=pubblock,last=NULL; pub; last = pub, pub = pub->next ) {
+ if ( pub->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
+ KBNODE sec;
+ PKT_public_key *pk = pub->pkt->pkt.public_key;
+
+ for (sec=secblock->next; sec; sec = sec->next ) {
+ if ( sec->pkt->pkttype == PKT_SECRET_SUBKEY ) {
+ PKT_secret_key *sk = sec->pkt->pkt.secret_key;
+ if ( !cmp_public_secret_key ( pk, sk ) )
+ break;
+ }
+ }
if ( !sec ) {
+ KBNODE next, ll;
log_error ( "no corresponding secret subkey "
"for public subkey - removing\n" );
- /* better remove the public subkey in this case */
- delete_kbnode ( pub );
- deleting = 1;
- any_deleted = 1;
+ /* we have to remove the subkey in this case */
+ assert ( last );
+ /* find the next subkey */
+ for (next=pub->next,ll=pub;
+ next && pub->pkt->pkttype != PKT_PUBLIC_SUBKEY;
+ ll = next, next = next->next )
+ ;
+ /* make new link */
+ last->next = next;
+ /* release this public subkey with all sigs */
+ ll->next = NULL;
+ release_kbnode( pub );
+ /* let the loop continue */
+ pub = last;
}
}
- else if ( deleting ) {
- delete_kbnode (pub);
- }
- }
-
- if ( any_deleted ) {
- /* because we have not deleted the root node, we don't need to
- * update the pubblock */
- pub = pubblock;
- commit_kbnode ( &pubblock );
- assert ( pub == pubblock );
}
}
@@ -1859,8 +2032,17 @@ find_by_fpr( KBNODE keyblock, const char *name, int mode )
size_t an;
fingerprint_from_pk(k->pkt->pkt.public_key, afp, &an );
- if( an == mode && !memcmp( afp, name, an) ) {
- return k;
+ if ( mode == 21 ) {
+ /* Unified fingerprint. The fingerprint is always 20 bytes*/
+ while ( an < 20 )
+ afp[an++] = 0;
+ if ( !memcmp( afp, name, 20 ) )
+ return k;
+ }
+ else {
+ if( an == mode && !memcmp( afp, name, an) ) {
+ return k;
+ }
}
}
}
@@ -2055,6 +2237,7 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
}
secblock = ctx->keyblock;
ctx->keyblock = k;
+ premerge_public_with_secret ( ctx->keyblock, secblock );
}
@@ -2078,7 +2261,8 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
else if( item->mode == 15 ) {
found = 1;
}
- else if( item->mode == 16 || item->mode == 20 ) {
+ else if( item->mode == 16 || item->mode == 20
+ || item->mode == 21 ) {
k = find_by_fpr( ctx->keyblock,
item->fprint, item->mode );
found = !!k;
@@ -2218,7 +2402,7 @@ enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys )
save_mode = set_packet_list_mode(0);
init_packet(&pkt);
- while( (rc=parse_packet(c->iobuf, &pkt)) != -1 ) {
+ while( (rc=parse_packet(c->iobuf, &pkt, NULL)) != -1 ) {
if( rc )
; /* e.g. unknown packet */
else if( pkt.pkttype == PKT_SECRET_KEY
diff --git a/g10/import.c b/g10/import.c
index 94b83f080..fa21fbc34 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -274,7 +274,7 @@ read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root )
in_cert = 0;
pkt = gcry_xmalloc( sizeof *pkt );
init_packet(pkt);
- while( (rc=parse_packet(a, pkt)) != -1 ) {
+ while( (rc=parse_packet(a, pkt, NULL)) != -1 ) {
if( rc ) { /* ignore errors */
if( rc != GPGERR_UNKNOWN_PACKET ) {
log_error("read_block: read error: %s\n", gpg_errstr(rc) );
@@ -436,7 +436,7 @@ import_one( const char *fname, KBNODE keyblock, int fast )
if( (rc=lock_keyblock( &kbpos )) )
log_error(_("can't lock keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), gpg_errstr(rc) );
- else if( (rc=insert_keyblock( &kbpos, keyblock )) )
+ else if( (rc=insert_keyblock( keyblock )) )
log_error( _("error writing keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), gpg_errstr(rc) );
unlock_keyblock( &kbpos );
@@ -466,18 +466,12 @@ import_one( const char *fname, KBNODE keyblock, int fast )
}
/* now read the original keyblock */
- rc = find_keyblock_bypk( &kbpos, pk_orig );
+ rc = find_keyblock_bypk( &keyblock_orig, pk_orig );
if( rc ) {
log_error( _("key %08lX: can't locate original keyblock: %s\n"),
(ulong)keyid[1], gpg_errstr(rc));
goto leave;
}
- rc = read_keyblock( &kbpos, &keyblock_orig );
- if( rc ) {
- log_error( _("key %08lX: can't read original keyblock: %s\n"),
- (ulong)keyid[1], gpg_errstr(rc));
- goto leave;
- }
collapse_uids( &keyblock );
/* and try to merge the block */
@@ -494,7 +488,7 @@ import_one( const char *fname, KBNODE keyblock, int fast )
if( (rc=lock_keyblock( &kbpos )) )
log_error( _("can't lock keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), gpg_errstr(rc) );
- else if( (rc=update_keyblock( &kbpos, keyblock_orig )) )
+ else if( (rc=update_keyblock( keyblock_orig )) )
log_error( _("error writing keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), gpg_errstr(rc) );
unlock_keyblock( &kbpos );
@@ -603,7 +597,7 @@ import_secret_one( const char *fname, KBNODE keyblock )
if( (rc=lock_keyblock( &kbpos )) )
log_error( _("can't lock keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), gpg_errstr(rc) );
- else if( (rc=insert_keyblock( &kbpos, keyblock )) )
+ else if( (rc=insert_keyblock( keyblock )) )
log_error( _("error writing keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), gpg_errstr(rc) );
unlock_keyblock( &kbpos );
@@ -659,18 +653,12 @@ import_revoke_cert( const char *fname, KBNODE node )
}
/* read the original keyblock */
- rc = find_keyblock_bypk( &kbpos, pk );
+ rc = find_keyblock_bypk( &keyblock, pk );
if( rc ) {
log_error( _("key %08lX: can't locate original keyblock: %s\n"),
(ulong)keyid[1], gpg_errstr(rc));
goto leave;
}
- rc = read_keyblock( &kbpos, &keyblock );
- if( rc ) {
- log_error( _("key %08lX: can't read original keyblock: %s\n"),
- (ulong)keyid[1], gpg_errstr(rc));
- goto leave;
- }
/* it is okay, that node is not in keyblock because
@@ -704,7 +692,7 @@ import_revoke_cert( const char *fname, KBNODE node )
if( (rc=lock_keyblock( &kbpos )) )
log_error( _("can't lock keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), gpg_errstr(rc) );
- else if( (rc=update_keyblock( &kbpos, keyblock )) )
+ else if( (rc=update_keyblock( keyblock )) )
log_error( _("error writing keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), gpg_errstr(rc) );
unlock_keyblock( &kbpos );
diff --git a/g10/keydb.h b/g10/keydb.h
index 43c36e719..95d369ed4 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -21,10 +21,6 @@
#ifndef GPG_KEYDB_H
#define GPG_KEYDB_H
-#ifdef HAVE_LIBGDBM
- #include <gdbm.h>
-#endif
-
#include "types.h"
#include "basicdefs.h"
#include "packet.h"
@@ -67,30 +63,16 @@ struct kbnode_struct {
enum resource_type {
rt_UNKNOWN = 0,
rt_RING = 1,
- rt_GDBM = 2,
- rt_KBXF = 3
+ rt_KBXF = 2
};
/****************
- * A data structre to hold information about the external position
+ * A data structure to hold information about the external position
* of a keyblock.
*/
-struct keyblock_pos_struct {
- int resno; /* resource number */
- enum resource_type rt;
- ulong offset; /* position information */
- unsigned count; /* length of the keyblock in packets */
- IOBUF fp; /* used by enum_keyblocks */
- int secret; /* working on a secret keyring */
- #ifdef HAVE_LIBGDBM
- GDBM_FILE dbf;
- byte keybuf[21];
- #endif
- PACKET *pkt; /* ditto */
- int valid;
-};
-typedef struct keyblock_pos_struct KBPOS;
+struct keyblock_pos_struct;
+typedef struct keyblock_pos_struct *KBPOS;
/* structure to hold a couple of public key certificates */
struct pk_list {
@@ -106,18 +88,6 @@ struct sk_list {
int mark;
};
-/* structure to collect all information which can be used to
- * identify a public key */
-typedef struct pubkey_find_info *PUBKEY_FIND_INFO;
-struct pubkey_find_info {
- u32 keyid[2];
- unsigned nbits;
- byte pubkey_algo;
- byte fingerprint[MAX_FINGERPRINT_LEN];
- char userid[1];
-};
-
-
/*-- pkclist.c --*/
int check_signatures_trust( PKT_signature *sig );
@@ -159,11 +129,18 @@ int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
size_t fprint_len );
int get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid );
int seckey_available( u32 *keyid );
-int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock );
+int get_seckey_byname( GETKEY_CTX *rx,
+ PKT_secret_key *sk, const char *name, int unlock,
+ KBNODE *retblock );
int get_seckey_bynames( GETKEY_CTX *rx, PKT_secret_key *sk,
STRLIST names, KBNODE *ret_keyblock );
int get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock );
void get_seckey_end( GETKEY_CTX ctx );
+int find_keyblock_byname( KBNODE *retblock, const char *username );
+int find_secret_keyblock_byname( KBNODE *retblock, const char *username );
+int find_keyblock_bypk( KBNODE *retblock, PKT_public_key *pk );
+int find_keyblock_bysk( KBNODE *retblock, PKT_secret_key *sk );
+
int enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys );
void merge_keys_and_selfsig( KBNODE keyblock );
void merge_public_with_secret ( KBNODE pubblock, KBNODE secblock );
@@ -187,6 +164,10 @@ const char *expirestr_from_pk( PKT_public_key *pk );
const char *expirestr_from_sk( PKT_secret_key *sk );
byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf, size_t *ret_len );
byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
+char *unified_fingerprint_from_pk( PKT_public_key *pk,
+ char *buffer, size_t bufsize );
+char *unified_fingerprint_from_sk( PKT_secret_key *sk,
+ char *buffer, size_t bufsize );
/*-- kbnode.c --*/
KBNODE new_kbnode( PACKET *pkt );
@@ -208,25 +189,13 @@ void dump_kbnode( KBNODE node );
/*-- ringedit.c --*/
const char *enum_keyblock_resources( int *sequence, int secret );
int add_keyblock_resource( const char *resname, int force, int secret );
-const char *keyblock_resource_name( KBPOS *kbpos );
-int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos );
+const char *keyblock_resource_name( KBPOS kbpos );
+int get_keyblock_handle( const char *filename, int secret, KBPOS kbpos );
char *get_writable_keyblock_file( int secret );
-int locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr,
- int fprlen, int secret );
-int locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid,
- int shortkid, int secret );
-int find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos );
-int find_keyblock_byname( KBPOS *kbpos, const char *username );
-int find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk );
-int find_keyblock_bysk( KBPOS *kbpos, PKT_secret_key *sk );
-int find_secret_keyblock_byname( KBPOS *kbpos, const char *username );
-int lock_keyblock( KBPOS *kbpos );
-void unlock_keyblock( KBPOS *kbpos );
-int read_keyblock( KBPOS *kbpos, KBNODE *ret_root );
-int enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root );
-int insert_keyblock( KBPOS *kbpos, KBNODE root );
-int delete_keyblock( KBPOS *kbpos );
-int update_keyblock( KBPOS *kbpos, KBNODE root );
+int enum_keyblocks( int mode, KBPOS kbpos, KBNODE *ret_root );
+int insert_keyblock( KBNODE keyblock );
+int delete_keyblock( KBNODE keyblock );
+int update_keyblock( KBNODE keyblock );
#endif /*GPG_KEYDB_H*/
diff --git a/g10/keyedit.c b/g10/keyedit.c
index b7e836711..095e43baf 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -89,18 +89,13 @@ get_keyblock_byname( KBNODE *keyblock, KBPOS *kbpos, const char *username )
*keyblock = NULL;
/* search the userid */
- rc = find_keyblock_byname( kbpos, username );
+ rc = find_keyblock_byname( keyblock, username );
if( rc ) {
- log_error(_("%s: user not found\n"), username );
+ log_error(_("%s: user not found: %s\n"), username, gpg_errstr(rc) );
return rc;
}
- /* read the keyblock */
- rc = read_keyblock( kbpos, keyblock );
- if( rc )
- log_error("%s: keyblock read problem: %s\n", username, gpg_errstr(rc));
- else
- merge_keys_and_selfsig( *keyblock );
+ merge_keys_and_selfsig( *keyblock );
return rc;
}
@@ -616,7 +611,6 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
KBNODE keyblock = NULL;
KBPOS keyblockpos;
KBNODE sec_keyblock = NULL;
- KBPOS sec_keyblockpos;
KBNODE cur_keyblock;
char *answer = NULL;
int redisplay = 1;
@@ -640,14 +634,11 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
if( !sign_mode ) {
/* first try to locate it as secret key */
- rc = find_secret_keyblock_byname( &sec_keyblockpos, username );
- if( !rc ) {
- rc = read_keyblock( &sec_keyblockpos, &sec_keyblock );
- if( rc ) {
- log_error("%s: secret keyblock read problem: %s\n",
+ rc = find_secret_keyblock_byname( &sec_keyblock, username );
+ if( rc && rc != GPGERR_NO_SECKEY )
+ log_debug("%s: secret keyblock read problem: %s\n",
username, gpg_errstr(rc));
- goto leave;
- }
+ if( !rc ) {
merge_keys_and_selfsig( sec_keyblock );
if( fix_keyblock( sec_keyblock ) )
sec_modified++;
@@ -966,14 +957,14 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
do_cmd_save:
if( modified || sec_modified ) {
if( modified ) {
- rc = update_keyblock( &keyblockpos, keyblock );
+ rc = update_keyblock( keyblock );
if( rc ) {
log_error(_("update failed: %s\n"), gpg_errstr(rc) );
break;
}
}
if( sec_modified ) {
- rc = update_keyblock( &sec_keyblockpos, sec_keyblock );
+ rc = update_keyblock( sec_keyblock );
if( rc ) {
log_error(_("update secret failed: %s\n"),
gpg_errstr(rc) );
diff --git a/g10/keygen.c b/g10/keygen.c
index ef0064fc7..d3887dd7d 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -1752,9 +1752,9 @@ do_generate_keypair( struct para_data_s *para,
log_error("can't lock public keyring: %s\n", gpg_errstr(rc) );
else if( (rc=rc2=lock_keyblock( &sec_kbpos )) )
log_error("can't lock secret keyring: %s\n", gpg_errstr(rc) );
- else if( (rc=insert_keyblock( &pub_kbpos, pub_root )) )
+ else if( (rc=insert_keyblock( pub_root )) )
log_error("can't write public key: %s\n", gpg_errstr(rc) );
- else if( (rc=insert_keyblock( &sec_kbpos, sec_root )) )
+ else if( (rc=insert_keyblock( sec_root )) )
log_error("can't write secret key: %s\n", gpg_errstr(rc) );
else {
if( !opt.batch )
diff --git a/g10/keyid.c b/g10/keyid.c
index a4acb16d5..0269a6bb0 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -436,6 +436,40 @@ fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
return array;
}
+
+/* Create a unified fingerprint, that is a printable fingerprint along
+ * wth some other information suitable to passto get_pubkye_byname.
+ * Pass NULL for buffer to let this function allocate the buffer.
+ * This function will truncate the buffer in a way that a valid C string
+ * is returnd (unless bufsize is 0)
+ * Returns: Supplied buffer or newly allocated buffer
+ */
+char *
+unified_fingerprint_from_pk( PKT_public_key *pk,
+ char *buffer, size_t bufsize )
+{
+ byte fpr[MAX_FINGERPRINT_LEN];
+ size_t fprlen;
+ int i;
+
+ fingerprint_from_pk( pk, fpr, &fprlen );
+ if ( !buffer ) {
+ bufsize = 1+fprlen*2+1+4+1+1;
+ buffer = gcry_xmalloc( bufsize );
+ }
+ if ( bufsize < 1+fprlen*2+1+4+1+1 ) {
+ /* Hmmm, that should be sufficiend also not very nice */
+ if ( bufsize )
+ *buffer = 0;
+ return buffer;
+ }
+ *buffer = ':';
+ for (i=0; i < fprlen; i++ )
+ sprintf( buffer+1+i*2, "%02X", fpr[i] );
+ sprintf( buffer+1+i*2, ":%d:", (pk->pubkey_algo & 0xff) );
+ return buffer;
+}
+
byte *
fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
{
@@ -495,5 +529,36 @@ fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
return array;
}
+char *
+unified_fingerprint_from_sk( PKT_secret_key *sk,
+ char *buffer, size_t bufsize )
+{
+ byte fpr[MAX_FINGERPRINT_LEN];
+ size_t fprlen;
+ int i;
+
+ fingerprint_from_sk( sk, fpr, &fprlen );
+ if ( !buffer ) {
+ bufsize = 1+fprlen*2+1+4+1+1;
+ buffer = gcry_xmalloc( bufsize );
+ }
+ if ( bufsize < 1+fprlen*2+1+4+1+1 ) {
+ /* Hmmm, that should be sufficiend also not very nice */
+ if ( bufsize )
+ *buffer = 0;
+ return buffer;
+ }
+ *buffer = ':';
+ for (i=0; i < fprlen; i++ )
+ sprintf( buffer+1+i*2, "%02X", fpr[i] );
+ sprintf( buffer+1+i*2, ":%d:", (sk->pubkey_algo & 0xff) );
+ return buffer;
+}
+
+
+
+
+
+
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 09c35db21..7b04b3e6f 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -953,7 +953,7 @@ do_proc_packets( CTX c, IOBUF a )
c->iobuf = a;
init_packet(pkt);
- while( (rc=parse_packet(a, pkt)) != -1 ) {
+ while( (rc=parse_packet(a, pkt, NULL)) != -1 ) {
any_data = 1;
if( rc ) {
free_packet(pkt);
diff --git a/g10/packet.h b/g10/packet.h
index 03fa2ca6e..33bcf792a 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -293,18 +293,19 @@ int set_packet_list_mode( int mode );
#if DEBUG_PARSE_PACKET
int dbg_search_packet( IOBUF inp, PACKET *pkt, int pkttype, ulong *retpos, const char* file, int lineno );
-int dbg_parse_packet( IOBUF inp, PACKET *ret_pkt, const char* file, int lineno );
+int dbg_parse_packet( IOBUF inp, PACKET *ret_pkt, ulong *pos,
+ const char* file, int lineno );
int dbg_copy_all_packets( IOBUF inp, IOBUF out, const char* file, int lineno );
int dbg_copy_some_packets( IOBUF inp, IOBUF out, ulong stopoff, const char* file, int lineno );
int dbg_skip_some_packets( IOBUF inp, unsigned n, const char* file, int lineno );
#define search_packet( a,b,c,d ) dbg_search_packet( (a), (b), (c), (d), __FILE__, __LINE__ )
-#define parse_packet( a, b ) dbg_parse_packet( (a), (b), __FILE__, __LINE__ )
+#define parse_packet( a, b, c ) dbg_parse_packet( (a), (b), (c), __FILE__, __LINE__ )
#define copy_all_packets( a,b ) dbg_copy_all_packets((a),(b), __FILE__, __LINE__ )
#define copy_some_packets( a,b,c ) dbg_copy_some_packets((a),(b),(c), __FILE__, __LINE__ )
#define skip_some_packets( a,b ) dbg_skip_some_packets((a),(b), __FILE__, __LINE__ )
#else
int search_packet( IOBUF inp, PACKET *pkt, int pkttype, ulong *retpos );
-int parse_packet( IOBUF inp, PACKET *ret_pkt);
+int parse_packet( IOBUF inp, PACKET *ret_pkt, ulong *retpos);
int copy_all_packets( IOBUF inp, IOBUF out );
int copy_some_packets( IOBUF inp, IOBUF out, ulong stopoff );
int skip_some_packets( IOBUF inp, unsigned n );
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 3cabe77b1..b22a59989 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -127,23 +127,25 @@ unknown_pubkey_warning( int algo )
*/
#ifdef DEBUG_PARSE_PACKET
int
-dbg_parse_packet( IOBUF inp, PACKET *pkt, const char *dbg_f, int dbg_l )
+dbg_parse_packet( IOBUF inp, PACKET *pkt, ulong *retpos,
+ const char *dbg_f, int dbg_l )
{
int skip, rc;
do {
- rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l );
+ rc = parse( inp, pkt, 0, retpos,
+ &skip, NULL, 0, "parse", dbg_f, dbg_l );
} while( skip );
return rc;
}
#else
int
-parse_packet( IOBUF inp, PACKET *pkt )
+parse_packet( IOBUF inp, PACKET *pkt, ulong *retpos )
{
int skip, rc;
do {
- rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 );
+ rc = parse( inp, pkt, 0, retpos, &skip, NULL, 0 );
} while( skip );
return rc;
}
diff --git a/g10/pkclist.c b/g10/pkclist.c
index d585880ea..1170c4088 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -779,7 +779,7 @@ default_recipient(void)
if( !opt.def_recipient_self )
return NULL;
sk = gcry_xcalloc( 1, sizeof *sk );
- i = get_seckey_byname( sk, NULL, 0 );
+ i = get_seckey_byname( NULL, sk, NULL, 0, NULL );
if( i ) {
free_secret_key( sk );
return NULL;
diff --git a/g10/revoke.c b/g10/revoke.c
index 4abd5edd7..e988e5e62 100644
--- a/g10/revoke.c
+++ b/g10/revoke.c
@@ -87,7 +87,6 @@ gen_revoke( const char *uname )
IOBUF out = NULL;
KBNODE keyblock = NULL;
KBNODE node;
- KBPOS kbpos;
struct revocation_reason_info *reason = NULL;
if( opt.batch ) {
@@ -102,16 +101,10 @@ gen_revoke( const char *uname )
/* search the userid */
- rc = find_secret_keyblock_byname( &kbpos, uname );
+ rc = find_secret_keyblock_byname( &keyblock, uname );
if( rc ) {
- log_error(_("secret key for user `%s' not found\n"), uname );
- goto leave;
- }
-
- /* read the keyblock */
- rc = read_keyblock( &kbpos, &keyblock );
- if( rc ) {
- log_error(_("error reading the certificate: %s\n"), gpg_errstr(rc) );
+ log_error(_("secret key for user `%s' not found: %s\n"),
+ uname, gpg_errstr(rc) );
goto leave;
}
diff --git a/g10/ringedit.c b/g10/ringedit.c
index 311cf41fc..de05ba6e2 100644
--- a/g10/ringedit.c
+++ b/g10/ringedit.c
@@ -48,9 +48,6 @@
#include <sys/stat.h>
#include <unistd.h> /* for truncate */
#include <assert.h>
-#ifdef HAVE_LIBGDBM
- #include <gdbm.h>
-#endif
#include <gcrypt.h>
#include "util.h"
@@ -71,47 +68,42 @@ struct resource_table_struct {
int secret; /* this is a secret keyring */
char *fname;
IOBUF iobuf;
- #ifdef HAVE_LIBGDBM
- GDBM_FILE dbf;
- #endif
enum resource_type rt;
DOTLOCK lockhd;
int is_locked;
};
typedef struct resource_table_struct RESTBL;
+
+struct keyblock_pos_struct {
+ int resno; /* resource number */
+ enum resource_type rt;
+ ulong offset; /* position information */
+ unsigned count; /* length of the keyblock in packets */
+ IOBUF fp; /* used by enum_keyblocks */
+ int secret; /* working on a secret keyring */
+ PACKET *pkt; /* ditto */
+ int valid;
+ ulong save_offset;
+};
+
+
+
+
#define MAX_RESOURCES 10
static RESTBL resource_table[MAX_RESOURCES];
static int default_public_resource;
static int default_secret_resource;
-static int search( PACKET *pkt, KBPOS *kbpos, int secret );
+static int keyring_enum( KBPOS kbpos, KBNODE *ret_root, int skipsigs );
+static int keyring_copy( KBPOS kbpos, int mode, KBNODE root );
-
-static int keyring_search( PACKET *pkt, KBPOS *kbpos, IOBUF iobuf,
- const char *fname );
-static int keyring_read( KBPOS *kbpos, KBNODE *ret_root );
-static int keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs );
-static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root );
-
-static int do_kbxf_search( PACKET *pkt, KBPOS *kbpos, IOBUF iobuf,
- const char *fname );
-static int do_kbxf_read( KBPOS *kbpos, KBNODE *ret_root );
-static int do_kbxf_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs );
-static int do_kbxf_copy( KBPOS *kbpos, int mode, KBNODE root );
-
-#ifdef HAVE_LIBGDBM
-static int do_gdbm_store( KBPOS *kbpos, KBNODE root, int update );
-static int do_gdbm_locate( GDBM_FILE dbf, KBPOS *kbpos,
- const byte *fpr, int fprlen );
-static int do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid );
-static int do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root );
-static int do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root );
-#endif
+static int do_kbxf_enum( KBPOS kbpos, KBNODE *ret_root, int skipsigs );
+static int do_kbxf_copy( KBPOS kbpos, int mode, KBNODE root );
static RESTBL *
-check_pos( KBPOS *kbpos )
+check_pos( KBPOS kbpos )
{
if( kbpos->resno < 0 || kbpos->resno >= MAX_RESOURCES )
return NULL;
@@ -120,15 +112,6 @@ check_pos( KBPOS *kbpos )
return resource_table + kbpos->resno;
}
-#ifdef HAVE_LIBGDBM
-static void
-fatal_gdbm_error( const char *string )
-{
- log_fatal("gdbm failed: %s\n", string);
-}
-
-#endif /* HAVE_LIBGDBM */
-
/****************
* Hmmm, how to avoid deadlock? They should not happen if everyone
@@ -208,7 +191,6 @@ add_keyblock_resource( const char *url, int force, int secret )
/* Do we have an URL?
- * gnupg-gdbm:filename := this is a GDBM resource
* gnupg-kbxf:filename := this is a KBX file resource
* gnupg-ring:filename := this is a plain keyring
* filename := See what is is, but create as plain keyring.
@@ -222,10 +204,6 @@ add_keyblock_resource( const char *url, int force, int secret )
rt = rt_KBXF;
resname += 11;
}
- else if( !strncmp( resname, "gnupg-gdbm:", 11 ) ) {
- rt = rt_GDBM;
- resname += 11;
- }
#ifndef HAVE_DRIVE_LETTERS
else if( strchr( resname, ':' ) ) {
log_error("%s: invalid URL\n", url );
@@ -263,22 +241,16 @@ add_keyblock_resource( const char *url, int force, int secret )
u32 magic;
if( fread( &magic, 4, 1, fp) == 1 ) {
- if( magic == 0x13579ace )
- rt = rt_GDBM;
- else if( magic == 0xce9a5713 )
- log_error("%s: endianess does not match\n", url );
- else {
- char buf[8];
-
- rt = rt_RING;
- if( fread( buf, 8, 1, fp) == 1 ) {
- if( !memcmp( buf+4, "KBXf", 4 )
- && buf[0] == 1 && buf[1] == 1 ) {
- rt = rt_KBXF;
- }
- }
- }
- }
+ char buf[8];
+
+ rt = rt_RING;
+ if( fread( buf, 8, 1, fp) == 1 ) {
+ if( !memcmp( buf+4, "KBXf", 4 )
+ && buf[0] == 1 && buf[1] == 1 ) {
+ rt = rt_KBXF;
+ }
+ }
+ }
else /* maybe empty: assume ring */
rt = rt_RING;
fclose( fp );
@@ -348,21 +320,6 @@ add_keyblock_resource( const char *url, int force, int secret )
#endif
break;
- #ifdef HAVE_LIBGDBM
- case rt_GDBM:
- resource_table[i].dbf = gdbm_open( filename, 0,
- force? GDBM_WRCREAT : GDBM_WRITER,
- S_IRUSR | S_IWUSR |
- S_IRGRP | S_IWGRP | S_IROTH,
- fatal_gdbm_error );
- if( !resource_table[i].dbf ) {
- log_error("%s: can't open gdbm file: %s\n",
- filename, gdbm_strerror(gdbm_errno));
- rc = GPGERR_OPEN_FILE;
- goto leave;
- }
- break;
- #endif
default:
log_error("%s: unsupported resource type\n", url );
@@ -403,7 +360,7 @@ add_keyblock_resource( const char *url, int force, int secret )
* Return the resource name of the keyblock associated with KBPOS.
*/
const char *
-keyblock_resource_name( KBPOS *kbpos )
+keyblock_resource_name( KBPOS kbpos )
{
RESTBL *rentry;
@@ -419,7 +376,7 @@ keyblock_resource_name( KBPOS *kbpos )
* Using a filename of NULL returns the default resource
*/
int
-get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos )
+get_keyblock_handle( const char *filename, int secret, KBPOS kbpos )
{
int i = 0;
@@ -471,253 +428,21 @@ get_writable_keyblock_file( int secret )
}
-/****************
- * Search a keyblock which starts with the given packet and puts all
- * information into KBPOS, which can be used later to access this key block.
- * This function looks into all registered keyblock sources.
- * PACKET must be a packet with either a secret_key or a public_key
- *
- * This function is intended to check whether a given certificate
- * is already in a keyring or to prepare it for editing.
- *
- * Returns: 0 if found, -1 if not found or an errorcode.
- */
-static int
-search( PACKET *pkt, KBPOS *kbpos, int secret )
-{
- int i, rc, last_rc=-1;
-
- for(i=0; i < MAX_RESOURCES; i++ ) {
- if( resource_table[i].used && !resource_table[i].secret == !secret ) {
- switch( resource_table[i].rt ) {
- case rt_RING:
- rc = keyring_search( pkt, kbpos, resource_table[i].iobuf,
- resource_table[i].fname );
- break;
- case rt_KBXF:
- rc = do_kbxf_search( pkt, kbpos, resource_table[i].iobuf,
- resource_table[i].fname );
- break;
- #ifdef HAVE_LIBGDBM
- case rt_GDBM: {
- PKT_public_key *req_pk = pkt->pkt.public_key;
- byte fpr[20];
- size_t fprlen;
-
- fingerprint_from_pk( req_pk, fpr, &fprlen );
- rc = do_gdbm_locate( resource_table[i].dbf,
- kbpos, fpr, fprlen );
- }
- break;
- #endif
- default: BUG();
- }
-
- kbpos->rt = resource_table[i].rt;
- if( !rc ) {
- kbpos->resno = i;
- kbpos->fp = NULL;
- return 0;
- }
- if( rc != -1 ) {
- log_error("error searching resource %d: %s\n",
- i, gpg_errstr(rc));
- last_rc = rc;
- }
- }
- }
- return last_rc;
-}
-
-
-/****************
- * Combined function to search for a username and get the position
- * of the keyblock.
- */
-int
-find_keyblock_byname( KBPOS *kbpos, const char *username )
-{
- PACKET pkt;
- PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
- int rc;
-
- rc = get_pubkey_byname( NULL, pk, username, NULL );
- if( rc ) {
- free_public_key(pk);
- return rc;
- }
-
- init_packet( &pkt );
- pkt.pkttype = PKT_PUBLIC_KEY;
- pkt.pkt.public_key = pk;
- rc = search( &pkt, kbpos, 0 );
- free_public_key(pk);
- return rc;
-}
-
-
-/****************
- * Combined function to search for a key and get the position
- * of the keyblock.
- */
-int
-find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk )
-{
- PACKET pkt;
- int rc;
-
- init_packet( &pkt );
- pkt.pkttype = PKT_PUBLIC_KEY;
- pkt.pkt.public_key = pk;
- rc = search( &pkt, kbpos, 0 );
- return rc;
-}
-
-/****************
- * Combined function to search for a key and get the position
- * of the keyblock.
- */
-int
-find_keyblock_bysk( KBPOS *kbpos, PKT_secret_key *sk )
-{
- PACKET pkt;
- int rc;
-
- init_packet( &pkt );
- pkt.pkttype = PKT_SECRET_KEY;
- pkt.pkt.secret_key = sk;
- rc = search( &pkt, kbpos, 0 );
- return rc;
-}
-
-
-/****************
- * Combined function to search for a username and get the position
- * of the keyblock. This function does not unprotect the secret key.
- */
-int
-find_secret_keyblock_byname( KBPOS *kbpos, const char *username )
+void
+ringedit_copy_kbpos ( KBPOS d, KBPOS s )
{
- PACKET pkt;
- PKT_secret_key *sk = gcry_xcalloc( 1, sizeof *sk );
- int rc;
-
- rc = get_seckey_byname( sk, username, 0 );
- if( rc ) {
- free_secret_key(sk);
- return rc;
- }
-
- init_packet( &pkt );
- pkt.pkttype = PKT_SECRET_KEY;
- pkt.pkt.secret_key = sk;
- rc = search( &pkt, kbpos, 1 );
- free_secret_key(sk);
- return rc;
+ *d = *s;
}
/****************
- * Locate a keyblock in a database which is capable of direct access
- * Put all information into KBPOS, which can be later be to access this
- * key block.
- * This function looks into all registered keyblock sources.
- *
- * Returns: 0 if found,
- * -1 if not found
- * GPGERR_UNSUPPORTED if no resource is able to handle this
- * or another errorcode.
- */
-int
-locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr, int fprlen, int secret )
-{
- RESTBL *rentry;
- int i, rc, any=0, last_rc=-1;
-
-
- for(i=0, rentry = resource_table; i < MAX_RESOURCES; i++, rentry++ ) {
- if( rentry->used && !rentry->secret == !secret ) {
- kbpos->rt = rentry->rt;
- switch( rentry->rt ) {
- #ifdef HAVE_LIBGDBM
- case rt_GDBM:
- any = 1;
- rc = do_gdbm_locate( rentry->dbf, kbpos, fpr, fprlen );
- break;
- #endif
- default:
- rc = GPGERR_UNSUPPORTED;
- break;
- }
-
- if( !rc ) {
- kbpos->resno = i;
- kbpos->fp = NULL;
- return 0;
- }
- else if( rc != -1 && rc != GPGERR_UNSUPPORTED ) {
- log_error("error searching resource %d: %s\n",
- i, gpg_errstr(rc));
- last_rc = rc;
- }
- }
- }
-
- return (last_rc == -1 && !any)? GPGERR_UNSUPPORTED : last_rc;
-}
-
-
-int
-locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid, int shortkid, int secret )
-{
- RESTBL *rentry;
- int i, rc, any=0, last_rc=-1;
-
- if( shortkid )
- return GPGERR_UNSUPPORTED;
-
- for(i=0, rentry = resource_table; i < MAX_RESOURCES; i++, rentry++ ) {
- if( rentry->used && !rentry->secret == !secret ) {
- kbpos->rt = rentry->rt;
- switch( rentry->rt ) {
- #ifdef HAVE_LIBGDBM
- case rt_GDBM:
- any = 1;
- rc = do_gdbm_locate_by_keyid( rentry->dbf, kbpos, keyid );
- break;
- #endif
- default:
- rc = GPGERR_UNSUPPORTED;
- break;
- }
-
- if( !rc ) {
- kbpos->resno = i;
- kbpos->fp = NULL;
- return 0;
- }
- else if( rc != -1 && rc != GPGERR_UNSUPPORTED ) {
- log_error("error searching resource %d: %s\n",
- i, gpg_errstr(rc));
- last_rc = rc;
- }
- }
- }
-
- return (last_rc == -1 && !any)? GPGERR_UNSUPPORTED : last_rc;
-}
-
-
-
-
-/****************
* Lock the keyblock; wait until it's available
* This function may change the internal data in kbpos, in cases
* when the keyblock to be locked has been modified.
* fixme: remove this function and add an option to search()?
*/
-int
-lock_keyblock( KBPOS *kbpos )
+static int
+lock_keyblock( KBPOS kbpos )
{
if( !check_pos(kbpos) )
return GPGERR_GENERAL;
@@ -727,35 +452,13 @@ lock_keyblock( KBPOS *kbpos )
/****************
* Release a lock on a keyblock
*/
-void
-unlock_keyblock( KBPOS *kbpos )
+static void
+unlock_keyblock( KBPOS kbpos )
{
if( !check_pos(kbpos) )
BUG();
}
-/****************
- * Read a complete keyblock and return the root in ret_root.
- */
-int
-read_keyblock( KBPOS *kbpos, KBNODE *ret_root )
-{
- if( !check_pos(kbpos) )
- return GPGERR_GENERAL;
-
- switch( kbpos->rt ) {
- case rt_RING:
- return keyring_read( kbpos, ret_root );
- case rt_KBXF:
- return do_kbxf_read( kbpos, ret_root );
- #ifdef HAVE_LIBGDBM
- case rt_GDBM:
- return do_gdbm_read( kbpos, ret_root );
- #endif
- default: BUG();
- }
-}
-
/****************
* This functions can be used to read through a complete keyring.
@@ -765,13 +468,9 @@ read_keyblock( KBPOS *kbpos, KBNODE *ret_root )
* 5 = open secret keyrings
* 11 = read but skip signature and comment packets.
* all others are reserved!
- * Note that you do not need a search prior to this function,
- * only a handle is needed.
- * NOTE: It is not allowed to do an insert/update/delete with this
- * keyblock, if you want to do this, use search/read!
*/
int
-enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
+enum_keyblocks( int mode, KBPOS kbpos, KBNODE *ret_root )
{
int rc = 0;
RESTBL *rentry;
@@ -811,12 +510,7 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
return GPGERR_OPEN_FILE;
}
break;
- #ifdef HAVE_LIBGDBM
- case rt_GDBM:
- /* FIXME: make sure that there is only one enum at a time */
- kbpos->offset = 0;
- break;
- #endif
+
default: BUG();
}
kbpos->pkt = NULL;
@@ -836,11 +530,6 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
return GPGERR_GENERAL;
rc = do_kbxf_enum( kbpos, ret_root, mode == 11 );
break;
- #ifdef HAVE_LIBGDBM
- case rt_GDBM:
- rc = do_gdbm_enum( kbpos, ret_root );
- break;
- #endif
default: BUG();
}
@@ -866,8 +555,6 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
kbpos->fp = NULL;
}
break;
- case rt_GDBM:
- break;
case rt_UNKNOWN:
/* this happens when we have no keyring at all */
return rc;
@@ -890,10 +577,10 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
* by KBPOS. This actually appends the data to the keyfile.
*/
int
-insert_keyblock( KBPOS *kbpos, KBNODE root )
+insert_keyblock( KBNODE root )
{
int rc;
-
+#if 0
if( !check_pos(kbpos) )
return GPGERR_GENERAL;
@@ -904,14 +591,9 @@ insert_keyblock( KBPOS *kbpos, KBNODE root )
case rt_KBXF:
rc = do_kbxf_copy( kbpos, 1, root );
break;
- #ifdef HAVE_LIBGDBM
- case rt_GDBM:
- rc = do_gdbm_store( kbpos, root, 0 );
- break;
- #endif
default: BUG();
}
-
+#endif
return rc;
}
@@ -922,10 +604,10 @@ insert_keyblock( KBPOS *kbpos, KBNODE root )
* zero bytes are written.
*/
int
-delete_keyblock( KBPOS *kbpos )
+delete_keyblock( KBNODE keyblock )
{
int rc;
-
+ #if 0
if( !check_pos(kbpos) )
return GPGERR_GENERAL;
@@ -936,42 +618,43 @@ delete_keyblock( KBPOS *kbpos )
case rt_KBXF:
rc = do_kbxf_copy( kbpos, 2, NULL );
break;
- #ifdef HAVE_LIBGDBM
- case rt_GDBM:
- log_debug("deleting gdbm keyblock is not yet implemented\n");
- rc = 0;
- break;
- #endif
default: BUG();
}
-
+ #endif
return rc;
}
/****************
- * Update the keyblock at KBPOS with the one in ROOT.
+ * Update the keyblock in the ring (or whatever resource) one in ROOT.
*/
int
-update_keyblock( KBPOS *kbpos, KBNODE root )
+update_keyblock( KBNODE root )
{
int rc;
+ struct WORK WORK WORK KBPOS kbpos;
+
+ /* We need to get the file position of original keyblock first */
+ if ( root->pkt->pkttype == PKT_PUBLIC_KEY )
+ rc = find_kblocation_bypk( &kbpos, root->pkt->pkt.public_key );
+ else if ( root->pkt->pkttype == PKT_SECRET_KEY )
+ rc = find_kblocation_bysk( &kbpos, root->pkt->pkt.secret_key );
+ else
+ BUG();
- if( !check_pos(kbpos) )
+ if ( rc )
+ return rc;
+
+ if( !check_pos(&kbpos) )
return GPGERR_GENERAL;
- switch( kbpos->rt ) {
+ switch( kbpos.rt ) {
case rt_RING:
- rc = keyring_copy( kbpos, 3, root );
+ rc = keyring_copy( &kbpos, 3, root );
break;
case rt_KBXF:
- rc = do_kbxf_copy( kbpos, 3, root );
- break;
- #ifdef HAVE_LIBGDBM
- case rt_GDBM:
- rc = do_gdbm_store( kbpos, root, 1 );
+ rc = do_kbxf_copy( &kbpos, 3, root );
break;
- #endif
default: BUG();
}
@@ -981,341 +664,34 @@ update_keyblock( KBPOS *kbpos, KBNODE root )
/****************************************************************
- ********** Implemenation of a user ID database **************
- ****************************************************************/
-#if 0
-/****************
- * Layout of the user ID db
- *
- * This user ID DB provides fast lookup of user ID, but the user ids are
- * not in any specific order.
- *
- * A string "GnuPG user db", a \n.
- * user ids of one key, delimited by \t,
- * a # or ^ followed by a 20 byte fingerprint, followed by an \n
- * The literal characters %, \n, \t, #, ^ must be replaced by a percent sign
- * and their hex value.
- *
- * (We use Boyer/Moore pattern matching)
- */
-
-/****************
- * This compiles pattern to the distance table, the table will be allocate
- * here and must be freed by using free().
- * Returns: Ptr to new allocated Table
- * Caller must free the table.
- */
-
-static size_t *
-compile_bm_table( const byte *pattern, size_t len )
-{
- ushort *dist;
- int i;
-
- dist = gcry_xcalloc( 1, 256 * sizeof *dist );
- for(i=0; i < 256; i++ )
- dist[i] = len;
- for(i=0; i < len-1; i++ )
- dTbl[p[i]] = len-i-1;
- return dist;
-}
-
-
-
-
-/****************
- * Search BUF of BUFLEN for pattern P of length PATLEN.
- * dist is the Boyer/Moore distance table of 256 Elements,
- * case insensitive search is done if IGNCASE is true (In this case
- * the distance table has to compiled from uppercase chacaters and
- * PAT must also be uppercase.
- * Returns: Prt to maching string in BUF, or NULL if not found.
- */
-
-static const *
-do_bm_search( const byte *buf, size_t buflen,
- const byte *pat, size_t patlen, size_t *dist, int igncase )
-{
- int i, j, k;
-
- if( igncase ) {
- int c, c1;
-
- for( i = --patlen; i < buflen; i += dist[c1] )
- for( j=patlen, k=i, c1=c=toupper(buf[k]); c == pat[j];
- j--, k--, c=toupper(buf[k]) ) {
- if( !j )
- return buf+k;
- }
- }
- else {
- for( i = --patlen; i < buflen; i += dist[buf[i]] )
- for( j=patlen, k=i; buf[k] == pat[j]; j--, k-- ) {
- if( !j )
- return buf+k;
- }
- }
- return NULL;
-}
-
-
-typedef struct {
- size_t dist[256];
-} *SCAN_USER_HANDLE;
-
-static SCAN_USER_HANDLE
-scan_user_file_open( const byte *name )
-{
- SCAN_USER_HANDLE hd;
- size_t *dist;
- int i;
-
- hd = gcry_xcalloc( 1, sizeof *hd );
- dist = hd->dist;
- /* compile the distance table */
- for(i=0; i < 256; i++ )
- dist[i] = len;
- for(i=0; i < len-1; i++ )
- dTbl[p[i]] = len-i-1;
- /* setup other things */
-
- return hd;
-}
-
-static int
-scan_user_file_close( SCAN_USER_HANDLE hd )
-{
- gcry_free( hd );
-}
-
-static int
-scan_user_file_read( SCAN_USER_HANDLE hd, byte *fpr )
-{
- char record[1000];
-
- /* read a record */
-
-
-}
-#endif
-
-
-
-/****************************************************************
********** Functions which operates on regular keyrings ********
****************************************************************/
static int
-cmp_seckey( PKT_secret_key *req_sk, PKT_secret_key *sk )
-{
- int n,i;
-
- assert( req_sk->pubkey_algo == sk->pubkey_algo );
-
- n = pubkey_get_nskey( req_sk->pubkey_algo );
- for(i=0; i < n; i++ ) {
- /* Note: because v4 protected keys have nothing in the
- * mpis except for the first one, we skip all NULL MPIs.
- * This might not be always correct in cases where the both
- * keys do not match in their secret parts but we can ignore that
- * because the need for this function is quite ugly. */
- if( req_sk->skey[1] && sk->skey[i]
- && mpi_cmp( req_sk->skey[i], sk->skey[i] ) )
- return -1;
- }
- return 0;
-}
-
-static int
-cmp_pubkey( PKT_public_key *req_pk, PKT_public_key *pk )
-{
- int n, i;
-
- assert( req_pk->pubkey_algo == pk->pubkey_algo );
-
- n = pubkey_get_npkey( req_pk->pubkey_algo );
- for(i=0; i < n; i++ ) {
- if( mpi_cmp( req_pk->pkey[i], pk->pkey[i] ) )
- return -1;
- }
- return 0;
-}
-
-/****************
- * search one keyring, return 0 if found, -1 if not found or an errorcode.
- */
-static int
-keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
-{
- int rc;
- PACKET pkt;
- int save_mode;
- ulong offset;
- int pkttype = req->pkttype;
- PKT_public_key *req_pk = req->pkt.public_key;
- PKT_secret_key *req_sk = req->pkt.secret_key;
-
- init_packet(&pkt);
- save_mode = set_packet_list_mode(0);
- kbpos->rt = rt_RING;
- kbpos->valid = 0;
-
- #if HAVE_DOSISH_SYSTEM || 1
- assert(!iobuf);
- iobuf = iobuf_open( fname );
- if( !iobuf ) {
- log_error("%s: can't open keyring file\n", fname);
- rc = GPGERR_KEYRING_OPEN;
- goto leave;
- }
- #else
- if( iobuf_seek( iobuf, 0 ) ) {
- log_error("can't rewind keyring file\n");
- rc = GPGERR_KEYRING_OPEN;
- goto leave;
- }
- #endif
-
- while( !(rc=search_packet(iobuf, &pkt, pkttype, &offset)) ) {
- if( pkt.pkttype == PKT_SECRET_KEY ) {
- PKT_secret_key *sk = pkt.pkt.secret_key;
-
- if( req_sk->timestamp == sk->timestamp
- && req_sk->pubkey_algo == sk->pubkey_algo
- && !cmp_seckey( req_sk, sk) )
- break; /* found */
- }
- else if( pkt.pkttype == PKT_PUBLIC_KEY ) {
- PKT_public_key *pk = pkt.pkt.public_key;
-
- if( req_pk->timestamp == pk->timestamp
- && req_pk->pubkey_algo == pk->pubkey_algo
- && !cmp_pubkey( req_pk, pk ) )
- break; /* found */
- }
- else
- BUG();
- free_packet(&pkt);
- }
- if( !rc ) {
- kbpos->offset = offset;
- kbpos->valid = 1;
- }
-
- leave:
- free_packet(&pkt);
- set_packet_list_mode(save_mode);
- #if HAVE_DOSISH_SYSTEM || 1
- iobuf_close(iobuf);
- #endif
- return rc;
-}
-
-
-static int
-keyring_read( KBPOS *kbpos, KBNODE *ret_root )
-{
- PACKET *pkt;
- int rc;
- RESTBL *rentry;
- KBNODE root = NULL;
- IOBUF a;
- int in_cert = 0;
-
- if( !(rentry=check_pos(kbpos)) )
- return GPGERR_GENERAL;
-
- a = iobuf_open( rentry->fname );
- if( !a ) {
- log_error("can't open `%s'\n", rentry->fname );
- return GPGERR_OPEN_FILE;
- }
-
- if( !kbpos->valid )
- log_debug("kbpos not valid in keyring_read, want %d\n", (int)kbpos->offset );
- if( iobuf_seek( a, kbpos->offset ) ) {
- log_error("can't seek to %lu\n", kbpos->offset);
- iobuf_close(a);
- return GPGERR_KEYRING_OPEN;
- }
-
- pkt = gcry_xmalloc( sizeof *pkt );
- init_packet(pkt);
- kbpos->count=0;
- while( (rc=parse_packet(a, pkt)) != -1 ) {
- if( rc ) { /* ignore errors */
- if( rc != GPGERR_UNKNOWN_PACKET ) {
- log_error("read_keyblock: read error: %s\n", gpg_errstr(rc) );
- rc = GPGERR_INV_KEYRING;
- goto ready;
- }
- kbpos->count++;
- free_packet( pkt );
- init_packet( pkt );
- continue;
- }
- /* make a linked list of all packets */
- switch( pkt->pkttype ) {
- case PKT_COMPRESSED:
- log_error("skipped compressed packet in keyring\n" );
- free_packet(pkt);
- init_packet(pkt);
- break;
-
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- if( in_cert )
- goto ready;
- in_cert = 1;
- default:
- kbpos->count++;
- if( !root )
- root = new_kbnode( pkt );
- else
- add_kbnode( root, new_kbnode( pkt ) );
- pkt = gcry_xmalloc( sizeof *pkt );
- init_packet(pkt);
- break;
- }
- }
- ready:
- kbpos->valid = 0;
- if( rc == -1 && root )
- rc = 0;
-
- if( rc )
- release_kbnode( root );
- else
- *ret_root = root;
- free_packet( pkt );
- gcry_free( pkt );
- iobuf_close(a);
- return rc;
-}
-
-
-static int
keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
{
PACKET *pkt;
int rc;
RESTBL *rentry;
KBNODE root = NULL;
+ ulong offset, first_offset=0;
if( !(rentry=check_pos(kbpos)) )
return GPGERR_GENERAL;
if( kbpos->pkt ) {
root = new_kbnode( kbpos->pkt );
+ first_offset = kbpos->save_offset;
kbpos->pkt = NULL;
}
+ kbpos->valid = 0;
pkt = gcry_xmalloc( sizeof *pkt );
init_packet(pkt);
- while( (rc=parse_packet(kbpos->fp, pkt)) != -1 ) {
+ while( (rc=parse_packet(kbpos->fp, pkt, &offset )) != -1 ) {
if( rc ) { /* ignore errors */
if( rc != GPGERR_UNKNOWN_PACKET ) {
- log_error("read_keyblock: read error: %s\n", gpg_errstr(rc) );
+ log_error("keyring_enum: read error: %s\n", gpg_errstr(rc) );
rc = GPGERR_INV_KEYRING;
goto ready;
}
@@ -1333,12 +709,14 @@ keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
case PKT_PUBLIC_KEY:
case PKT_SECRET_KEY:
- if( root ) { /* store this packet */
+ if( root ) { /* save this packet */
kbpos->pkt = pkt;
+ kbpos->save_offset = offset;
pkt = NULL;
goto ready;
}
root = new_kbnode( pkt );
+ first_offset = offset;
pkt = gcry_xmalloc( sizeof *pkt );
init_packet(pkt);
break;
@@ -1368,8 +746,13 @@ keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
if( rc )
release_kbnode( root );
- else
+ else {
+ if ( root ) {
+ kbpos->offset = first_offset;
+ kbpos->valid = 1;
+ }
*ret_root = root;
+ }
free_packet( pkt );
gcry_free( pkt );
@@ -1391,11 +774,11 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
int rc=0;
char *bakfname = NULL;
char *tmpfname = NULL;
+#warning We need to lock the keyring while we are editing it.
+ /* rethink this whole module */
if( !(rentry = check_pos( kbpos )) )
return GPGERR_GENERAL;
- if( kbpos->fp )
- BUG(); /* not allowed with such a handle */
if( opt.dry_run )
return 0;
@@ -1403,6 +786,13 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
lock_rentry( rentry );
/* open the source file */
+ if( kbpos->fp ) {
+ /* BUG(); not allowed with such a handle */
+ log_debug("keyring_copy: closing fp %p\n", kbpos->fp );
+ iobuf_close (kbpos->fp);
+ kbpos->fp = NULL;
+ kbpos->valid = 0;
+ }
fp = iobuf_open( rentry->fname );
if( mode == 1 && !fp && errno == ENOENT ) { /* no file yet */
KBNODE kbctx, node;
@@ -1612,159 +1002,6 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
********** Functions which operate on KBX files ****************
****************************************************************/
-/****************
- * search a KBX file return 0 if found, -1 if not found or an errorcode.
- */
-static int
-do_kbxf_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
-{
- int rc;
- PACKET pkt;
- int save_mode;
- ulong offset;
- int pkttype = req->pkttype;
- PKT_public_key *req_pk = req->pkt.public_key;
- PKT_secret_key *req_sk = req->pkt.secret_key;
-
- init_packet(&pkt);
- save_mode = set_packet_list_mode(0);
- kbpos->rt = rt_RING;
- kbpos->valid = 0;
-
- #if HAVE_DOSISH_SYSTEM || 1
- assert(!iobuf);
- iobuf = iobuf_open( fname );
- if( !iobuf ) {
- log_error("%s: can't open keyring file\n", fname);
- rc = GPGERR_KEYRING_OPEN;
- goto leave;
- }
- #else
- if( iobuf_seek( iobuf, 0 ) ) {
- log_error("can't rewind keyring file\n");
- rc = GPGERR_KEYRING_OPEN;
- goto leave;
- }
- #endif
-
- while( !(rc=search_packet(iobuf, &pkt, pkttype, &offset)) ) {
- if( pkt.pkttype == PKT_SECRET_KEY ) {
- PKT_secret_key *sk = pkt.pkt.secret_key;
-
- if( req_sk->timestamp == sk->timestamp
- && req_sk->pubkey_algo == sk->pubkey_algo
- && !cmp_seckey( req_sk, sk) )
- break; /* found */
- }
- else if( pkt.pkttype == PKT_PUBLIC_KEY ) {
- PKT_public_key *pk = pkt.pkt.public_key;
-
- if( req_pk->timestamp == pk->timestamp
- && req_pk->pubkey_algo == pk->pubkey_algo
- && !cmp_pubkey( req_pk, pk ) )
- break; /* found */
- }
- else
- BUG();
- free_packet(&pkt);
- }
- if( !rc ) {
- kbpos->offset = offset;
- kbpos->valid = 1;
- }
-
- leave:
- free_packet(&pkt);
- set_packet_list_mode(save_mode);
- #if HAVE_DOSISH_SYSTEM || 1
- iobuf_close(iobuf);
- #endif
- return rc;
-}
-
-
-static int
-do_kbxf_read( KBPOS *kbpos, KBNODE *ret_root )
-{
- PACKET *pkt;
- int rc;
- RESTBL *rentry;
- KBNODE root = NULL;
- IOBUF a;
- int in_cert = 0;
-
- if( !(rentry=check_pos(kbpos)) )
- return GPGERR_GENERAL;
-
- a = iobuf_open( rentry->fname );
- if( !a ) {
- log_error("can't open `%s'\n", rentry->fname );
- return GPGERR_OPEN_FILE;
- }
-
- if( !kbpos->valid )
- log_debug("kbpos not valid in keyring_read, want %d\n", (int)kbpos->offset );
- if( iobuf_seek( a, kbpos->offset ) ) {
- log_error("can't seek to %lu\n", kbpos->offset);
- iobuf_close(a);
- return GPGERR_KEYRING_OPEN;
- }
-
- pkt = gcry_xmalloc( sizeof *pkt );
- init_packet(pkt);
- kbpos->count=0;
- while( (rc=parse_packet(a, pkt)) != -1 ) {
- if( rc ) { /* ignore errors */
- if( rc != GPGERR_UNKNOWN_PACKET ) {
- log_error("read_keyblock: read error: %s\n", gpg_errstr(rc) );
- rc = GPGERR_INV_KEYRING;
- goto ready;
- }
- kbpos->count++;
- free_packet( pkt );
- init_packet( pkt );
- continue;
- }
- /* make a linked list of all packets */
- switch( pkt->pkttype ) {
- case PKT_COMPRESSED:
- log_error("skipped compressed packet in keyring\n" );
- free_packet(pkt);
- init_packet(pkt);
- break;
-
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- if( in_cert )
- goto ready;
- in_cert = 1;
- default:
- kbpos->count++;
- if( !root )
- root = new_kbnode( pkt );
- else
- add_kbnode( root, new_kbnode( pkt ) );
- pkt = gcry_xmalloc( sizeof *pkt );
- init_packet(pkt);
- break;
- }
- }
- ready:
- kbpos->valid = 0;
- if( rc == -1 && root )
- rc = 0;
-
- if( rc )
- release_kbnode( root );
- else
- *ret_root = root;
- free_packet( pkt );
- gcry_free( pkt );
- iobuf_close(a);
- return rc;
-}
-
-
static int
do_kbxf_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
{
@@ -1783,10 +1020,10 @@ do_kbxf_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
pkt = gcry_xmalloc( sizeof *pkt );
init_packet(pkt);
- while( (rc=parse_packet(kbpos->fp, pkt)) != -1 ) {
+ while( (rc=parse_packet(kbpos->fp, pkt, NULL)) != -1 ) {
if( rc ) { /* ignore errors */
if( rc != GPGERR_UNKNOWN_PACKET ) {
- log_error("read_keyblock: read error: %s\n", gpg_errstr(rc) );
+ log_error("do_kbxf_enum: read error: %s\n", gpg_errstr(rc) );
rc = GPGERR_INV_KEYRING;
goto ready;
}
@@ -2079,300 +1316,5 @@ do_kbxf_copy( KBPOS *kbpos, int mode, KBNODE root )
}
-
-#ifdef HAVE_LIBGDBM
-/****************************************************************
- ********** Functions which operates on GDM files ***************
- ****************************************************************/
-
-#if MAX_FINGERPRINT_LEN > 20
- #error A GDBM keyring assumes that fingerprints are less than 21
-#endif
-
-/****************
- * Insert the keyblock into the GDBM database
- */
-
-static int
-do_gdbm_store( KBPOS *kbpos, KBNODE root, int update )
-{
- RESTBL *rentry;
- PKT_public_key *pk;
- KBNODE kbctx, node;
- IOBUF fp = NULL;
- byte fpr[20];
- byte contbuf[21];
- byte keybuf[21];
- size_t fprlen;
- datum key, content;
- int i, rc;
-
- if( !(rentry = check_pos( kbpos )) )
- return GPGERR_GENERAL;
-
- if( opt.dry_run )
- return 0;
-
- /* construct the fingerprint which is used as the primary key */
- node = find_kbnode( root, PKT_PUBLIC_KEY );
- if( !node )
- log_bug("a gdbm database can't store secret keys\n");
- pk = node->pkt->pkt.public_key;
-
- fingerprint_from_pk( pk, fpr, &fprlen );
- for(i=fprlen; i < DIM(fpr); i++ )
- fpr[i] = 0;
-
- /* build the keyblock */
- kbctx=NULL;
- fp = iobuf_temp();
- iobuf_put( fp, 1 ); /* data is a keyblock */
- while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
- if( (rc = build_packet( fp, node->pkt )) ) {
- log_error("build_packet(%d) failed: %s\n",
- node->pkt->pkttype, gpg_errstr(rc) );
- rc = GPGERR_WRITE_FILE;
- goto leave;
- }
- }
- /* store data and key */
- *keybuf = 1; /* key is a padded fingerprint */
- memcpy(keybuf+1, fpr, 20 );
- key.dptr = keybuf;
- key.dsize = 21;
- content.dptr = iobuf_get_temp_buffer( fp );
- content.dsize = iobuf_get_temp_length( fp );
- rc = gdbm_store( rentry->dbf, key, content,
- update? GDBM_REPLACE : GDBM_INSERT );
- if( rc == 1 && !update )
- rc = gdbm_store( rentry->dbf, key, content, GDBM_REPLACE );
-
- if( rc ) {
- log_error("%s: gdbm_store failed: %s\n", rentry->fname,
- rc == 1 ? "already stored"
- : gdbm_strerror(gdbm_errno) );
- rc = GPGERR_WRITE_FILE;
- goto leave;
- }
- /* now store all keyids */
- *contbuf = 2; /* data is a list of fingerprints */
- memcpy(contbuf+1, fpr, 20 );
- content.dptr = contbuf;
- content.dsize= 21;
- kbctx=NULL;
- while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
- if( node->pkt->pkttype == PKT_PUBLIC_KEY
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- u32 aki[2];
-
- keyid_from_pk( node->pkt->pkt.public_key, aki );
- *keybuf = 2; /* key is a 8 byte keyid */
- u32tobuf( keybuf+1 , aki[0] );
- u32tobuf( keybuf+5, aki[1] );
- key.dptr = keybuf;
- key.dsize= 9;
- /* fixme: must be more clever when a insert failed:
- * build a list of fingerprints in this case */
- rc = gdbm_store( rentry->dbf, key, content,
- update? GDBM_REPLACE : GDBM_INSERT );
- if( rc ) {
- log_info("%s: gdbm_store keyid failed: %s\n", rentry->fname,
- rc == 1 ? "already stored"
- : gdbm_strerror(gdbm_errno) );
- rc = 0;
- }
- }
- }
-
- leave:
- iobuf_close(fp); /* don't need a cancel because it is a temp iobuf */
- return rc;
-}
-
-
-/****************
- * search one keybox, return 0 if found, -1 if not found or an errorcode.
- */
-static int
-do_gdbm_locate( GDBM_FILE dbf, KBPOS *kbpos, const byte *fpr, int fprlen )
-{
- byte *keybuf = kbpos->keybuf;
- datum key;
- int i;
-
- *keybuf = 1;
- for(i=0; i < fprlen; i++ )
- keybuf[i+1] = fpr[i];
- for(; i < 20; i++ )
- keybuf[i+1] = 0;
-
- /* fetch the data */
- key.dptr = keybuf;
- key.dsize = 21;
- if( !gdbm_exists( dbf, key ) )
- return -1; /* not found */
- return 0;
-}
-
-/****************
- * locate by keyid.
- * FIXME: we must have a way to enumerate thru the list opf fingerprints
- */
-static int
-do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid )
-{
- byte keybuf[9];
- datum key, content;
- int rc;
-
- /* construct the fingerprint which is used as the primary key */
- *keybuf = 2;
- u32tobuf( keybuf+1, keyid[0] );
- u32tobuf( keybuf+5, keyid[1] );
-
- /* fetch the data */
- key.dptr = keybuf;
- key.dsize = 9;
- content = gdbm_fetch( dbf, key );
- if( !content.dptr )
- return -1;
-
- if( content.dsize < 2 ) {
- log_error("gdbm_fetch did not return enough data\n" );
- free( content.dptr ); /* can't use gcry_free() here */
- return GPGERR_INV_KEYRING;
- }
- if( *content.dptr != 2 ) {
- log_error("gdbm_fetch returned unexpected type %d\n",
- *(byte*)content.dptr );
- free( content.dptr ); /* can't use gcry_free() here */
- return GPGERR_INV_KEYRING;
- }
- if( content.dsize < 21 ) {
- log_error("gdbm_fetch did not return a complete fingerprint\n" );
- free( content.dptr ); /* can't use gcry_free() here */
- return GPGERR_INV_KEYRING;
- }
- if( content.dsize > 21 )
- log_info("gdbm_fetch: WARNING: more than one fingerprint\n" );
-
- rc = do_gdbm_locate( dbf, kbpos, content.dptr+1, 20 );
- free( content.dptr ); /* can't use gcry_free() here */
- return rc;
-}
-
-
-
-static int
-do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
-{
- PACKET *pkt;
- int rc;
- RESTBL *rentry;
- KBNODE root = NULL;
- IOBUF a;
- datum key, content;
-
- if( !(rentry=check_pos(kbpos)) )
- return GPGERR_GENERAL;
-
- key.dptr = kbpos->keybuf;
- key.dsize = 21;
- content = gdbm_fetch( rentry->dbf, key );
- if( !content.dptr ) {
- log_error("gdbm_fetch failed: %s\n", gdbm_strerror(gdbm_errno) );
- return GPGERR_INV_KEYRING;
- }
- if( content.dsize < 2 ) {
- log_error("gdbm_fetch did not return enough data\n" );
- free( content.dptr ); /* can't use gcry_free() here */
- return GPGERR_INV_KEYRING;
- }
- if( *content.dptr != 1 ) {
- log_error("gdbm_fetch returned unexpected type %d\n",
- *(byte*)content.dptr );
- free( content.dptr ); /* can't use gcry_free() here */
- return GPGERR_INV_KEYRING;
- }
-
- a = iobuf_temp_with_content( content.dptr+1, content.dsize-1 );
- free( content.dptr ); /* can't use gcry_free() here */
-
- pkt = gcry_xmalloc( sizeof *pkt );
- init_packet(pkt);
- kbpos->count=0;
- while( (rc=parse_packet(a, pkt)) != -1 ) {
- if( rc ) { /* ignore errors */
- if( rc != GPGERR_UNKNOWN_PACKET ) {
- log_error("read_keyblock: read error: %s\n", gpg_errstr(rc) );
- rc = GPGERR_INV_KEYRING;
- break;
- }
- kbpos->count++;
- free_packet( pkt );
- init_packet( pkt );
- continue;
- }
- /* make a linked list of all packets */
- kbpos->count++;
- if( !root )
- root = new_kbnode( pkt );
- else
- add_kbnode( root, new_kbnode( pkt ) );
- pkt = gcry_xmalloc( sizeof *pkt );
- init_packet(pkt);
- }
- if( rc == -1 && root )
- rc = 0;
- if( rc )
- release_kbnode( root );
- else
- *ret_root = root;
- free_packet( pkt );
- gcry_free( pkt );
- iobuf_close(a);
- return rc;
-}
-
-
-/****************
- * Enum over keyblok data
- */
-static int
-do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root )
-{
- RESTBL *rentry;
- datum key, helpkey;
-
- if( !(rentry=check_pos(kbpos)) )
- return GPGERR_GENERAL;
-
- if( !kbpos->offset ) {
- kbpos->offset = 1;
- key = gdbm_firstkey( rentry->dbf );
- }
- else {
- helpkey.dptr = kbpos->keybuf;
- helpkey.dsize= 21;
- key = gdbm_nextkey( rentry->dbf, helpkey );
- }
- while( key.dptr && (!key.dsize || *key.dptr != 1) ) {
- helpkey = key;
- key = gdbm_nextkey( rentry->dbf, helpkey );
- free( helpkey.dptr ); /* free and not gcry_free() ! */
- }
- if( !key.dptr )
- return -1; /* eof */
-
- if( key.dsize < 21 ) {
- free( key.dptr ); /* free and not gcry_free() ! */
- log_error("do_gdm_enum: key is too short\n" );
- return GPGERR_INV_KEYRING;
- }
- memcpy( kbpos->keybuf, key.dptr, 21 );
- free( key.dptr ); /* free and not gcry_free() ! */
- return do_gdbm_read( kbpos, ret_root );
-}
-#endif /*HAVE_LIBGDBM*/
diff --git a/g10/skclist.c b/g10/skclist.c
index dceba71f8..bc325cd58 100644
--- a/g10/skclist.c
+++ b/g10/skclist.c
@@ -60,7 +60,7 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
sk = gcry_xcalloc( 1, sizeof *sk );
sk->req_usage = use;
- if( (rc = get_seckey_byname( sk, NULL, unlock )) ) {
+ if( (rc = get_seckey_byname( NULL, sk, NULL, unlock, NULL )) ) {
free_secret_key( sk ); sk = NULL;
log_error("no default secret key: %s\n", gpg_errstr(rc) );
}
@@ -93,7 +93,7 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
sk = gcry_xcalloc( 1, sizeof *sk );
sk->req_usage = use;
- if( (rc = get_seckey_byname( sk, locusr->d, unlock )) ) {
+ if( (rc = get_seckey_byname( NULL, sk, locusr->d, unlock, NULL))) {
free_secret_key( sk ); sk = NULL;
log_error(_("skipped `%s': %s\n"), locusr->d, gpg_errstr(rc) );
}