summaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>1998-07-21 14:53:38 +0200
committerWerner Koch <wk@gnupg.org>1998-07-21 14:53:38 +0200
commit1a80de41a5f5e753c427872f8ab6ee5a844ea761 (patch)
tree8d5312c6f56c54dc6092556b8569b16b22e4d8fe /g10
parentsync (diff)
downloadgnupg2-1a80de41a5f5e753c427872f8ab6ee5a844ea761.tar.xz
gnupg2-1a80de41a5f5e753c427872f8ab6ee5a844ea761.zip
changed trustdb design
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog16
-rw-r--r--g10/Makefile.am10
-rw-r--r--g10/OPTIONS8
-rw-r--r--g10/g10.c77
-rw-r--r--g10/getkey.c14
-rw-r--r--g10/import.c11
-rw-r--r--g10/keydb.h5
-rw-r--r--g10/keygen.c4
-rw-r--r--g10/keyid.c37
-rw-r--r--g10/pkclist.c2
-rw-r--r--g10/tdbio.c92
-rw-r--r--g10/tdbio.h30
-rw-r--r--g10/trustdb.c899
-rw-r--r--g10/trustdb.h3
14 files changed, 760 insertions, 448 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index f6f935a57..badb5cd32 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,19 @@
+Tue Jul 21 14:37:09 1998 Werner Koch (wk@(none))
+
+ * import.c (import_one): Now creates a trustdb record.
+
+ * g10.c (main): New command --check-trustdb
+
+Mon Jul 20 11:15:07 1998 Werner Koch (wk@(none))
+
+ * genkey.c (generate_keypair): Default key is now DSA with
+ encryption only ElGamal subkey.
+
+Thu Jul 16 10:58:33 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * keyid.c (keyid_from_fingerprint): New.
+ * getkey.c (get_pubkey_byfprint): New.
+
Tue Jul 14 18:09:51 1998 Werner Koch (wk@isil.d.shuttle.de)
* keyid.c (fingerprint_from_pk): Add argument and changed all callers.
diff --git a/g10/Makefile.am b/g10/Makefile.am
index be695d895..e97fb8cf4 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -6,7 +6,7 @@ OMIT_DEPENDENCIES = zlib.h zconf.h
LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@
needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
-noinst_PROGRAMS = gpgd
+#noinst_PROGRAMS = gpgd
bin_PROGRAMS = gpg gpgm
common_source = \
@@ -67,10 +67,10 @@ gpg_SOURCES = g10.c \
gpgm_SOURCES = dearmor.c \
$(common_source)
-gpgd_SOURCES = gpgd.c \
- ks-proto.h \
- ks-proto.c \
- $(common_source)
+#gpgd_SOURCES = gpgd.c \
+# ks-proto.h \
+# ks-proto.c \
+# $(common_source)
LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@
diff --git a/g10/OPTIONS b/g10/OPTIONS
index 8e9cf8a6c..aa8b46d6e 100644
--- a/g10/OPTIONS
+++ b/g10/OPTIONS
@@ -36,6 +36,14 @@ list-secret-keys
export-secret-keys
# export secret keys (which may be usefuil in some cases)
+check-trustdb
+
+
+
+
+
+
+
#-----------------------------------------------
#--- options
#-----------------------------------------------
diff --git a/g10/g10.c b/g10/g10.c
index 308b58227..dbd277d63 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -52,43 +52,44 @@ static ARGPARSE_OPTS opts[] = {
{ 300, NULL, 0, N_("@Commands:\n ") },
#ifdef IS_G10
- { 's', "sign", 0, N_("|[file]|make a signature")},
- { 539, "clearsign", 0, N_("|[file]|make a clear text signature") },
- { 'b', "detach-sign", 0, N_("make a detached signature")},
- { 'e', "encrypt", 0, N_("encrypt data")},
- { 'c', "symmetric", 0, N_("encryption only with symmetric cipher")},
- { 507, "store", 0, N_("store only")},
- { 'd', "decrypt", 0, N_("decrypt data (default)")},
- { 550, "verify" , 0, N_("verify a signature")},
+ { 's', "sign", 256, N_("|[file]|make a signature")},
+ { 539, "clearsign", 256, N_("|[file]|make a clear text signature") },
+ { 'b', "detach-sign", 256, N_("make a detached signature")},
+ { 'e', "encrypt", 256, N_("encrypt data")},
+ { 'c', "symmetric", 256, N_("encryption only with symmetric cipher")},
+ { 507, "store", 256, N_("store only")},
+ { 'd', "decrypt", 256, N_("decrypt data (default)")},
+ { 550, "verify" , 256, N_("verify a signature")},
#endif
- { 551, "list-keys", 0, N_("list keys")},
- { 552, "list-sigs", 0, N_("list keys and signatures")},
- { 508, "check-sigs",0, N_("check key signatures")},
- { 515, "fingerprint", 0, N_("list keys and fingerprints")},
- { 558, "list-secret-keys", 0, N_("list secret keys")},
+ { 551, "list-keys", 256, N_("list keys")},
+ { 552, "list-sigs", 256, N_("list keys and signatures")},
+ { 508, "check-sigs",256, N_("check key signatures")},
+ { 515, "fingerprint", 256, N_("list keys and fingerprints")},
+ { 558, "list-secret-keys", 256, N_("list secret keys")},
#ifdef IS_G10
- { 503, "gen-key", 0, N_("generate a new key pair")},
- { 554, "add-key", 0, N_("add a subkey to a key pair")},
- { 506, "sign-key" ,0, N_("make a signature on a key in the keyring")},
- { 505, "delete-key",0, N_("remove key from the public keyring")},
- { 524, "edit-key" ,0, N_("edit a key signature")},
- { 525, "change-passphrase", 0, N_("change the passphrase of your secret keyring")},
- { 542, "gen-revoke",0, N_("generate a revocation certificate")},
+ { 503, "gen-key", 256, N_("generate a new key pair")},
+ { 554, "add-key", 256, N_("add a subkey to a key pair")},
+ { 506, "sign-key" ,256, N_("make a signature on a key in the keyring")},
+ { 505, "delete-key",256, N_("remove key from the public keyring")},
+ { 524, "edit-key" ,256, N_("edit a key signature")},
+ { 525, "change-passphrase", 256, N_("change the passphrase of your secret keyring")},
+ { 542, "gen-revoke",256, N_("generate a revocation certificate")},
#endif
- { 537, "export" , 0, N_("export keys") },
- { 563, "export-secret-keys" , 0, "@" },
+ { 537, "export" , 256, N_("export keys") },
+ { 563, "export-secret-keys" , 256, "@" },
{ 565, "do-not-export-rsa", 0, "@" },
- { 530, "import", 0 , N_("import/merge keys")},
- { 521, "list-packets",0,N_("list only the sequence of packets")},
+ { 530, "import", 256 , N_("import/merge keys")},
+ { 521, "list-packets",256,N_("list only the sequence of packets")},
#ifdef IS_G10MAINT
- { 564, "list-ownertrust", 0, "list the ownertrust values"},
- { 546, "dearmor", 0, N_("De-Armor a file or stdin") },
- { 547, "enarmor", 0, N_("En-Armor a file or stdin") },
- { 555, "print-md" , 0, N_("|algo [files]|print message digests")},
- { 516, "print-mds" , 0, N_("print all message digests")},
+ { 564, "list-ownertrust", 256, N_("list the ownertrust values")},
+ { 567, "check-trustdb",0 , N_("|[NAMES]|check the trust database")},
+ { 546, "dearmor", 256, N_("De-Armor a file or stdin") },
+ { 547, "enarmor", 256, N_("En-Armor a file or stdin") },
+ { 555, "print-md" , 256, N_("|algo [files]|print message digests")},
+ { 516, "print-mds" , 256, N_("print all message digests")},
#ifdef MAINTAINER_OPTIONS
- { 513, "gen-prime" , 0, "@" },
- { 548, "gen-random" , 0, "@" },
+ { 513, "gen-prime" , 256, "@" },
+ { 548, "gen-random" , 256, "@" },
#endif
#endif
@@ -143,6 +144,7 @@ static ARGPARSE_OPTS opts[] = {
#ifdef IS_G10MAINT
{ 514, "test" , 0, "@" },
{ 564, "list-ownertrust",0 , "@"},
+ { 567, "check-trustdb",0 , "@"},
{ 531, "list-trustdb",0 , "@"},
{ 533, "list-trust-path",0, "@"},
#endif
@@ -182,7 +184,7 @@ enum cmd_values { aNull = 0,
aListSigs, aKeyadd, aListSecretKeys,
aExport, aExportSecret,
aCheckKeys, aGenRevoke, aPrimegen, aPrintMD, aPrintMDs,
- aListTrustDB, aListTrustPath, aListOwnerTrust,
+ aCheckTrustDB, aListTrustDB, aListTrustPath, aListOwnerTrust,
aDeArmor, aEnArmor, aGenRandom,
aTest };
@@ -195,7 +197,6 @@ static void set_cmd( enum cmd_values *ret_cmd,
#ifdef IS_G10MAINT
static void print_hex( byte *p, size_t n );
static void print_mds( const char *fname, int algo );
-static void do_test(int);
#endif
const char *
@@ -541,6 +542,7 @@ main( int argc, char **argv )
#endif
case 516: set_cmd( &cmd, aPrintMDs); break;
case 531: set_cmd( &cmd, aListTrustDB); break;
+ case 567: set_cmd( &cmd, aCheckTrustDB); break;
case 533: set_cmd( &cmd, aListTrustPath); break;
case 540: break; /* dummy */
case 546: set_cmd( &cmd, aDeArmor); break;
@@ -1032,6 +1034,15 @@ main( int argc, char **argv )
}
break;
+ case aCheckTrustDB:
+ if( !argc )
+ check_trustdb(NULL);
+ else {
+ for( ; argc; argc--, argv++ )
+ check_trustdb( *argv );
+ }
+ break;
+
case aListTrustPath:
if( argc != 2 )
wrong_args("--list-trust-path [-- -]<maxdepth> <username>");
diff --git a/g10/getkey.c b/g10/getkey.c
index b73a00616..912c91906 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -464,6 +464,20 @@ get_pubkey_byname( PKT_public_key *pk, const char *name )
}
+/****************
+ * Search for a key with the given fingerprint.
+ */
+int
+get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint, size_t fprint_len)
+{
+ int rc;
+
+ if( fprint_len == 20 || fprint_len == 16 )
+ rc = lookup( pk, fprint_len, NULL, fprint, NULL );
+ else
+ rc = G10ERR_GENERAL; /* Oops */
+ return rc;
+}
/****************
* Search for a key with the given fingerprint and return the
diff --git a/g10/import.c b/g10/import.c
index d32852cf0..ec143dce2 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -381,6 +381,17 @@ import_one( const char *fname, KBNODE keyblock )
else
log_info_f(fname, _("key %08lX: not changed\n"), (ulong)keyid[1] );
}
+ if( !rc ) {
+ rc = query_trust_record( pk_orig );
+ if( rc && rc != -1 )
+ log_error("trustdb error: %s\n", g10_errstr(rc) );
+ else if( rc == -1 ) {
+ rc = insert_trust_record( pk_orig );
+ if( rc )
+ log_error("key %08lX: trustdb insert failed: %s\n",
+ (ulong)keyid[1], g10_errstr(rc) );
+ }
+ }
leave:
release_kbnode( keyblock_orig );
diff --git a/g10/keydb.h b/g10/keydb.h
index 51da9a628..bbd803fbe 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -112,6 +112,8 @@ void add_secret_keyring( const char *name );
int get_pubkey( PKT_public_key *pk, u32 *keyid );
int get_pubkey_byname( PKT_public_key *pk, const char *name );
int get_seckey( PKT_secret_key *sk, u32 *keyid );
+int get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint,
+ size_t fprint_len );
int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
size_t fprint_len );
int seckey_available( u32 *keyid );
@@ -125,12 +127,13 @@ int pubkey_letter( int algo );
u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid );
u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid );
u32 keyid_from_sig( PKT_signature *sig, u32 *keyid );
+u32 keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid );
unsigned nbits_from_pk( PKT_public_key *pk );
unsigned nbits_from_sk( PKT_secret_key *sk );
const char *datestr_from_pk( PKT_public_key *pk );
const char *datestr_from_sk( PKT_secret_key *sk );
const char *datestr_from_sig( PKT_signature *sig );
-byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf; size_t *ret_len );
+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 );
/*-- kbnode.c --*/
diff --git a/g10/keygen.c b/g10/keygen.c
index b114b8444..0eaeafeae 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -371,7 +371,7 @@ check_valid_days( const char *s )
/****************
- * Returns o to create both a DSA and a ElGamal key.
+ * Returns: 0 to create both a DSA and a ElGamal key.
*/
static int
ask_algo( int *ret_v4, int addmode )
@@ -756,7 +756,7 @@ generate_keypair()
algo = ask_algo( &v4, 0 );
if( !algo ) {
- algo = PUBKEY_ALGO_ELGAMAL;
+ algo = PUBKEY_ALGO_ELGAMAL_E;
both = 1;
tty_printf(_("DSA keypair will have 1024 bits.\n"));
}
diff --git a/g10/keyid.c b/g10/keyid.c
index 2e5c6aad6..de0319fe3 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -189,6 +189,43 @@ keyid_from_pk( PKT_public_key *pk, u32 *keyid )
}
+/****************
+ * Get the keyid from the fingerprint. This function is simple for most
+ * keys, but has to do a keylookup for old stayle keys.
+ */
+u32
+keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
+{
+ u32 dummy_keyid[2];
+
+ if( !keyid )
+ keyid = dummy_keyid;
+
+ if( fprint_len != 20 ) {
+ /* This is special as we have to lookup the key first */
+ PKT_public_key pk;
+ int rc;
+
+ memset( &pk, 0, sizeof pk );
+ rc = get_pubkey_byfprint( &pk, fprint, fprint_len );
+ if( rc ) {
+ log_error("Oops: keyid_from_fingerprint: no pubkey\n");
+ keyid[0] = 0;
+ keyid[1] = 0;
+ }
+ else
+ keyid_from_pk( &pk, keyid );
+ }
+ else {
+ const byte *dp = fprint;
+ keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
+ keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
+ }
+
+ return keyid[1];
+}
+
+
u32
keyid_from_sig( PKT_signature *sig, u32 *keyid )
{
diff --git a/g10/pkclist.c b/g10/pkclist.c
index e509f0064..7fbe065b6 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -49,7 +49,7 @@ query_ownertrust( ulong lid )
PKT_public_key *pk ;
int changed=0;
- rc = keyid_from_trustdb( lid, keyid );
+ rc = keyid_from_lid( lid, keyid );
if( rc ) {
log_error("ooops: can't get keyid for lid %lu\n", lid);
return 0;
diff --git a/g10/tdbio.c b/g10/tdbio.c
index 9355f4c6e..ac1266147 100644
--- a/g10/tdbio.c
+++ b/g10/tdbio.c
@@ -147,11 +147,11 @@ create_db( const char *fname )
fp =fopen( fname, "w" );
if( !fp )
log_fatal_f( fname, _("can't create %s: %s\n"), strerror(errno) );
- fwrite_8( fp, 2 );
+ fwrite_8( fp, 1 ); /* record type */
fwrite_8( fp, 'g' );
fwrite_8( fp, 'p' );
fwrite_8( fp, 'g' );
- fwrite_8( fp, 1 ); /* version */
+ fwrite_8( fp, 2 ); /* version */
fwrite_zeros( fp, 3 ); /* reserved */
fwrite_32( fp, 0 ); /* not locked */
fwrite_32( fp, make_timestamp() ); /* created */
@@ -183,11 +183,12 @@ open_db()
void
-tdbio_dump_record( ulong rnum, TRUSTREC *rec, FILE *fp )
+tdbio_dump_record( TRUSTREC *rec, FILE *fp )
{
int i, any;
+ ulong rnum = rec->recnum;
- fprintf(fp, "rec %5lu, type=", rnum );
+ fprintf(fp, "rec %5lu, ", rnum );
switch( rec->rectype ) {
case 0: fprintf(fp, "free\n");
@@ -201,30 +202,36 @@ tdbio_dump_record( ulong rnum, TRUSTREC *rec, FILE *fp )
rec->r.dir.uidlist,
rec->r.dir.cacherec,
rec->r.dir.ownertrust );
- if( rec->r.dir.sigflag == 1 )
- fputs(", (none)", fp );
- else if( rec->r.dir.sigflag == 2 )
- fputs(", (invalid)", fp );
- else if( rec->r.dir.sigflag == 3 )
- fputs(", (revoked)", fp );
- else if( rec->r.dir.sigflag )
- fputs(", (??)", fp );
+ if( rec->r.dir.dirflags & DIRF_ERROR )
+ fputs(", error", fp );
+ if( rec->r.dir.dirflags & DIRF_CHECKED )
+ fputs(", checked", fp );
+ if( rec->r.dir.dirflags & DIRF_REVOKED )
+ fputs(", revoked", fp );
+ if( rec->r.dir.dirflags & DIRF_MISKEY )
+ fputs(", miskey", fp );
putc('\n', fp);
break;
case RECTYPE_KEY:
- fprintf(fp, "key %lu, next=%lu, algo=%d, flen=%d\n",
+ fprintf(fp, "key %lu, next=%lu, algo=%d, flen=%d",
rec->r.key.lid,
rec->r.key.next,
rec->r.key.pubkey_algo,
rec->r.key.fingerprint_len );
+ if( rec->r.key.keyflags & KEYF_REVOKED )
+ fputs(", revoked", fp );
+ putc('\n', fp);
break;
case RECTYPE_UID:
- fprintf(fp, "uid %lu, next=%lu, pref=%lu, sig=%lu, hash=%02X%02X\n",
+ fprintf(fp, "uid %lu, next=%lu, pref=%lu, sig=%lu, hash=%02X%02X",
rec->r.uid.lid,
rec->r.uid.next,
rec->r.uid.prefrec,
rec->r.uid.siglist,
rec->r.uid.namehash[18], rec->r.uid.namehash[19]);
+ if( rec->r.uid.uidflags & UIDF_REVOKED )
+ fputs(", revoked", fp );
+ putc('\n', fp);
break;
case RECTYPE_PREF:
fprintf(fp, "pref %lu, next=%lu\n",
@@ -253,11 +260,11 @@ tdbio_dump_record( ulong rnum, TRUSTREC *rec, FILE *fp )
case RECTYPE_HTBL:
fprintf(fp, "htbl\n");
break;
- case RECTYPE_HTBL:
+ case RECTYPE_HLST:
fprintf(fp, "hlst\n");
break;
default:
- fprintf(fp, "%d (unknown)\n", rec->rectype );
+ fprintf(fp, "unknown type %d\n", rec->rectype );
break;
}
}
@@ -330,7 +337,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
rec->r.dir.uidlist = buftoulong(p); p += 4;
rec->r.dir.cacherec = buftoulong(p); p += 4;
rec->r.dir.ownertrust = *p++;
- rec->r.dir.sigflag = *p++;
+ rec->r.dir.dirflags = *p++;
if( rec->r.dir.lid != recnum ) {
log_error_f( db_name, "dir LID != recnum (%lu,%lu)\n",
rec->r.dir.lid, (ulong)recnum );
@@ -340,7 +347,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
case RECTYPE_KEY: /* public key record */
rec->r.key.lid = buftoulong(p); p += 4;
rec->r.key.next = buftoulong(p); p += 4;
- p += 8;
+ p += 7;
+ rec->r.key.keyflags = *p++;
rec->r.key.pubkey_algo = *p++;
rec->r.key.fingerprint_len = *p++;
if( rec->r.key.fingerprint_len < 1 || rec->r.key.fingerprint_len > 20 )
@@ -352,7 +360,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
rec->r.uid.next = buftoulong(p); p += 4;
rec->r.uid.prefrec = buftoulong(p); p += 4;
rec->r.uid.siglist = buftoulong(p); p += 4;
- p += 2;
+ rec->r.uid.uidflags = *p++;
+ p ++;
memcpy( rec->r.uid.namehash, p, 20);
break;
case RECTYPE_PREF: /* preference record */
@@ -413,14 +422,15 @@ tdbio_write_record( TRUSTREC *rec )
ulongtobuf(p, rec->r.dir.uidlist); p += 4;
ulongtobuf(p, rec->r.dir.cacherec); p += 4;
*p++ = rec->r.dir.ownertrust;
- *p++ = rec->r.dir.sigflag;
+ *p++ = rec->r.dir.dirflags;
assert( rec->r.dir.lid == recnum );
break;
case RECTYPE_KEY:
ulongtobuf(p, rec->r.key.lid); p += 4;
ulongtobuf(p, rec->r.key.next); p += 4;
- p += 8;
+ p += 7;
+ *p++ = rec->r.key.keyflags;
*p++ = rec->r.key.pubkey_algo;
*p++ = rec->r.key.fingerprint_len;
memcpy( p, rec->r.key.fingerprint, 20); p += 20;
@@ -431,7 +441,8 @@ tdbio_write_record( TRUSTREC *rec )
ulongtobuf(p, rec->r.uid.next); p += 4;
ulongtobuf(p, rec->r.uid.prefrec); p += 4;
ulongtobuf(p, rec->r.uid.siglist); p += 4;
- p += 2;
+ *p++ = rec->r.uid.uidflags;
+ p++;
memcpy( p, rec->r.uid.namehash, 20 ); p += 20;
break;
@@ -472,6 +483,15 @@ tdbio_write_record( TRUSTREC *rec )
return rc;
}
+int
+tdbio_delete_record( ulong recnum )
+{
+ TRUSTREC rec;
+
+ rec.recnum = recnum;
+ rec.rectype = 0;
+ return tdbio_write_record( &rec );
+}
/****************
* create a new record and return its record number
@@ -495,7 +515,8 @@ tdbio_new_recnum()
* returns another recnum */
memset( &rec, 0, sizeof rec );
rec.rectype = 0; /* free record */
- rc = tdbio_write_record(recnum, &rec );
+ rec.recnum = recnum;
+ rc = tdbio_write_record( &rec );
if( rc )
log_fatal_f(db_name,_("failed to append a record: %s\n"),
g10_errstr(rc));
@@ -530,10 +551,10 @@ tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec )
if( rec->r.key.pubkey_algo == pk->pubkey_algo
&& !memcmp(rec->r.key.fingerprint, fingerprint, fingerlen) ) {
/* found: read the dir record for this key */
- rc = tdbio_read_record( rec->r.key.lid, rec, RECTYPE_DIR);
+ recnum = rec->r.key.lid;
+ rc = tdbio_read_record( recnum, rec, RECTYPE_DIR);
if( rc )
break;
-
if( pk->local_id && pk->local_id != recnum )
log_error_f(db_name,
"found record, but LID from memory does "
@@ -549,22 +570,13 @@ tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec )
}
+/****************
+ * Delete the Userid UIDLID from DIRLID
+ */
int
-tdbio_update_sigflag( ulong lid, int sigflag )
+tdbio_delete_uidrec( ulong dirlid, ulong uidlid )
{
- TRUSTREC rec;
-
- if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
- log_error("update_sigflag: read failed\n");
- return G10ERR_TRUSTDB;
- }
-
- rec.r.dir.sigflag = sigflag;
- if( tdbio_write_record( lid, &rec ) ) {
- log_error("update_sigflag: write failed\n");
- return G10ERR_TRUSTDB;
- }
-
- return 0;
+ return G10ERR_GENERAL; /* not implemented */
}
+
diff --git a/g10/tdbio.h b/g10/tdbio.h
index 2d28131cd..8eec40e4a 100644
--- a/g10/tdbio.h
+++ b/g10/tdbio.h
@@ -40,11 +40,23 @@
#define RECTYPE_HLST 11
+
+#define DIRF_CHECKED 1 /* everything has been checked, the other bits are
+ valid */
+#define DIRF_MISKEY 2 /* some keys are missing, so they could not be checked*/
+#define DIRF_ERROR 4 /* severe errors: the key is not valid for some reasons
+ but we mark it to avoid duplicate checks */
+#define DIRF_REVOKED 8 /* the complete key has been revoked */
+
+#define KEYF_REVOKED DIRF_REVOKED /* this key has been revoked
+ (only useful on subkeys)*/
+#define UIDF_REVOKED DIRF_REVOKED /* this user id has been revoked */
+
+
struct trust_record {
int rectype;
struct trust_record *next; /* help pointer to build lists in memory */
struct trust_record *help_pref;
- struct trust_record *help_sig;
int mark;
ulong recnum;
union {
@@ -64,11 +76,12 @@ struct trust_record {
ulong uidlist; /* list of uid records */
ulong cacherec; /* the cache record */
byte ownertrust;
- byte sigflag;
+ byte dirflags;
} dir;
struct { /* primary public key record */
ulong lid;
ulong next; /* next key */
+ byte keyflags;
byte pubkey_algo;
byte fingerprint_len;
byte fingerprint[20];
@@ -78,6 +91,7 @@ struct trust_record {
ulong next; /* points to next user id record */
ulong prefrec; /* recno of preference record */
ulong siglist; /* list of valid signatures (w/o self-sig)*/
+ byte uidflags;
byte namehash[20]; /* ripemd hash of the username */
} uid;
struct { /* preference reord */
@@ -90,7 +104,7 @@ struct trust_record {
ulong next; /* recnno of next record or NULL for last one */
struct {
ulong lid; /* of pubkey record of signator (0=unused) */
- byte flag; /* reserved */
+ byte flag; /* SIGRF_xxxxx */
} sig[SIGS_PER_RECORD];
} sig;
struct { /* cache record */
@@ -113,14 +127,15 @@ struct trust_record {
typedef struct trust_record TRUSTREC;
typedef struct {
- ulong local_id; /* localid of the pubkey */
+ ulong lid; /* localid */
ulong sigrec;
- ulong sig_id; /* returned signature id */
+ ulong sig_lid; /* returned signatures LID */
unsigned sig_flag; /* returned signature record flag */
struct { /* internal data */
int init_done;
int eof;
TRUSTREC rec;
+ ulong nextuid;
int index;
} ctl;
} SIGREC_CONTEXT;
@@ -129,12 +144,13 @@ typedef struct {
/*-- tdbio.c --*/
int tdbio_set_dbname( const char *new_dbname, int create );
const char *tdbio_get_dbname(void);
-void tdbio_dump_record( ulong rnum, TRUSTREC *rec, FILE *fp );
+void tdbio_dump_record( TRUSTREC *rec, FILE *fp );
int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected );
int tdbio_write_record( TRUSTREC *rec );
+int tdbio_delete_record( ulong recnum );
ulong tdbio_new_recnum(void);
int tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec );
-int tdbio_update_sigflag( ulong lid, int sigflag );
+int tdbio_delete_uidrec( ulong dirlid, ulong uidlid );
#define buftoulong( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
diff --git a/g10/trustdb.c b/g10/trustdb.c
index b2e478ceb..b82d26a1e 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -87,9 +87,9 @@ static void upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
static void print_user_id( const char *text, u32 *keyid );
static int do_list_path( TRUST_INFO *stack, int depth, int max_depth,
LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist );
+static int update_sigs_by_lid( ulong lid );
static int list_sigs( ulong pubkey_id );
-static int build_sigrecs( ulong local_id );
static int propagate_trust( TRUST_SEG_LIST tslist );
static int do_check( TRUSTREC *drec, unsigned *trustlevel );
@@ -179,7 +179,7 @@ upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag )
* the signature packet in our trustdb or insert them into the trustdb
*/
static int
-set_signature_packets_local_id( PKT_signature *sig )
+set_signature_packets_lid( PKT_signature *sig )
{
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
TRUSTREC rec;
@@ -204,24 +204,34 @@ set_signature_packets_local_id( PKT_signature *sig )
-static int
-keyid_from_local_id( ulong lid, u32 *keyid )
+/****************
+ * Return the keyid from the primary key identified by LID.
+ */
+int
+keyid_from_lid( ulong lid, u32 *keyid )
{
TRUSTREC rec;
int rc;
rc = tdbio_read_record( lid, &rec, RECTYPE_DIR );
if( rc ) {
- log_error(_("error reading record with local_id %lu: %s\n"),
+ log_error("error reading dir record for LID %lu: %s\n",
lid, g10_errstr(rc));
return G10ERR_TRUSTDB;
}
- if( rec.rectype != RECTYPE_DIR ) {
- log_error(_("record with local_id %lu is not a dir record\n"), lid);
+ if( !rec.r.dir.keylist ) {
+ log_error("no primary key for LID %lu\n", lid );
return G10ERR_TRUSTDB;
}
- keyid[0] = rec.r.dir.keyid[0];
- keyid[1] = rec.r.dir.keyid[1];
+ rc = tdbio_read_record( rec.r.dir.keylist, &rec, RECTYPE_KEY );
+ if( rc ) {
+ log_error("error reading primary key for LID %lu: %s\n",
+ lid, g10_errstr(rc));
+ return G10ERR_TRUSTDB;
+ }
+ keyid_from_fingerprint( rec.r.key.fingerprint, rec.r.key.fingerprint_len,
+ keyid );
+
return 0;
}
@@ -247,48 +257,52 @@ walk_sigrecs( SIGREC_CONTEXT *c, int create )
r = &c->ctl.rec;
if( !c->ctl.init_done ) {
c->ctl.init_done = 1;
- if( !c->sigrec ) {
- rc = tdbio_read_record( c->local_id, r, RECTYPE_DIR );
- if( rc ) {
- log_error(_("%lu: error reading dir record: %s\n"),
- c->local_id, g10_errstr(rc));
- return rc;
- }
- c->sigrec = r->r.dir.sigrec;
- if( !c->sigrec && create && !r->r.dir.no_sigs ) {
- rc = build_sigrecs( c->local_id );
+ rc = tdbio_read_record( c->lid, r, RECTYPE_DIR );
+ if( rc ) {
+ log_error("LID %lu: error reading dir record: %s\n",
+ c->lid, g10_errstr(rc));
+ return rc;
+ }
+ c->ctl.nextuid = r->r.dir.uidlist;
+ /* force a read (what a bad bad hack) */
+ c->ctl.index = SIGS_PER_RECORD;
+ r->r.sig.next = 0;
+ }
+
+ /* need a loop to skip over deleted sigs */
+ do {
+ if( c->ctl.index >= SIGS_PER_RECORD ) { /* read the record */
+ rnum = r->r.sig.next;
+ if( !rnum && c->ctl.nextuid ) { /* read next uid record */
+ rc = tdbio_read_record( c->ctl.nextuid, r, RECTYPE_UID );
if( rc ) {
- if( rc == G10ERR_BAD_CERT )
- rc = -1; /* maybe no selfsignature */
- if( rc != -1 )
- log_info(_("%lu: error building sigs on the fly: %s\n"),
- c->local_id, g10_errstr(rc) );
+ log_error("error reading next uidrec: %s\n",
+ g10_errstr(rc));
c->ctl.eof = 1;
return rc;
}
- rc = tdbio_read_record( c->local_id, r, RECTYPE_DIR );
- if( rc ) {
- log_error(_("%lu: error re-reading dir record: %s\n"),
- c->local_id, g10_errstr(rc));
- return rc;
+ if( !r->r.uid.siglist && create ) {
+ rc = update_sigs_by_lid( c->lid );
+ if( rc ) {
+ if( rc == G10ERR_BAD_CERT )
+ rc = -1; /* maybe no selfsignature */
+ if( rc != -1 )
+ log_info("LID %lu: "
+ "error building sigs on the fly: %s\n",
+ c->lid, g10_errstr(rc) );
+ c->ctl.eof = 1;
+ return rc;
+ }
+ rc = tdbio_read_record( c->ctl.nextuid, r, RECTYPE_UID );
+ if( rc ) {
+ log_error("LID %lu: error re-reading uid record: %s\n",
+ c->lid, g10_errstr(rc));
+ return rc;
+ }
}
- c->sigrec = r->r.dir.sigrec;
- }
- if( !c->sigrec ) {
- c->ctl.eof = 1;
- return -1;
+ c->ctl.nextuid = r->r.uid.next;
+ rnum = r->r.uid.siglist;
}
- }
- /* force a read */
- c->ctl.index = SIGS_PER_RECORD;
- r->r.sig.chain = c->sigrec;
- }
-
- /* enter loop to skip deleted sigs */
- do {
- if( c->ctl.index >= SIGS_PER_RECORD ) {
- /* read the record */
- rnum = r->r.sig.chain;
if( !rnum ) {
c->ctl.eof = 1;
return -1; /* return eof */
@@ -299,15 +313,16 @@ walk_sigrecs( SIGREC_CONTEXT *c, int create )
c->ctl.eof = 1;
return rc;
}
- if( r->r.sig.owner != c->local_id ) {
+ if( r->r.sig.lid != c->lid ) {
log_error(_("chained sigrec %lu has a wrong owner\n"), rnum );
c->ctl.eof = 1;
return G10ERR_TRUSTDB;
}
c->ctl.index = 0;
}
- } while( !r->r.sig.sig[c->ctl.index++].local_id );
- c->sig_id = r->r.sig.sig[c->ctl.index-1].local_id;
+ } while( !r->r.sig.sig[c->ctl.index++].lid );
+
+ c->sig_lid = r->r.sig.sig[c->ctl.index-1].lid;
c->sig_flag = r->r.sig.sig[c->ctl.index-1].flag;
return 0;
}
@@ -333,13 +348,6 @@ verify_own_keys()
u32 keyid[2];
while( !(rc=enum_secret_keys( &enum_context, sk) ) ) {
- /* To be sure that it is a secret key of our own,
- * we should check it, but this needs a passphrase
- * for every key and this is boring for the user.
- * Anyway, access to the seret keyring should be
- * granted to the user only as it is poosible to
- * crack it with dictionary attacks.
- */
keyid_from_sk( sk, keyid );
if( DBG_TRUST )
@@ -383,7 +391,6 @@ verify_own_keys()
log_error(_("key %08lX: already in ultikey_table\n"),
(ulong)keyid[1]);
-
release_secret_key_parts( sk );
release_public_key_parts( pk );
}
@@ -421,7 +428,7 @@ static void
print_keyid( FILE *fp, ulong lid )
{
u32 ki[2];
- if( keyid_from_trustdb( lid, ki ) )
+ if( keyid_from_lid( lid, ki ) )
fprintf(fp, "????????.%lu", lid );
else
fprintf(fp, "%08lX.%lu", (ulong)ki[1], lid );
@@ -454,36 +461,36 @@ do_list_sigs( ulong root, ulong pubkey, int depth,
u32 keyid[2];
memset( &sx, 0, sizeof sx );
- sx.local_id = pubkey;
+ sx.lid = pubkey;
for(;;) {
rc = walk_sigrecs( &sx, 0 );
if( rc )
break;
- rc = keyid_from_local_id( sx.sig_id, keyid );
+ rc = keyid_from_lid( sx.sig_lid, keyid );
if( rc ) {
printf("%6u: %*s????????.%lu:%02x\n", *lineno, depth*4, "",
- sx.sig_id, sx.sig_flag );
+ sx.sig_lid, sx.sig_flag );
++*lineno;
}
else {
printf("%6u: %*s%08lX.%lu:%02x ", *lineno, depth*4, "",
- (ulong)keyid[1], sx.sig_id, sx.sig_flag );
+ (ulong)keyid[1], sx.sig_lid, sx.sig_flag );
/* check whether we already checked this pubkey */
- if( !qry_lid_table_flag( ultikey_table, sx.sig_id, NULL ) ) {
+ if( !qry_lid_table_flag( ultikey_table, sx.sig_lid, NULL ) ) {
print_user_id("[ultimately trusted]", keyid);
++*lineno;
}
- else if( sx.sig_id == pubkey ) {
+ else if( sx.sig_lid == pubkey ) {
printf("[self-signature]\n");
++*lineno;
}
- else if( sx.sig_id == root ) {
+ else if( sx.sig_lid == root ) {
printf("[closed]\n");
++*lineno;
}
- else if( ins_lid_table_item( lids, sx.sig_id, *lineno ) ) {
+ else if( ins_lid_table_item( lids, sx.sig_lid, *lineno ) ) {
unsigned refline;
- qry_lid_table_flag( lids, sx.sig_id, &refline );
+ qry_lid_table_flag( lids, sx.sig_lid, &refline );
printf("[see line %u]\n", refline);
++*lineno;
}
@@ -494,7 +501,7 @@ do_list_sigs( ulong root, ulong pubkey, int depth,
else {
print_user_id( "", keyid );
++*lineno;
- rc = do_list_sigs( root, sx.sig_id, depth+1, lids, lineno );
+ rc = do_list_sigs( root, sx.sig_lid, depth+1, lids, lineno );
if( rc )
break;
}
@@ -514,11 +521,9 @@ list_sigs( ulong pubkey_id )
LOCAL_ID_INFO *lids;
unsigned lineno = 1;
- rc = keyid_from_local_id( pubkey_id, keyid );
- if( rc ) {
- log_error("Hmmm, no pubkey record for local_id %lu\n", pubkey_id);
+ rc = keyid_from_lid( pubkey_id, keyid );
+ if( rc )
return rc;
- }
printf("Signatures of %08lX.%lu ", (ulong)keyid[1], pubkey_id );
print_user_id("", keyid);
printf("----------------------\n");
@@ -530,6 +535,70 @@ list_sigs( ulong pubkey_id )
return rc;
}
+/****************
+ * List all records of a public key
+ */
+static int
+list_records( ulong lid )
+{
+ int rc;
+ TRUSTREC dr, ur, rec;
+ ulong recno;
+
+ rc = tdbio_read_record( lid, &dr, RECTYPE_DIR );
+ if( rc ) {
+ log_error("lid %lu: read dir record failed: %s\n", lid, g10_errstr(rc));
+ return rc;
+ }
+ tdbio_dump_record( &dr, stdout );
+
+ for( recno=dr.r.dir.keylist; recno; recno = rec.r.key.next ) {
+ rc = tdbio_read_record( recno, &rec, RECTYPE_KEY );
+ if( rc ) {
+ log_error("lid %lu: read key record failed: %s\n",
+ lid, g10_errstr(rc));
+ return rc;
+ }
+ tdbio_dump_record( &rec, stdout );
+ }
+
+ for( recno=dr.r.dir.uidlist; recno; recno = ur.r.uid.next ) {
+ rc = tdbio_read_record( recno, &ur, RECTYPE_UID );
+ if( rc ) {
+ log_error("lid %lu: read uid record failed: %s\n",
+ lid, g10_errstr(rc));
+ return rc;
+ }
+ tdbio_dump_record( &ur, stdout );
+ /* preference records */
+ for(recno=ur.r.uid.prefrec; recno; recno = rec.r.pref.next ) {
+ rc = tdbio_read_record( recno, &rec, RECTYPE_PREF );
+ if( rc ) {
+ log_error("lid %lu: read pref record failed: %s\n",
+ lid, g10_errstr(rc));
+ return rc;
+ }
+ tdbio_dump_record( &rec, stdout );
+ }
+ /* sig records */
+ for(recno=ur.r.uid.siglist; recno; recno = rec.r.sig.next ) {
+ rc = tdbio_read_record( recno, &rec, RECTYPE_SIG );
+ if( rc ) {
+ log_error("lid %lu: read sig record failed: %s\n",
+ lid, g10_errstr(rc));
+ return rc;
+ }
+ tdbio_dump_record( &rec, stdout );
+ }
+ }
+
+ /* add cache record dump here */
+
+
+
+ return rc;
+}
+
/****************
@@ -551,29 +620,28 @@ do_list_path( TRUST_INFO *stack, int depth, int max_depth,
return 0;
}
memset( &sx, 0, sizeof sx );
- sx.local_id = stack[depth-1].lid;
- /* loop over all signatures. If we do not have any, try to
- * create them */
+ sx.lid = stack[depth-1].lid;
+ /* loop over all signatures. If we do not have any, try to create them */
while( !(rc = walk_sigrecs( &sx, 1 )) ) {
TRUST_SEG_LIST tsl, t2, tl;
int i;
- stack[depth].lid = sx.sig_id;
+ stack[depth].lid = sx.sig_lid;
stack[depth].trust = 0;
- if( qry_lid_table_flag( lids, sx.sig_id, &last_depth) ) {
- /*printf("%2lu/%d: marked\n", sx.sig_id, depth );*/
- ins_lid_table_item( lids, sx.sig_id, depth);
+ if( qry_lid_table_flag( lids, sx.sig_lid, &last_depth) ) {
+ /*printf("%2lu/%d: marked\n", sx.sig_lid, depth );*/
+ ins_lid_table_item( lids, sx.sig_lid, depth);
last_depth = depth;
}
else if( depth < last_depth ) {
- /*printf("%2lu/%d: last_depth=%u - updated\n", sx.sig_id, depth, last_depth);*/
+ /*printf("%2lu/%d: last_depth=%u - updated\n", sx.sig_lid, depth, last_depth);*/
last_depth = depth;
- upd_lid_table_flag( lids, sx.sig_id, depth);
+ upd_lid_table_flag( lids, sx.sig_lid, depth);
}
if( last_depth < depth )
- /*printf("%2lu/%d: already visited\n", sx.sig_id, depth)*/;
- else if( !qry_lid_table_flag( ultikey_table, sx.sig_id, NULL ) ) {
+ /*printf("%2lu/%d: already visited\n", sx.sig_lid, depth)*/;
+ else if( !qry_lid_table_flag( ultikey_table, sx.sig_lid, NULL ) ) {
/* found end of path; store it, ordered by path length */
tsl = m_alloc( sizeof *tsl + depth*sizeof(TRUST_INFO) );
tsl->nseg = depth+1;
@@ -592,7 +660,7 @@ do_list_path( TRUST_INFO *stack, int depth, int max_depth,
tl->next = tsl;
}
/*putchar('.'); fflush(stdout);*/
- /*printf("%2lu/%d: found\n", sx.sig_id, depth);*/
+ /*printf("%2lu/%d: found\n", sx.sig_lid, depth);*/
}
else {
rc = do_list_path( stack, depth+1, max_depth, lids, tslist);
@@ -604,209 +672,327 @@ do_list_path( TRUST_INFO *stack, int depth, int max_depth,
}
+/****************
+ * find the uid record given the uid packet and the dir-record.
+ * Returns: 0 = found
+ * -1 = No such uid-record
+ * or other error
+ */
+static int
+find_urec( TRUSTREC *dir, PKT_user_id *uid, TRUSTREC *urec )
+{
+ byte nhash[20];
+ ulong recno;
+ int rc;
+
+ assert(dir->rectype == RECTYPE_DIR );
+ rmd160_hash_buffer( nhash, uid->name, uid->len );
+ for( recno=dir->r.dir.uidlist; recno; recno = urec->r.uid.next ) {
+ rc = tdbio_read_record( recno, urec, RECTYPE_UID );
+ if( rc )
+ return rc == -1 ? G10ERR_READ_FILE : rc;
+ if( !memcmp( nhash, urec->r.uid.namehash, 20 ) )
+ return 0;
+ }
+
+ return -1;
+}
+
/****************
- * Check all the sigs of the given keyblock and mark them
- * as checked. Valid signatures which are duplicates are
- * also marked [shall we check them at all?]
- * FIXME: what shall we do if we have duplicate signatures where only
- * some of them are bad?
+ * Test whether zthe signature lid is already in the (in mem) list.
+ * Returns: True if it is a duplicate
*/
static int
-check_sigs( KBNODE keyblock, int *selfsig_okay, int *revoked )
+test_dupsig( TRUSTREC *rec, ulong lid )
+{
+ int i;
+ ulong alid;
+
+ for( ; rec; rec = rec->next ) {
+ for(i=0; i < SIGS_PER_RECORD && (alid = rec->r.sig.sig[i].lid); i++ )
+ if( alid == lid )
+ return 1;
+ }
+ return 0;
+}
+
+
+/****************
+ * release the sigrec from the uidlist
+ */
+static void
+rel_uidsigs( TRUSTREC *urec )
+{
+ TRUSTREC *r2, *rec;
+ assert( urec->rectype == RECTYPE_UID );
+
+ for(rec=urec->next ; rec; rec = r2 ) {
+ assert( rec->rectype == RECTYPE_SIG );
+ r2 = rec->next;
+ m_free( rec );
+ }
+ urec->next = NULL;
+}
+
+static int
+no_selfsig_del( ulong lid, u32 *keyid, TRUSTREC *urec )
{
- KBNODE node;
int rc;
- LOCAL_ID_INFO *dups = NULL;
- *selfsig_okay = 0;
- *revoked = 0;
- for( node=keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_SIGNATURE
- && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
- || node->pkt->pkt.signature->sig_class == 0x20
- || node->pkt->pkt.signature->sig_class == 0x30) ) {
- int selfsig;
- rc = check_key_signature( keyblock, node, &selfsig );
- if( !rc ) {
- rc = set_signature_packets_local_id( node->pkt->pkt.signature );
- if( rc )
- log_fatal("set_signature_packets_local_id failed: %s\n",
- g10_errstr(rc));
- if( selfsig ) {
- node->flag |= 2; /* mark signature valid */
- *selfsig_okay = 1;
- }
- else if( node->pkt->pkt.signature->sig_class == 0x20 )
- *revoked = 1;
- else
- node->flag |= 1; /* mark signature valid */
-
- if( node->pkt->pkt.signature->sig_class != 0x20 ) {
- if( !dups )
- dups = new_lid_table();
- if( ins_lid_table_item( dups,
- node->pkt->pkt.signature->local_id, 0) )
- node->flag |= 4; /* mark as duplicate */
- }
+ log_error("key %08lX.%lu, uid %02X%02X: "
+ "no self-signature - user id removed\n",
+ (ulong)keyid[1], lid, urec->r.uid.namehash[18],
+ urec->r.uid.namehash[19] );
+ rel_uidsigs( urec );
+ rc = tdbio_delete_uidrec( lid, urec->recnum );
+ if( rc )
+ log_error("no_selfsig_del: delete_uid %lu failed: %s\n",
+ lid, g10_errstr(rc) );
+ return rc;
+}
+
+/****************
+ * Write the signature records from the in-mem list at urec
+ * (The sequence of signatures does not matter)
+ */
+static int
+write_sigs_from_urec( ulong lid, u32 *keyid, TRUSTREC *urec )
+{
+ int rc;
+ TRUSTREC *rec, srec;
+ ulong nextrecno;
+ ulong recno;
+
+ nextrecno = urec->r.uid.siglist;
+ urec->r.uid.siglist = 0; /* end of list marker */
+ for( rec = urec->next; rec; rec = rec->next ) {
+ assert( rec->rectype == RECTYPE_SIG );
+ if( nextrecno ) { /* read the sig record, so it can be reused */
+ rc = tdbio_read_record( nextrecno, &srec, RECTYPE_SIG );
+ if( rc ) {
+ log_error("write_sig_from_urec: read sigrecno %lu failed: %s\n",
+ nextrecno, g10_errstr(rc) );
+ return rc;
}
- if( DBG_TRUST )
- log_debug("trustdb: sig from %08lX.%lu: %s%s\n",
- (ulong)node->pkt->pkt.signature->keyid[1],
- node->pkt->pkt.signature->local_id,
- g10_errstr(rc), (node->flag&4)?" (dup)":"" );
+ recno = nextrecno;
+ nextrecno = srec.r.sig.next;
+ }
+ else
+ recno = tdbio_new_recnum();
+
+ /* link together (the sequence of signatures does not matter) */
+ rec->r.sig.next = urec->r.uid.siglist;
+ urec->r.uid.siglist = recno;
+ rec->r.sig.lid = lid;
+ /* and write */
+ rec->recnum = recno;
+ rc = tdbio_write_record( rec );
+ if( rc ) {
+ log_error("write_sig_from_urec: write sigrecno %lu failed: %s\n",
+ recno, g10_errstr(rc) );
+ return rc;
}
}
- if( dups )
- release_lid_table(dups);
- return 0;
-}
+ /* write the urec back */
+ rc = tdbio_write_record( urec );
+ if( rc ) {
+ log_error("write_sig_from_urec: write urec %lu failed: %s\n",
+ urec->recnum, g10_errstr(rc) );
+ return rc;
+ }
+
+ /* delete remaining old sigrecords */
+ while( nextrecno ) {
+ rc = tdbio_read_record( nextrecno, &srec, RECTYPE_SIG );
+ if( rc ) {
+ log_error("write_sig_from_urec: read sigrecno %lu failed: %s\n",
+ nextrecno, g10_errstr(rc) );
+ return rc;
+ }
+ rc = tdbio_delete_record( nextrecno );
+ if( rc ) {
+ log_error("write_sig_from_urec: delete old %lu failed: %s\n",
+ nextrecno, g10_errstr(rc) );
+ return rc;
+
+ }
+ nextrecno = srec.r.sig.next;
+ }
+
+ return rc;
+}
/****************
* If we do not have sigrecs for the given key, build them and write them
* to the trustdb
*/
static int
-build_sigrecs( ulong lid )
+update_sigs( TRUSTREC *dir )
{
- TRUSTREC rec, krec, rec2;
- KBNODE keyblock = NULL;
- KBNODE node;
+ TRUSTREC *rec, krec;
+ TRUSTREC urec;
+ TRUSTREC *sigrec_list;
+ KBNODE keyblock = NULL;
+ KBNODE node;
+ int i, sigidx, have_urec ;
+ ulong lid = dir->r.dir.lid;
+ u32 keyid[2];
+ int miskey=0;
int rc=0;
- int i, selfsig, revoked;
- ulong rnum, rnum2;
- ulong first_sigrec = 0;
if( DBG_TRUST )
- log_debug("trustdb: build_sigrecs for LID %lu\n", lid );
+ log_debug("update_sigs for %lu\n", lid );
- /* get the keyblock */
- if( (rc=tdbio_read_record( lid, &rec, RECTYPE_DIR )) ) {
- log_error( "build_sigrecs: can't read dir record %lu\n"), lid );
- goto leave;
- }
- if( (rc=tdbio_read_record( rec.r.dir.keylist, &krec, RECTYPE_KEY )) ) {
- log_error("build_sigrecs: can't read primary key record %lu\n"), lid);
+ if( (rc=tdbio_read_record( dir->r.dir.keylist, &krec, RECTYPE_KEY )) ) {
+ log_error("update_sigs: can't read primary key for %lu\n", lid);
goto leave;
}
rc = get_keyblock_byfprint( &keyblock, krec.r.key.fingerprint,
krec.r.key.fingerprint_len );
if( rc ) {
- log_error( "build_sigrecs: keyblock for %lu not found: %s\n",
+ log_error( "update_sigs: keyblock for %lu not found: %s\n",
lid, g10_errstr(rc) );
goto leave;
}
/* check all key signatures */
- rc = check_sigs( keyblock, &selfsig, &revoked );
- if( rc ) {
- log_error(_("build_sigrecs: check_sigs failed\n") );
- goto leave;
- }
- if( !selfsig ) {
- log_error(_("build_sigrecs: self-signature missing\n") );
- tdbio_update_sigflag( lid, 2 );
- rc = G10ERR_BAD_CERT;
- goto leave;
- }
- if( revoked ) {
- log_info(_("build_sigrecs: key has been revoked\n") );
- tdbio_update_sigflag( lid, 3 );
- }
- else
- tdbio_update_sigflag( lid, 0 ); /* assume we have sigs */
-
- /* valid key signatures are now marked; we can now build the sigrecs */
- memset( &rec, 0, sizeof rec );
- rec.rectype = RECTYPE_SIG;
- i = 0;
- rnum = rnum2 = 0;
+ assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
+ have_urec = 0;
+ sigrec_list = NULL;
+ sigidx = 0;
for( node=keyblock; node; node = node->next ) {
- /* insert sigs which are not a selfsig nor a duplicate */
- if( (node->flag & 1) && !(node->flag & 4) ) {
- assert( node->pkt->pkttype == PKT_SIGNATURE );
- if( !node->pkt->pkt.signature->local_id ) {
- /* the next function should always succeed, because
- * we have already checked the signature, and for this
- * it was necessary to have the pubkey. The only reason
- * this can fail are I/O errors of the trustdb or a
- * remove operation on the pubkey database - which should
- * not disturb us, because we have to change them anyway. */
- rc = set_signature_packets_local_id( node->pkt->pkt.signature );
+ if( node->pkt->pkttype == PKT_PUBLIC_KEY )
+ keyid_from_pk( node->pkt->pkt.public_key, keyid );
+ else if( node->pkt->pkttype == PKT_USER_ID ) {
+ if( have_urec && !(urec.mark & 1) ) {
+ if( (rc = no_selfsig_del(lid, keyid, &urec )) )
+ goto leave;
+ have_urec = 0;
+ }
+ if( have_urec ) {
+ rc = write_sigs_from_urec( lid, keyid, &urec );
if( rc )
- log_fatal(_("set_signature_packets_local_id failed: %s\n"),
- g10_errstr(rc));
+ goto leave;
+ rel_uidsigs( &urec );
}
- if( i == SIGS_PER_RECORD ) {
- /* write the record */
- rnum = tdbio_new_recnum();
- if( rnum2 ) { /* write the stored record */
- rec2.r.sig.lid = lid;
- rec2.r.sig.next = rnum; /* the next record number */
- rc = tdbio_write_record( rnum2, &rec2 );
- if( rc ) {
- log_error(_("build_sigrecs: write_record failed\n") );
- goto leave;
- }
- if( !first_sigrec )
- first_sigrec = rnum2;
- }
- rec2 = rec;
- rnum2 = rnum;
- memset( &rec, 0, sizeof rec );
- rec.rectype = RECTYPE_SIG;
- i = 0;
+ rc = find_urec( dir, node->pkt->pkt.user_id, &urec );
+ urec.next = NULL;
+ urec.mark = 0;
+ have_urec = sigidx = 0;
+ if( rc == -1 ) {
+ log_info("update_sigs: new user id for %lu\n", lid );
+ /* fixme: we should add the new user id here */
}
- rec.r.sig.sig[i].lid = node->pkt->pkt.signature->local_id;
- rec.r.sig.sig[i].flag = 0;
- i++;
- }
- }
- if( i || rnum2 ) {
- /* write the record */
- rnum = tdbio_new_recnum();
- if( rnum2 ) { /* write the stored record */
- rec2.r.sig.lid = lid;
- rec2.r.sig.next = rnum;
- rc = tdbio_write_record( rnum2, &rec2 );
- if( rc ) {
- log_error(_("build_sigrecs: write_record failed\n") );
+ else if( rc ) {
+ log_error("update_sigs: find_urec %lu failed: %s\n",
+ lid, g10_errstr(rc) );
goto leave;
}
- if( !first_sigrec )
- first_sigrec = rnum2;
+ else
+ have_urec = 1;
}
- if( i ) { /* write the pending record */
- rec.r.sig.lid = lid;
- rec.r.sig.next = 0;
- rc = tdbio_write_record( rnum, &rec );
- if( rc ) {
- log_error(_("build_sigrecs: write_record failed\n") );
- goto leave;
+ else if( have_urec && node->pkt->pkttype == PKT_SIGNATURE ) {
+ PKT_signature *sig = node->pkt->pkt.signature;
+
+ if( (sig->sig_class&~3) == 0x10 ) {
+ rc = check_key_signature( keyblock, node, &i );
+ if( rc == G10ERR_NO_PUBKEY ) {
+ log_info("key %08lX.%lu, uid %02X%02X: "
+ "no public key for signature %08lX\n",
+ (ulong)keyid[1], lid, urec.r.uid.namehash[18],
+ urec.r.uid.namehash[19], (ulong)sig->keyid[1] );
+ miskey = 1;
+ }
+ else if( rc )
+ log_error("key %08lX.%lu, uid %02X%02X: "
+ "invalid %ssignature: %s\n",
+ (ulong)keyid[1], lid, urec.r.uid.namehash[18],
+ urec.r.uid.namehash[19],
+ i?"self-":"",g10_errstr(rc));
+ else if( i ) /* mark that we have a valid selfsignature */
+ urec.mark |= 1;
+ else if( (rc = set_signature_packets_lid( sig )) )
+ log_error("key %08lX.%lu, uid %02X%02X: "
+ "can't get LID of signer: %s\n",
+ (ulong)keyid[1], lid, urec.r.uid.namehash[18],
+ urec.r.uid.namehash[19], g10_errstr(rc));
+ else if( !test_dupsig( urec.next, sig->local_id ) ) {
+ /* put the valid signature into a list */
+ rec = urec.next;
+ if( !rec || sigidx == SIGS_PER_RECORD ) {
+ rec = m_alloc_clear( sizeof *rec );
+ rec->rectype = RECTYPE_SIG;
+ rec->next = urec.next;
+ urec.next = rec;
+ sigidx = 0;
+ }
+ rec->r.sig.sig[sigidx].lid = sig->local_id;
+ rec->r.sig.sig[sigidx].flag = 0;
+ sigidx++;
+ log_debug("key %08lX.%lu, uid %02X%02X: "
+ "signed by LID %lu\n",
+ (ulong)keyid[1], lid, urec.r.uid.namehash[18],
+ urec.r.uid.namehash[19], sig->local_id);
+ }
+ else if( DBG_TRUST )
+ log_debug("key %08lX.%lu, uid %02X%02X: "
+ "duplicate signature by LID %lu\n",
+ (ulong)keyid[1], lid, urec.r.uid.namehash[18],
+ urec.r.uid.namehash[19], sig->local_id );
+ rc = 0;
+ }
+ else {
+ /* fixme: handle other sig classes here */
}
- if( !first_sigrec )
- first_sigrec = rnum;
}
}
- if( first_sigrec ) { /* update the uid records */
- if( (rc =tdbio_read_record( pubkeyid, &rec, RECTYPE_DIR )) ) {
- log_error(_("update_dir_record: read failed\n"));
+ if( have_urec && !(urec.mark & 1) ) {
+ if( (rc = no_selfsig_del(lid, keyid, &urec )) )
goto leave;
- }
- rec.r.dir.sigrec = first_sigrec;
- if( (rc=tdbio_write_record( pubkeyid, &rec )) ) {
- log_error(_("update_dir_record: write failed\n"));
+ have_urec = 0;
+ }
+ if( have_urec ) {
+ rc = write_sigs_from_urec( lid, keyid, &urec );
+ if( rc )
goto leave;
- }
+ rel_uidsigs( &urec );
}
+ dir->r.dir.dirflags |= DIRF_CHECKED;
+ if( miskey )
+ dir->r.dir.dirflags |= DIRF_MISKEY;
else
- tdbio_update_sigflag( lid, revoked? 3:1 ); /* no signatures */
+ dir->r.dir.dirflags &= ~DIRF_MISKEY;
+ rc = tdbio_write_record( dir );
+ if( rc ) {
+ log_error("update_sigs: write dir record failed: %s\n", g10_errstr(rc));
+ return rc;
+ }
leave:
+ /* fixme: need more cleanup in case of an error */
release_kbnode( keyblock );
if( DBG_TRUST )
- log_debug(_("trustdb: build_sigrecs: %s\n"), g10_errstr(rc) );
+ log_debug("update_sigs for %lu: %s\n", lid, g10_errstr(rc) );
+ return rc;
+}
+
+
+static int
+update_sigs_by_lid( ulong lid )
+{
+ int rc;
+ TRUSTREC rec;
+
+ rc = tdbio_read_record( lid, &rec, RECTYPE_DIR );
+ if( rc ) {
+ log_error("LID %lu: error reading dir record: %s\n",
+ lid, g10_errstr(rc));
+ return rc;
+ }
+ if( !(rec.r.dir.dirflags & DIRF_CHECKED) )
+ rc = update_sigs( &rec );
return rc;
}
@@ -814,7 +1000,7 @@ build_sigrecs( ulong lid )
* Make a list of trust paths
*/
static int
-make_tsl( ulong pubkey_id, TRUST_SEG_LIST *ret_tslist )
+make_tsl( ulong lid, TRUST_SEG_LIST *ret_tslist )
{
int i, rc;
LOCAL_ID_INFO *lids = new_lid_table();
@@ -824,17 +1010,17 @@ make_tsl( ulong pubkey_id, TRUST_SEG_LIST *ret_tslist )
tslist = *ret_tslist = NULL;
- if( !qry_lid_table_flag( ultikey_table, pubkey_id, NULL ) ) {
+ if( !qry_lid_table_flag( ultikey_table, lid, NULL ) ) {
tslist = m_alloc( sizeof *tslist );
tslist->nseg = 1;
tslist->dup = 0;
- tslist->seg[0].lid = pubkey_id;
+ tslist->seg[0].lid = lid;
tslist->seg[0].trust = 0;
tslist->next = NULL;
rc = 0;
}
else {
- stack[0].lid = pubkey_id;
+ stack[0].lid = lid;
stack[0].trust = 0;
rc = do_list_path( stack, 1, max_depth, lids, &tslist );
}
@@ -901,17 +1087,6 @@ propagate_trust( TRUST_SEG_LIST tslist )
}
-
-/****************
- * check whether we already build signature records
- * Return: true if we have.
- */
-static int
-do_we_have_sigs( TRUSTREC *dr )
-{
-}
-
-
/****************
* we have the pubkey record and all needed informations are in the trustdb
* but nothing more is known.
@@ -934,41 +1109,36 @@ do_check( TRUSTREC *dr, unsigned *trustlevel )
if( !dr->r.dir.keylist ) {
log_error("Ooops, no keys\n");
- return G10ERR_TRUSTDB
+ return G10ERR_TRUSTDB;
}
if( !dr->r.dir.uidlist ) {
log_error("Ooops, no user ids\n");
- return G10ERR_TRUSTDB
- }
-
- /* verify the cache */
-
- /* do we have sigrecs */
- if( !do_we_have_sigs( dr ) ) { /* no sigrecs, so build them */
- rc = build_sigrecs( dr->lid );
- if( !rc ) /* and read again */
- rc = tdbio_read_record( dr->lid, dr, RECTYPE_DIR );
+ return G10ERR_TRUSTDB;
}
+ /* did we already check the signatures */
+ if( !(dr->r.dir.dirflags & DIRF_CHECKED) ) /* no - do it now */
+ rc = update_sigs( dr );
- !!!!WORK!!!!
-
- if( dr->r.dir.no_sigs == 3 )
+ if( dr->r.dir.dirflags & DIRF_REVOKED )
tflags |= TRUST_FLAG_REVOKED;
- if( !rc && !dr->r.dir.sigrec ) {
- /* See whether this is our own key */
- if( !qry_lid_table_flag( ultikey_table, pubkeyid, NULL ) )
+ #if 0
+ if( !rc && !dr->r.dir.siglist ) {
+ /* We do not have any signatures; check whether it is one of our
+ * secret keys */
+ if( !qry_lid_table_flag( ultikey_table, dr->r.dir.lid, NULL ) )
*trustlevel = tflags | TRUST_ULTIMATE;
return 0;
}
+ #endif
if( rc )
return rc; /* error while looking for sigrec or building sigrecs */
/* fixme: take it from the cache if it is valid */
/* Make a list of all possible trust-paths */
- rc = make_tsl( pubkeyid, &tslist );
+ rc = make_tsl( dr->r.dir.lid, &tslist );
if( rc )
return rc;
rc = propagate_trust( tslist );
@@ -1023,7 +1193,7 @@ do_check( TRUSTREC *dr, unsigned *trustlevel )
m_free(tsl);
}
}
- last_trust_web_key = pubkeyid;
+ last_trust_web_key = dr->r.dir.lid;
last_trust_web_tslist = tslist;
return 0;
}
@@ -1079,11 +1249,13 @@ list_trustdb( const char *username )
if( (rc = get_pubkey_byname( pk, username )) )
log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
- else if( (rc=tdbio_search_record( pk, &rec )) && rc != -1 )
+ else if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 )
log_error("problem finding '%s' in trustdb: %s\n",
username, g10_errstr(rc));
else if( rc == -1 )
log_error("user '%s' not in trustdb\n", username);
+ else if( (rc = list_records( pk->local_id)) )
+ log_error("user '%s' read problem: %s\n", username, g10_errstr(rc));
else if( (rc = list_sigs( pk->local_id )) )
log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
free_public_key( pk );
@@ -1097,27 +1269,40 @@ list_trustdb( const char *username )
putchar('-');
putchar('\n');
for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ )
- tdbio_dump_record( recnum, &rec, stdout );
+ tdbio_dump_record( &rec, stdout );
}
}
/****************
- * make a list of all owner trust value.
+ * make a list of all defined owner trust value.
*/
void
list_ownertrust()
{
TRUSTREC rec;
+ TRUSTREC rec2;
ulong recnum;
int i;
byte *p;
+ int rc;
for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
- if( rec.rectype == RECTYPE_KEY ) {
- p = rec.r.key.fingerprint;
- for(i=0; i < rec.r.key.fingerprint_len; i++, p++ )
+ if( rec.rectype == RECTYPE_DIR ) {
+ if( !rec.r.dir.keylist ) {
+ log_error("Oops; directory record w/o primary key\n");
+ continue;
+ }
+ if( !rec.r.dir.ownertrust )
+ continue;
+ rc = tdbio_read_record( rec.r.dir.keylist, &rec2, RECTYPE_KEY);
+ if( rc ) {
+ log_error("error reading key record: %s\n", g10_errstr(rc));
+ continue;
+ }
+ p = rec2.r.key.fingerprint;
+ for(i=0; i < rec2.r.key.fingerprint_len; i++, p++ )
printf("%02X", *p );
- printf(":%u:\n", (unsigned)rec.r.key.ownertrust );
+ printf(":%u:\n", (unsigned)rec.r.dir.ownertrust );
}
}
}
@@ -1138,7 +1323,7 @@ list_trust_path( int max_depth, const char *username )
if( (rc = get_pubkey_byname( pk, username )) )
log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
- else if( (rc=tdbio_search_record( pk, &rec )) && rc != -1 )
+ else if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 )
log_error("problem finding '%s' in trustdb: %s\n",
username, g10_errstr(rc));
else if( rc == -1 ) {
@@ -1212,6 +1397,48 @@ list_trust_path( int max_depth, const char *username )
/****************
+ * Check the complete trustdb or only the entries for the given username
+ */
+void
+check_trustdb( const char *username )
+{
+ TRUSTREC rec;
+ int rc;
+
+ if( username ) {
+ PKT_public_key *pk = m_alloc_clear( sizeof *pk );
+
+ if( (rc = get_pubkey_byname( pk, username )) )
+ log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
+ else if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 )
+ log_error("problem finding '%s' in trustdb: %s\n",
+ username, g10_errstr(rc));
+ else if( rc == -1 )
+ log_error("user '%s' not in trustdb\n", username);
+ else if( (rc = update_sigs( &rec )) )
+ log_error("lid %lu: check failed: %s\n",
+ rec.recnum, g10_errstr(rc));
+ else
+ log_info("lid %lu: checked: %s\n", rec.recnum, g10_errstr(rc));
+ free_public_key( pk );
+ }
+ else {
+ ulong recnum;
+
+ for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
+ if( rec.rectype == RECTYPE_DIR ) {
+ rc = update_sigs( &rec );
+ if( rc )
+ log_error("lid %lu: check failed: %s\n",
+ recnum, g10_errstr(rc) );
+ else
+ log_info("lid %lu: checked\n", recnum );
+ }
+ }
+ }
+}
+
+/****************
* Get the trustlevel for this PK.
* Note: This does not ask any questions
* Returns: 0 okay of an errorcode
@@ -1385,35 +1612,15 @@ get_ownertrust( ulong lid, unsigned *r_otrust )
log_error("get_ownertrust: read dir record failed\n");
return G10ERR_TRUSTDB;
}
- if( tdbio_read_record( rec.r.dir.keyrec, &rec, RECTYPE_KEY ) ) {
- log_error("get_ownertrust: read key record failed\n");
- return G10ERR_TRUSTDB;
- }
if( r_otrust )
- *r_otrust = rec.r.key.ownertrust;
- return 0;
-}
-
-int
-keyid_from_trustdb( ulong lid, u32 *keyid )
-{
- TRUSTREC rec;
-
- if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
- log_error("keyid_from_trustdb: read record failed\n");
- return G10ERR_TRUSTDB;
- }
- if( keyid ) {
- keyid[0] = rec.r.dir.keyid[0];
- keyid[1] = rec.r.dir.keyid[1];
- }
+ *r_otrust = rec.r.dir.ownertrust;
return 0;
}
/****************
* This function simply looks for the key in the trustdb
- * and sets PK->local_id.
+ * and makes sure that pk->local_id is set to the coreect value.
* Return: 0 = found
* -1 = not found
* other = error
@@ -1431,7 +1638,7 @@ query_trust_record( PKT_public_key *pk )
}
}
else { /* no local_id: scan the trustdb */
- if( (rc=tdbio_search_record( pk, &rec )) && rc != -1 ) {
+ if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) {
log_error("query_trust_record: search_record failed: %s\n",
g10_errstr(rc));
return rc;
@@ -1457,10 +1664,6 @@ rel_mem_uidnode( u32 *keyid, int err, TRUSTREC *rec )
r2 = r->next;
m_free(r);
}
- for(r=rec->help_sig; r; r = r2 ) {
- r2 = r->next;
- m_free(r);
- }
m_free(rec);
}
@@ -1469,17 +1672,19 @@ rel_mem_uidnode( u32 *keyid, int err, TRUSTREC *rec )
/****************
* Insert a trust record into the TrustDB
* This function fails if this record already exists.
+ *
+ * We build everything we can do at this point. We cannot build
+ * the sig records, because their LIDs are needed and we may not have them.
*/
int
insert_trust_record( PKT_public_key *orig_pk )
{
TRUSTREC dirrec, *rec, *rec2;
- TRUSTREC *keylist_head, **keylist_tail;
- TRUSTREC *uidlist_head, **uidlist_tail, uidlist;
+ TRUSTREC *keylist_head, **keylist_tail, *keylist;
+ TRUSTREC *uidlist_head, **uidlist_tail, *uidlist;
KBNODE keyblock = NULL;
KBNODE node;
u32 keyid[2]; /* of primary key */
- ulong knum, dnum;
byte *fingerprint;
size_t fingerlen;
int rc = 0;
@@ -1489,9 +1694,9 @@ insert_trust_record( PKT_public_key *orig_pk )
dirrec.rectype = RECTYPE_DIR;
if( orig_pk->local_id )
- log_bug("pk->local_id=%lu\n", (ulong)pk->local_id );
+ log_bug("pk->local_id=%lu\n", (ulong)orig_pk->local_id );
- fingerprint = fingerprint_from_pk( orig_pk, &fingerlen );
+ fingerprint = fingerprint_from_pk( orig_pk, NULL, &fingerlen );
/* fixme: assert that we do not have this record.
* we can do this by searching for the primary keyid
@@ -1506,9 +1711,8 @@ insert_trust_record( PKT_public_key *orig_pk )
}
/* build data structure as linked lists in memory */
- keylist_head = NULL; keylist_tail = &keylist_head;
- uidlist_head = NULL; uidlist_tail = &uidlist_head;
- uidlist = NULL;
+ keylist_head = NULL; keylist_tail = &keylist_head; keylist = NULL;
+ uidlist_head = NULL; uidlist_tail = &uidlist_head; uidlist = NULL;
keyid[0] = keyid[1] = 0;
for( node=keyblock; node; node = node->next ) {
if( node->pkt->pkttype == PKT_PUBLIC_KEY
@@ -1520,7 +1724,7 @@ insert_trust_record( PKT_public_key *orig_pk )
BUG(); /* more than one primary key */
keyid_from_pk( pk, keyid );
}
- fingerprint = fingerprint_from_pk( orig_pk, &fingerlen );
+ fingerprint = fingerprint_from_pk( orig_pk, NULL, &fingerlen );
rec = m_alloc_clear( sizeof *rec );
rec->rectype = RECTYPE_KEY;
rec->r.key.pubkey_algo = pk->pubkey_algo;
@@ -1554,8 +1758,8 @@ insert_trust_record( PKT_public_key *orig_pk )
else if( (rc = check_key_signature( keyblock, node, NULL ))) {
log_error("key %08lX, uid %02X%02X: "
"invalid self-signature: %s\n",
- (ulong)keyid[1], uidlist->namehash[18],
- uidlist->namehash[19], g10_errstr(rc) );
+ (ulong)keyid[1], uidlist->r.uid.namehash[18],
+ uidlist->r.uid.namehash[19], g10_errstr(rc) );
rc = 0;
}
else { /* build the prefrecord */
@@ -1567,10 +1771,6 @@ insert_trust_record( PKT_public_key *orig_pk )
/* handle it here */
}
else { /* not a selfsignature */
- /* put all this sigs into a list and mark them as unchecked
- * we can't check here because we probably have not
- * all keys of other signators - we do it on deman
- */
}
}
}
@@ -1592,7 +1792,7 @@ insert_trust_record( PKT_public_key *orig_pk )
/* check that we have at least one userid */
if( !uidlist_head ) {
log_error("key %08lX: no user ids - rejected\n", (ulong)keyid[1] );
- rc = G10ERR_BAD_CERT,
+ rc = G10ERR_BAD_CERT;
goto leave;
}
@@ -1600,7 +1800,6 @@ insert_trust_record( PKT_public_key *orig_pk )
/* fixme: should start a transaction here */
dirrec.recnum = tdbio_new_recnum();
dirrec.r.dir.lid = dirrec.recnum;
- /* fixme: how do we set sigflag???*/
/* (list of keys) */
for(rec=keylist_head; rec; rec = rec->next ) {
rec->r.key.lid = dirrec.recnum;
@@ -1620,15 +1819,7 @@ insert_trust_record( PKT_public_key *orig_pk )
}
for( rec2 = rec->help_pref; rec2; rec2 = rec2->next )
rec2->r.pref.next = rec2->next? rec2->next->recnum : 0;
- rec->r.uid.prefrec = rec->help_pref->recnum;
- /* (signature list) */
- for( rec2 = rec->help_sig; rec2; rec2 = rec2->next ) {
- rec2->r.sig.lid = dirrec.recnum;
- rec2->recnum = tdbio_new_recnum();
- }
- for( rec2 = rec->help_sig; rec2; rec2 = rec2->next )
- rec2->r.sig.next = rec2->next? rec2->next->recnum : 0;
- rec->r.uid.siglist = rec->help_sig->recnum;
+ rec->r.uid.prefrec = rec->help_pref? rec->help_pref->recnum : 0;
}
for(rec=uidlist_head; rec; rec = rec->next )
rec->r.uid.next = rec->next? rec->next->recnum : 0;
@@ -1650,7 +1841,7 @@ insert_trust_record( PKT_public_key *orig_pk )
rc = G10ERR_TRUSTDB;
goto leave;
}
- for( rec2=rec->help_pref; rec2; rec2 = rec2->next ); {
+ for( rec2=rec->help_pref; rec2; rec2 = rec2->next ) {
assert( rec2->rectype == RECTYPE_PREF );
if( tdbio_write_record( rec2 ) ) {
log_error("writing pref record failed\n");
@@ -1658,29 +1849,33 @@ insert_trust_record( PKT_public_key *orig_pk )
goto leave;
}
}
- for( rec2=rec->help_sig; rec2; rec2 = rec2->next ); {
- assert( rec2->rectype == RECTYPE_SIG );
- if( tdbio_write_record( rec2 ) ) {
- log_error("writing sig record failed\n");
- rc = G10ERR_TRUSTDB;
- goto leave;
- }
- }
}
- if( tdbio_write_record( dirrec.r.dir.lid, &dirrec ) ) {
+ if( tdbio_write_record( &dirrec ) ) {
log_error("writing dir record failed\n");
return G10ERR_TRUSTDB;
}
/* and store the LID */
orig_pk->local_id = dirrec.r.dir.lid;
+ for( node=keyblock; node; node = node->next ) {
+ if( node->pkt->pkttype == PKT_PUBLIC_KEY
+ || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
+ PKT_public_key *pk = node->pkt->pkt.public_key;
+ pk->local_id = dirrec.r.dir.lid;
+ }
+ else if( node->pkt->pkttype == PKT_SIGNATURE ) {
+ PKT_signature *sig = node->pkt->pkt.signature;
+ sig->local_id = dirrec.r.dir.lid;
+ }
+ }
+
leave:
- for( rec=dirrec.r.dir.uidlist; rec; rec = rec2 ) {
+ for(rec=uidlist_head; rec; rec = rec->next ) {
rec2 = rec->next;
- rel_mem_uidnode(rec);
+ rel_mem_uidnode(NULL, 0, rec );
}
- for( rec=dirrec.r.dir.keylist; rec; rec = rec2 ) {
+ for(rec=keylist_head; rec; rec = rec->next ) {
rec2 = rec->next;
m_free(rec);
}
@@ -1693,29 +1888,17 @@ int
update_ownertrust( ulong lid, unsigned new_trust )
{
TRUSTREC rec;
- ulong recnum;
if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
log_error("update_ownertrust: read dir failed\n");
return G10ERR_TRUSTDB;
}
- recnum = rec.r.dir.keyrec;
- if( tdbio_read_record( recnum, &rec, RECTYPE_KEY ) ) {
- log_error("update_ownertrust: read key failed\n");
- return G10ERR_TRUSTDB;
- }
- /* check keyid, fingerprint etc ? */
-
- rec.r.key.ownertrust = new_trust;
- if( tdbio_write_record( recnum, &rec ) ) {
+ rec.r.dir.ownertrust = new_trust;
+ if( tdbio_write_record( &rec ) ) {
log_error("update_ownertrust: write failed\n");
return G10ERR_TRUSTDB;
}
-
return 0;
}
-
-
-
diff --git a/g10/trustdb.h b/g10/trustdb.h
index 705ffaf80..aaf0d4a8d 100644
--- a/g10/trustdb.h
+++ b/g10/trustdb.h
@@ -39,12 +39,13 @@
void list_trustdb(const char *username);
void list_trust_path( int max_depth, const char *username );
void list_ownertrust(void);
+void check_trustdb( const char *username );
int init_trustdb( int level, const char *dbname );
int check_trust( PKT_public_key *pk, unsigned *r_trustlevel );
int query_trust_info( PKT_public_key *pk );
int enum_trust_web( void **context, ulong *lid );
int get_ownertrust( ulong lid, unsigned *r_otrust );
-int keyid_from_trustdb( ulong lid, u32 *keyid );
+int keyid_from_lid( ulong lid, u32 *keyid );
int query_trust_record( PKT_public_key *pk );
int insert_trust_record( PKT_public_key *pk );
int update_ownertrust( ulong lid, unsigned new_trust );