Ready to test version 0.2.0

This commit is contained in:
Werner Koch 1998-01-25 18:56:33 +00:00
parent d71f8bce7e
commit 32344420b7
8 changed files with 130 additions and 25 deletions

8
NEWS
View File

@ -1,4 +1,12 @@
* The logic to handle the web of trust is now implemented. It is
has some bugs; but I'm going to change the algorithm anyway.
It works by calculating the trustlevel on the fly. It may ask
you to provide trust parameters if the calculated trust probability
is too low. I will write a paper which discusses this new approach.
* a couple of changes to the configure script.
* New option "--quick-random" which uses a much quicker random
number generator. Keys generated while this option is in effect
are flags with "INSECURE!" in the user-id. This is a development

6
README
View File

@ -11,14 +11,11 @@
* Some features are not yet implemented
I provide this version as a reality check to start discussion.
Please subscribe to g10@net.lut.ac.uk by sending a mail with
the word "subscribe" in the body to "g10-request@net.lut.ac.uk".
See the file COPYING for copyright and warranty information.
Due to the fact that G10 does not use use any patented algorithm,
it cannot be compatible to old PGP versions, because those use
IDEA (which is worldwide patented) and RSA (which is patented in
@ -210,7 +207,8 @@
depth. If depth is negative, duplicate introducers are not listed,
because those would increase the trust probabilty only minimal.
(you must use the special option "--" to stop option parsing when
using a negative number)
using a negative number). This option may create new entries in the
trustdb.
--print-mds filenames

5
TODO
View File

@ -39,4 +39,9 @@
* Burn the buffers used by fopen().
* bug: g10/trustdb.c#build_sigrecs caled to often by do_list_path
and remove the bad kludge. Maybe we should put all sigs into the trustdb
and mark them as valid/invalid/nopubkey, and how do we check, that
we have a self-signature -> put this stuff into a kind of directory
record, as it does not belong to the pubkey record?

View File

@ -1 +1 @@
0.1.4
0.2.0

View File

@ -11,6 +11,8 @@
Layout of the TrustDB
=====================
FIXME: use a directory record as top node instead of the pubkey record
The TrustDB is build from fixed length records, where the first bytes
describes the record type. All numeric values are stored in network
byte order. The length of each record is 40 bytes. The first record of
@ -74,7 +76,9 @@ Record type 2:
we have control over the secret key too.
Bit 3: set if key is revoked; do not use it.
Bit 7-4: reserved
3 byte reserved
1 byte No signatures (used to avoid duplicate building).
FIXME: this should be moved to the cahce record
2 byte reserved
Record type 3: (cache record)

View File

@ -191,6 +191,8 @@ main( int argc, char **argv )
{ 532, "quick-random", 0, "\r"},
{ 533, "list-trust-path",0, "\r"},
{ 534, "no-comment", 0, "do not write comment packets"},
{ 535, "completes_needed", 1, "(default is 1)"},
{ 536, "marginals_needed", 1, "(default is 3)"},
{0} };
ARGPARSE_ARGS pargs;
@ -219,6 +221,8 @@ main( int argc, char **argv )
opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH;
opt.def_pubkey_algo = PUBKEY_ALGO_ELGAMAL;
opt.def_digest_algo = DIGEST_ALGO_RMD160;
opt.completes_needed = 1;
opt.marginals_needed = 3;
/* check wether we have a config file on the commandline */
orig_argc = argc;
@ -338,6 +342,8 @@ main( int argc, char **argv )
case 532: quick_random_gen(1); break;
case 533: set_cmd( &cmd, aListTrustPath); break;
case 534: opt.no_comment=1; break;
case 535: opt.completes_needed = pargs.r.ret_int; break;
case 536: opt.marginals_needed = pargs.r.ret_int; break;
default : errors++; pargs.err = configfp? 1:2; break;
}
}
@ -360,9 +366,18 @@ main( int argc, char **argv )
log_error("selected digest algorithm is invalid\n");
errors++;
}
if( opt.completes_needed < 1 ) {
log_error("completes_needed must be greater than 0\n");
errors++;
}
if( opt.marginals_needed < 2 ) {
log_error("marginals_needed must be greater than 1\n");
errors++;
}
if( errors )
exit(2);
set_debug();
if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
if( cmd == aKModeC ) {

View File

@ -40,8 +40,8 @@ struct {
int def_pubkey_algo;
int def_digest_algo;
int no_comment;
int reserved10;
int reserved11;
int marginals_needed;
int completes_needed;
int reserved12;
int reserved13;
int reserved14;

View File

@ -66,6 +66,7 @@ struct trust_record {
byte reserved;
byte fingerprint[20];
byte ownertrust;
byte no_sigs;
/* fixme: indicate a flag to */
} pubkey;
struct { /* cache record */
@ -94,7 +95,7 @@ typedef struct trust_record TRUSTREC;
typedef struct {
ulong pubkey_id; /* localid of the pubkey */
ulong sig_id; /* returned signature id */
unsigned sig_flag; /* returned signaure record flag */
unsigned sig_flag; /* returned signature record flag */
struct { /* internal data */
int eof;
TRUSTREC rec;
@ -138,7 +139,7 @@ static int read_record( ulong recnum, TRUSTREC *rec );
static int write_record( ulong recnum, TRUSTREC *rec );
static ulong new_recnum(void);
static void dump_record( ulong rnum, TRUSTREC *rec, FILE *fp );
static int walk_sigrecs( SIGREC_CONTEXT *c );
static int walk_sigrecs( SIGREC_CONTEXT *c, int create );
static LOCAL_ID_INFO *new_lid_table(void);
static void release_lid_table( LOCAL_ID_INFO *tbl );
@ -151,9 +152,11 @@ static int do_list_path( TRUST_INFO *stack, int depth, int max_depth,
LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist );
static int list_sigs( ulong pubkey_id );
static int build_sigrecs( ulong pubkeyid, int kludge );
static int propagate_trust( TRUST_SEG_LIST tslist );
static int do_check( ulong pubkeyid, unsigned *trustlevel );
static int update_no_sigs( ulong lid, int no_sigs );
static char *db_name;
static int db_fd = -1;
@ -329,6 +332,7 @@ read_record( ulong recnum, TRUSTREC *rec )
rec->r.pubkey.reserved = *p++;
memcpy( rec->r.pubkey.fingerprint, p, 20); p += 20;
rec->r.pubkey.ownertrust = *p++;
rec->r.pubkey.no_sigs = *p++;
if( rec->r.pubkey.local_id != recnum ) {
log_error("%s: pubkey local_id != recnum (%lu,%lu)\n",
db_name,
@ -399,6 +403,7 @@ write_record( ulong recnum, TRUSTREC *rec )
*p++ = rec->r.pubkey.reserved;
memcpy( p, rec->r.pubkey.fingerprint, 20); p += 20;
*p++ = rec->r.pubkey.ownertrust;
*p++ = rec->r.pubkey.no_sigs;
assert( rec->r.pubkey.local_id == recnum );
break;
case 3:
@ -563,8 +568,9 @@ dump_record( ulong rnum, TRUSTREC *rec, FILE *fp )
break;
case 1: fprintf(fp, "version\n");
break;
case 2: fprintf(fp, "pubkey, keyid=%08lX, ownertrust=%02x\n",
rec->r.pubkey.keyid[1], rec->r.pubkey.ownertrust );
case 2: fprintf(fp, "pubkey, keyid=%08lX, ownertrust=%02x%s\n",
rec->r.pubkey.keyid[1], rec->r.pubkey.ownertrust,
rec->r.pubkey.no_sigs?" (inv sigs)":"");
break;
case 3: fprintf(fp, "cache\n");
case 4:
@ -674,9 +680,17 @@ list_trust_path( int max_depth, const char *username )
else if( (rc=scan_record_by_pkc( pkc, &rec, 2 )) && 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 {
else if( rc == -1 ) {
log_info("user '%s' not in trustdb - inserting\n", username);
rc = insert_trust_record( pkc );
if( rc )
log_error("failed to put '%s' into trustdb: %s\n", username, g10_errstr(rc));
else {
assert( pkc->local_id );
}
}
if( !rc ) {
TRUST_SEG_LIST tsl, tslist = NULL;
if( !qry_lid_table_flag( ultikey_table, pkc->local_id, NULL ) ) {
@ -742,7 +756,7 @@ list_trust_path( int max_depth, const char *username )
* Returns: 0 - okay, -1 for eof (no more sigs) or any other errorcode
*/
static int
walk_sigrecs( SIGREC_CONTEXT *c )
walk_sigrecs( SIGREC_CONTEXT *c, int create )
{
int rc=0;
TRUSTREC *r;
@ -753,6 +767,17 @@ walk_sigrecs( SIGREC_CONTEXT *c )
r = &c->ctl.rec;
if( !r->rectype ) { /* this is the first call */
rc = scan_record( c->pubkey_id, r, 4, &rnum );
if( rc == -1 && create ) { /* no signature records */
rc = build_sigrecs( c->pubkey_id, 1 );
if( rc ) {
if( rc != -1 )
log_info("%lu: error building sigs on the fly: %s\n",
c->pubkey_id, g10_errstr(rc) );
rc = -1;
}
else /* once more */
rc = scan_record( c->pubkey_id, r, 4, &rnum );
}
if( rc == -1 ) { /* no signature records */
c->ctl.eof = 1;
return -1; /* return eof */
@ -997,7 +1022,7 @@ do_list_sigs( ulong root, ulong pubkey, int depth,
memset( &sx, 0, sizeof sx );
sx.pubkey_id = pubkey;
for(;;) {
rc = walk_sigrecs( &sx );
rc = walk_sigrecs( &sx, 0 );
if( rc )
break;
rc = keyid_from_local_id( sx.sig_id, keyid );
@ -1090,7 +1115,9 @@ do_list_path( TRUST_INFO *stack, int depth, int max_depth,
}
memset( &sx, 0, sizeof sx );
sx.pubkey_id = stack[depth-1].lid;
while( !(rc = walk_sigrecs( &sx )) ) {
/* 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;
@ -1181,7 +1208,7 @@ check_sigs( KBNODE keyblock, int *selfsig_okay )
* to the trustdb
*/
static int
build_sigrecs( ulong pubkeyid )
build_sigrecs( ulong pubkeyid, int kludge )
{
TRUSTREC rec, rec2;
PUBKEY_FIND_INFO finfo=NULL;
@ -1201,6 +1228,10 @@ build_sigrecs( ulong pubkeyid )
log_error("build_sigrecs: can't read pubkey record\n");
goto leave;
}
if( kludge && rec.r.pubkey.no_sigs ) {
rc = -1;
goto leave;
}
finfo = m_alloc_clear( sizeof *finfo );
finfo->keyid[0] = rec.r.pubkey.keyid[0];
finfo->keyid[1] = rec.r.pubkey.keyid[1];
@ -1224,10 +1255,12 @@ build_sigrecs( ulong pubkeyid )
}
if( !selfsig ) {
log_error("build_sigrecs: self-certificate missing\n" );
update_no_sigs( pubkeyid, 1 );
rc = G10ERR_BAD_CERT;
goto leave;
}
update_no_sigs( pubkeyid, 0 );
/* valid key signatures are now marked; we can now build the
* sigrecs */
memset( &rec, 0, sizeof rec );
@ -1241,7 +1274,9 @@ build_sigrecs( ulong pubkeyid )
/* 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 erros of the trustdb. */
* 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 chace them anyway. */
rc = set_signature_packets_local_id( node->pkt->pkt.signature );
if( rc )
log_fatal("set_signature_packets_local_id failed: %s\n",
@ -1401,8 +1436,11 @@ do_check( ulong pubkeyid, unsigned *trustlevel )
TRUSTREC rec;
TRUST_SEG_LIST tsl, tsl2, tslist;
int marginal, fully;
int fully_needed = 4;
int marginal_needed = 6;
int fully_needed = opt.completes_needed;
int marginal_needed = opt.marginals_needed;
assert( fully_needed > 0 && marginal_needed > 1 );
*trustlevel = TRUST_UNDEFINED;
@ -1411,7 +1449,7 @@ do_check( ulong pubkeyid, unsigned *trustlevel )
/* do we have sigrecs */
rc = scan_record( pubkeyid, &rec, 4, &rnum );
if( rc == -1 ) { /* no sigrecs, so build them */
rc = build_sigrecs( pubkeyid );
rc = build_sigrecs( pubkeyid, 1 );
if( !rc ) /* and read again */
rc = scan_record( pubkeyid, &rec, 4, &rnum );
}
@ -1575,8 +1613,14 @@ check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel )
return rc;
}
else if( rc == -1 ) {
log_error("check_trust: pubkey not in TrustDB\n");
goto leave;
rc = insert_trust_record( pkc );
if( rc ) {
log_error("failed to insert pubkey into trustdb: %s\n",
g10_errstr(rc));
goto leave;
}
log_info("pubkey not in trustdb - inserted as %lu\n",
pkc->local_id );
}
}
/* fixme: do some additional checks on the pubkey record */
@ -1735,6 +1779,7 @@ insert_trust_record( PKT_public_cert *pkc )
rec.r.pubkey.pubkey_algo = pkc->pubkey_algo;
memcpy(rec.r.pubkey.fingerprint, fingerprint, fingerlen );
rec.r.pubkey.ownertrust = 0;
rec.r.pubkey.no_sigs = 0;
if( write_record( recnum, &rec ) ) {
log_error("insert_trust_record: write failed\n");
return G10ERR_TRUSTDB;
@ -1771,6 +1816,36 @@ update_ownertrust( ulong lid, unsigned new_trust )
}
/****************
* Kludge to prevent duplicate build_sigrecs() due to an invalid
* certificate (no selfsignature or something like this)
*/
static int
update_no_sigs( ulong lid, int no_sigs )
{
TRUSTREC rec;
if( read_record( lid, &rec ) ) {
log_error("update_no_sigs: read failed\n");
return G10ERR_TRUSTDB;
}
/* check keyid, fingerprint etc ? */
if( rec.rectype != 2 ) {
log_error("update_no_sigs: invalid record type\n");
return G10ERR_TRUSTDB;
}
rec.r.pubkey.no_sigs = !!no_sigs;
if( write_record( lid, &rec ) ) {
log_error("update_no_sigs: write failed\n");
return G10ERR_TRUSTDB;
}
return 0;
}
int
verify_private_data()
{