From 3bcd3cd7b28ac1e65738320af8451606a8c8dd51 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sat, 31 Jan 1998 21:24:36 +0000 Subject: [PATCH] auf tobold --- doc/DETAILS | 51 +++++++++ g10/sig-check.c | 5 +- g10/trustdb.c | 287 ++++++++++++++++++++++++++++-------------------- 3 files changed, 219 insertions(+), 124 deletions(-) diff --git a/doc/DETAILS b/doc/DETAILS index 905795a6e..7455a38bf 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -124,3 +124,54 @@ Record type 5 (sigrec) 1 byte reserved +Record Type 6 (hash table) +------------- + Due to the fact that we use the keyid to lookup keys, we can + implement quick access by some simple hash methods, and avoid + the overhead gdbm. A property of keyids is that they can be + used directly as hash value (They can be considered as strong + random numbers. + What we use is a dynamic multilevel architecture, which combines + Hashtables, record lists, and linked list. + + This record is a hashtable of 256 entries; a special property + is, that all these records are adjacent stored to make up one + big table. The hash value is simple the 1st, 2nd, ... byte of + the keyid (depending on the indirection level). + + 1 byte value 5 + 1 byte reserved + n u32 recnum; n depends on th record length: + n = (reclen-2)/4 which yields 9 for the current record length + of 40 bytes. + + the total number of surch record which makes up the table is: + m = (256+n-1) / n + which is 29 for a record length of 40. + + To look up a key we use its lsb to get the recnum from this + hashtable and look up this addressed record: + - If this record is another hashtable, we use 2nd lsb + to index this hast table and so on. + - if this record is of hashlist, we lwalk thru these + reclist record until we found one whos hash fields + matches the MSB of our keyid, and lookup this record + - if this record is a dir record, we compare the + keyid and if this is correct, we get the keyrecod and compare + the fingerprint to decide wether it is the requested key; + if this is not the correct dir record, we look at the next + dir record which is linked by the link field. + +Record type 7 (hast list) +------------- + see hash table for an explanation. + + 1 byte value 6 + 1 byte reserved + 1 u32 chain next hash list record + n times n = (reclen-6)/5 + 1 byte hash + 1 u32 recnum + + For the current record length of 40, n is 6 + diff --git a/g10/sig-check.c b/g10/sig-check.c index 54ccae951..fcc2a6948 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -42,8 +42,7 @@ signature_check( PKT_signature *sig, MD_HANDLE digest ) { PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc ); MPI result = NULL; - int rc=0, i, j, c, old_enc; - byte *dp; + int rc=0; if( get_pubkey( pkc, sig->keyid ) ) { @@ -74,6 +73,8 @@ signature_check( PKT_signature *sig, MD_HANDLE digest ) } #ifdef HAVE_RSA_CIPHER else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { + int i, j, c, old_enc; + byte *dp; RSA_public_key pkey; result = mpi_alloc(40); diff --git a/g10/trustdb.c b/g10/trustdb.c index 065d00d6c..9e2c5be74 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -39,7 +39,9 @@ #define TRUST_RECORD_LEN 40 -#define SIGS_PER_RECORD ((TRUST_RECORD_LEN-10)/5) +#define SIGS_PER_RECORD ((TRUST_RECORD_LEN-10)/5) +#define ITEMS_PER_HTBL_RECORD ((TRUST_RECORD_LEN-2)/4) +#define ITEMS_PER_HLST_RECORD ((TRUST_RECORD_LEN-6)/5) #define MAX_LIST_SIGS_DEPTH 20 @@ -48,6 +50,8 @@ #define RECTYPE_KEY 3 #define RECTYPE_CTL 4 #define RECTYPE_SIG 5 +#define RECTYPE_HTBL 6 +#define RECTYPE_HLST 7 struct trust_record { @@ -67,8 +71,9 @@ struct trust_record { ulong local_id; u32 keyid[2]; ulong keyrec; /* recno of public key record */ - ulong ctlrec /* recno of control record */ + ulong ctlrec; /* recno of control record */ ulong sigrec; /* recno of first signature record */ + ulong link; /* to next dir record */ byte no_sigs; /* does not have sigature and checked */ } dir; struct { /* public key record */ @@ -91,15 +96,27 @@ struct trust_record { byte flag; /* reserved */ } sig[SIGS_PER_RECORD]; } sig; + struct { + ulong item[ITEMS_PER_HTBL_RECORD]; + } htbl; + struct { + ulong chain; + struct { + byte hash; + ulong rnum; + } item[ITEMS_PER_HLST_RECORD]; + } hlst; } r; }; typedef struct trust_record TRUSTREC; typedef struct { ulong local_id; /* localid of the pubkey */ + ulong sigrec; ulong sig_id; /* returned signature id */ unsigned sig_flag; /* returned signature record flag */ struct { /* internal data */ + int init_done; int eof; TRUSTREC rec; int index; @@ -139,7 +156,7 @@ typedef struct { static void create_db( const char *fname ); static void open_db(void); static void dump_record( ulong rnum, TRUSTREC *rec, FILE *fp ); -static int read_record( ulong recnum, TRUSTREC *rec ); +static int read_record( ulong recnum, TRUSTREC *rec, int expected ); static int write_record( ulong recnum, TRUSTREC *rec ); static ulong new_recnum(void); static int search_record( PKT_public_cert *pkc, TRUSTREC *rec ); @@ -156,9 +173,9 @@ 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 build_sigrecs( ulong pubkeyid ); static int propagate_trust( TRUST_SEG_LIST tslist ); -static int do_check( ulong pubkeyid, unsigned *trustlevel ); +static int do_check( ulong pubkeyid, TRUSTREC *drec, unsigned *trustlevel ); static int update_no_sigs( ulong lid, int no_sigs ); @@ -335,7 +352,7 @@ open_db() db_fd = open( db_name, O_RDWR ); if( db_fd == -1 ) log_fatal("can't open %s: %s\n", db_name, strerror(errno) ); - if( read_record( 0, &rec ) ) + if( read_record( 0, &rec, RECTYPE_VER ) ) log_fatal("TrustDB %s is invalid\n", db_name ); /* fixme: check ->locked and other stuff */ } @@ -366,17 +383,16 @@ dump_record( ulong rnum, TRUSTREC *rec, FILE *fp ) case RECTYPE_CTL: fprintf(fp, "ctl\n"); break; case RECTYPE_SIG: - fprintf(fp, "sigrec, owner=%lu, chain=%lu%s\n", - rec->r.sig.owner, rec->r.sigrec.chain, - rec->rectype == 4?"":" (extend)"); + fprintf(fp, "sigrec, owner=%lu, chain=%lu\n", + rec->r.sig.owner, rec->r.sig.chain ); for(i=any=0; i < SIGS_PER_RECORD; i++ ) { - if( rec->r.sigrec.sig[i].local_id ) { + if( rec->r.sig.sig[i].local_id ) { if( !any ) { putc('\t', fp); any++; } - fprintf(fp, " %lu:%02x", rec->r.sigrec.sig[i].local_id, - rec->r.sigrec.sig[i].flag ); + fprintf(fp, " %lu:%02x", rec->r.sig.sig[i].local_id, + rec->r.sig.sig[i].flag ); } } if( any ) @@ -393,7 +409,7 @@ dump_record( ulong rnum, TRUSTREC *rec, FILE *fp ) * returns: -1 on error, 0 on success */ static int -read_record( ulong recnum, TRUSTREC *rec ) +read_record( ulong recnum, TRUSTREC *rec, int expected ) { byte buf[TRUST_RECORD_LEN], *p; int rc = 0; @@ -415,23 +431,26 @@ read_record( ulong recnum, TRUSTREC *rec ) } p = buf; rec->rectype = *p++; + if( expected && rec->rectype != expected ) { + log_error("%lu: read expected rec type %d, got %d\n", + recnum, expected, rec->rectype ); + return G10ERR_TRUSTDB; + } p++; switch( rec->rectype ) { case 0: /* unused record */ break; case RECTYPE_VER: /* version record */ - if( memcmp(buf+1, "g10", 3 ) { + if( memcmp(buf+1, "g10", 3 ) ) { log_error("%s: not a trustdb file\n", db_name ); rc = G10ERR_TRUSTDB; } p += 2; /* skip magic */ rec->r.ver.version = *p++; - memcpy( rec->r.ver.reserved, p, 3); p += 3; rec->r.ver.locked = buftoulong(p); p += 4; rec->r.ver.created = buftoulong(p); p += 4; rec->r.ver.modified = buftoulong(p); p += 4; rec->r.ver.validated= buftoulong(p); p += 4; - rec->r.ver.local_id_counter = buftoulong(p); p += 4; rec->r.ver.marginals_needed = *p++; rec->r.ver.completes_needed = *p++; rec->r.ver.max_cert_depth = *p++; @@ -442,7 +461,7 @@ read_record( ulong recnum, TRUSTREC *rec ) } if( rec->r.ver.version != 1 ) { log_error("%s: invalid file version %d\n", - db_name, rec->r.version.version ); + db_name, rec->r.ver.version ); rc = G10ERR_TRUSTDB; } break; @@ -467,8 +486,8 @@ read_record( ulong recnum, TRUSTREC *rec ) rec->r.dir.keyid[0] = buftou32(p); p += 4; rec->r.dir.keyid[1] = buftou32(p); p += 4; rec->r.key.pubkey_algo = *p++; p++; - memcpy( rec->r.pubkey.fingerprint, p, 20); p += 20; - rec->r.pubkey.ownertrust = *p++; + memcpy( rec->r.key.fingerprint, p, 20); p += 20; + rec->r.key.ownertrust = *p++; break; case RECTYPE_CTL: /* control record */ rec->r.ctl.owner = buftoulong(p); p += 4; @@ -508,8 +527,7 @@ write_record( ulong recnum, TRUSTREC *rec ) memset(buf, 0, TRUST_RECORD_LEN); p = buf; - *p++ = rec->rectype; - *p++ = rec->reserved; + *p++ = rec->rectype; p++; switch( rec->rectype ) { case 0: /* unused record */ break; @@ -532,9 +550,9 @@ write_record( ulong recnum, TRUSTREC *rec ) ulongtobuf(p, rec->r.key.owner); p += 4; u32tobuf(p, rec->r.key.keyid[0]); p += 4; u32tobuf(p, rec->r.key.keyid[1]); p += 4; - *p++ = rec->r.pubkey.pubkey_algo; p++; + *p++ = rec->r.key.pubkey_algo; p++; memcpy( p, rec->r.key.fingerprint, 20); p += 20; - *p++ = rec->r.pubkey.ownertrust; + *p++ = rec->r.key.ownertrust; break; case RECTYPE_CTL: /* control record */ @@ -617,18 +635,18 @@ search_record( PKT_public_cert *pkc, TRUSTREC *rec ) fingerprint = fingerprint_from_pkc( pkc, &fingerlen ); assert( fingerlen == 20 || fingerlen == 16 ); - for(recnum=1; !(rc=read_record( recnum, rec)); recnum++ ) { + for(recnum=1; !(rc=read_record( recnum, rec, 0)); recnum++ ) { if( rec->rectype != RECTYPE_DIR ) continue; if( rec->r.dir.keyid[0] == keyid[0] && rec->r.dir.keyid[1] == keyid[1]){ TRUSTREC keyrec; - if( read_record( rec->r.dir.keyrec, keyrec ) ) { + if( read_record( rec->r.dir.keyrec, &keyrec, RECTYPE_KEY ) ) { log_error("%lu: ooops: invalid dir record\n", recnum ); break; } - if( keyrec.key.pubkey_algo == pkc->pubkey_algo + if( keyrec.r.key.pubkey_algo == pkc->pubkey_algo && !memcmp(keyrec.r.key.fingerprint, fingerprint, fingerlen) ){ if( pkc->local_id && pkc->local_id != recnum ) log_error("%s: found record, but local_id from mem does " @@ -682,7 +700,7 @@ keyid_from_local_id( ulong lid, u32 *keyid ) TRUSTREC rec; int rc; - rc = read_record( lid, &rec ); + rc = read_record( lid, &rec, RECTYPE_DIR ); if( rc ) { log_error("error reading record with local_id %lu: %s\n", lid, g10_errstr(rc)); @@ -710,8 +728,6 @@ keyid_from_local_id( ulong lid, u32 *keyid ) static int walk_sigrecs( SIGREC_CONTEXT *c, int create ) { -!!!!!!FIXME!!!!!!! - int rc=0; TRUSTREC *r; ulong rnum; @@ -719,56 +735,68 @@ walk_sigrecs( SIGREC_CONTEXT *c, int create ) if( c->ctl.eof ) return -1; 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( !c->ctl.init_done ) { + c->ctl.init_done = 1; + if( !c->sigrec ) { + rc = read_record( c->local_id, r, RECTYPE_DIR ); if( rc ) { - if( rc != -1 ) - log_info("%lu: error building sigs on the fly: %s\n", - c->pubkey_id, g10_errstr(rc) ); - rc = -1; + 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 ); + if( rc ) { + if( rc != -1 ) + log_info("%lu: error building sigs on the fly: %s\n", + c->local_id, g10_errstr(rc) ); + c->ctl.eof = 1; + return rc; + } + rc = 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; + } + c->sigrec = r->r.dir.sigrec; + } + if( !c->sigrec ) { + c->ctl.eof = 1; + return -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 */ - } - if( rc ) { - log_error("scan_record(sigrec) failed: %s\n", g10_errstr(rc)); - c->ctl.eof = 1; - return rc; - } - c->ctl.index = 0; + /* 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 next record */ - if( !r->r.sigrec.chain ) { + /* read the record */ + rnum = r->r.sig.chain; + if( !rnum ) { c->ctl.eof = 1; return -1; /* return eof */ } - rnum = r->r.sigrec.chain; - rc = read_record( rnum, r ); + rc = read_record( rnum, r, RECTYPE_SIG ); if( rc ) { - log_error("error reading next sigrec: %s\n", g10_errstr(rc)); + log_error("error reading sigrec: %s\n", g10_errstr(rc)); c->ctl.eof = 1; return rc; } - if( r->r.sigrec.owner != c->pubkey_id ) { + if( r->r.sig.owner != c->local_id ) { 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.sigrec.sig[c->ctl.index++].local_id ); - c->sig_id = r->r.sigrec.sig[c->ctl.index-1].local_id; - c->sig_flag = r->r.sigrec.sig[c->ctl.index-1].flag; + } while( !r->r.sig.sig[c->ctl.index++].local_id ); + c->sig_id = r->r.sig.sig[c->ctl.index-1].local_id; + c->sig_flag = r->r.sig.sig[c->ctl.index-1].flag; return 0; } @@ -1089,7 +1117,7 @@ check_sigs( KBNODE keyblock, int *selfsig_okay ) * to the trustdb */ static int -build_sigrecs( ulong pubkeyid, int kludge ) +build_sigrecs( ulong pubkeyid ) { TRUSTREC rec, krec, rec2; PUBKEY_FIND_INFO finfo=NULL; @@ -1105,18 +1133,14 @@ build_sigrecs( ulong pubkeyid, int kludge ) log_debug("trustdb: build_sigrecs for pubkey %lu\n", (ulong)pubkeyid ); /* get the keyblock */ - if( (rc=read_record( pubkeyid, &rec )) ) { + if( (rc=read_record( pubkeyid, &rec, RECTYPE_DIR )) ) { log_error("%lu: build_sigrecs: can't read dir record\n", pubkeyid ); goto leave; } - if( kludge && rec.r.dir.no_sigs ) { - rc = -1; - goto leave; - } finfo = m_alloc_clear( sizeof *finfo ); finfo->keyid[0] = rec.r.dir.keyid[0]; finfo->keyid[1] = rec.r.dir.keyid[1]; - if( (rc=read_record( rec.r.dir.keyrec, &krec )) ) { + if( (rc=read_record( rec.r.dir.keyrec, &krec, RECTYPE_KEY )) ) { log_error("%lu: build_sigrecs: can't read key record\n", pubkeyid); goto leave; } @@ -1144,8 +1168,8 @@ build_sigrecs( ulong pubkeyid, int kludge ) 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 ); @@ -1313,13 +1337,12 @@ propagate_trust( TRUST_SEG_LIST tslist ) /**************** * we have the pubkey record but nothing more is known + * function may re-read dr. */ static int -do_check( ulong pubkeyid, unsigned *trustlevel ) +do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel ) { int i, rc=0; - ulong rnum; - TRUSTREC rec; TRUST_SEG_LIST tsl, tsl2, tslist; int marginal, fully; int fully_needed = opt.completes_needed; @@ -1333,12 +1356,14 @@ do_check( ulong pubkeyid, unsigned *trustlevel ) /* verify the cache */ /* do we have sigrecs */ - rc = scan_record( pubkeyid, &rec, 4, &rnum ); - if( rc == -1 ) { /* no sigrecs, so build them */ - rc = build_sigrecs( pubkeyid, 1 ); + if( !dr->r.dir.sigrec && !dr->r.dir.no_sigs) { + /* no sigrecs, so build them */ + rc = build_sigrecs( pubkeyid ); if( !rc ) /* and read again */ - rc = scan_record( pubkeyid, &rec, 4, &rnum ); + rc = read_record( pubkeyid, dr, RECTYPE_DIR ); } + if( !rc && !dr->r.dir.sigrec ) + rc = -1; if( rc ) return rc; /* error while looking for sigrec or building sigrecs */ @@ -1482,7 +1507,7 @@ list_trustdb( const char *username ) for(i=9+strlen(db_name); i > 0; i-- ) putchar('-'); putchar('\n'); - for(recnum=0; !read_record( recnum, &rec); recnum++ ) + for(recnum=0; !read_record( recnum, &rec, 0); recnum++ ) dump_record( recnum, &rec, stdout ); } } @@ -1550,7 +1575,7 @@ list_trust_path( int max_depth, const char *username ) release_lid_table(work); } release_lid_table(lids); - } cvs checkout -h + } if( rc ) log_error("user '%s' list problem: %s\n", username, g10_errstr(rc)); rc = propagate_trust( tslist ); @@ -1605,14 +1630,14 @@ check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel ) /* get the pubkey record */ if( pkc->local_id ) { - if( read_record( pkc->local_id, &rec ) ) { + if( read_record( pkc->local_id, &rec, RECTYPE_DIR ) ) { log_error("check_trust: read record failed\n"); return G10ERR_TRUSTDB; } } else { /* no local_id: scan the trustdb */ - if( (rc=scan_record_by_pkc( pkc, &rec, 2 )) && rc != -1 ) { - log_error("check_trust: scan_record_by_pkc(2) failed: %s\n", + if( (rc=search_record( pkc, &rec )) && rc != -1 ) { + log_error("check_trust: search_record failed: %s\n", g10_errstr(rc)); return rc; } @@ -1629,7 +1654,7 @@ check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel ) } /* fixme: do some additional checks on the pubkey record */ - rc = do_check( pkc->local_id, &trustlevel ); + rc = do_check( pkc->local_id, &rec, &trustlevel ); if( rc ) { log_error("check_trust: do_check failed: %s\n", g10_errstr(rc)); return rc; @@ -1648,7 +1673,7 @@ check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel ) /**************** * Enumerate all keys, which are needed to build all trust paths for - * the given key. This function dies not return the key itself or + * the given key. This function does not return the key itself or * the ultimate key. * * 1) create a void pointer and initialize it to NULL @@ -1700,12 +1725,16 @@ get_ownertrust( ulong lid, unsigned *r_otrust ) { TRUSTREC rec; - if( read_record( lid, &rec ) ) { - log_error("get_ownertrust: read record failed\n"); + if( read_record( lid, &rec, RECTYPE_DIR ) ) { + log_error("get_ownertrust: read dir record failed\n"); + return G10ERR_TRUSTDB; + } + if( 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.pubkey.ownertrust; + *r_otrust = rec.r.key.ownertrust; return 0; } @@ -1714,18 +1743,25 @@ keyid_from_trustdb( ulong lid, u32 *keyid ) { TRUSTREC rec; - if( read_record( lid, &rec ) ) { + if( read_record( lid, &rec, RECTYPE_DIR ) ) { log_error("keyid_from_trustdb: read record failed\n"); return G10ERR_TRUSTDB; } if( keyid ) { - keyid[0] = rec.r.pubkey.keyid[0]; - keyid[1] = rec.r.pubkey.keyid[1]; + keyid[0] = rec.r.dir.keyid[0]; + keyid[1] = rec.r.dir.keyid[1]; } return 0; } +/**************** + * This function simply looks for the key in the trustdb + * and sets PKC->local_id. + * Return: 0 = found + * -1 = not found + * other = error + */ int query_trust_record( PKT_public_cert *pkc ) { @@ -1733,21 +1769,19 @@ query_trust_record( PKT_public_cert *pkc ) int rc=0; if( pkc->local_id ) { - if( read_record( pkc->local_id, &rec ) ) { + if( read_record( pkc->local_id, &rec, RECTYPE_DIR ) ) { log_error("query_trust_record: read record failed\n"); return G10ERR_TRUSTDB; } } else { /* no local_id: scan the trustdb */ - if( (rc=scan_record_by_pkc( pkc, &rec, 2 )) && rc != -1 ) { - log_error("query_trust_record: scan_record_by_pkc(2) failed: %s\n", + if( (rc=search_record( pkc, &rec )) && rc != -1 ) { + log_error("query_trust_record: search_record failed: %s\n", g10_errstr(rc)); return rc; } - else if( rc == -1 ) - return rc; } - return 0; + return rc; } @@ -1760,7 +1794,7 @@ insert_trust_record( PKT_public_cert *pkc ) { TRUSTREC rec; u32 keyid[2]; - ulong recnum; + ulong knum, dnum; byte *fingerprint; size_t fingerlen; @@ -1773,23 +1807,35 @@ insert_trust_record( PKT_public_cert *pkc ) /* FIXME: check that we do not have this record. */ - recnum = new_recnum(); - /* build record */ + dnum = new_recnum(); + knum = new_recnum(); + /* build dir record */ memset( &rec, 0, sizeof rec ); - rec.rectype = 2; /* the pubkey record */ - rec.r.pubkey.local_id = recnum; - rec.r.pubkey.keyid[0] = keyid[0]; - rec.r.pubkey.keyid[1] = keyid[1]; - 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"); + rec.rectype = RECTYPE_DIR; + rec.r.dir.local_id = dnum; + rec.r.dir.keyid[0] = keyid[0]; + rec.r.dir.keyid[1] = keyid[1]; + rec.r.dir.keyrec = knum; + rec.r.dir.no_sigs = 0; + if( write_record( dnum, &rec ) ) { + log_error("writing dir record failed\n"); + return G10ERR_TRUSTDB; + } + /* and the key record */ + memset( &rec, 0, sizeof rec ); + rec.rectype = RECTYPE_KEY; + rec.r.key.owner = dnum; + rec.r.key.keyid[0] = keyid[0]; + rec.r.key.keyid[1] = keyid[1]; + rec.r.key.pubkey_algo = pkc->pubkey_algo; + memcpy(rec.r.key.fingerprint, fingerprint, fingerlen ); + rec.r.key.ownertrust = 0; + if( write_record( knum, &rec ) ) { + log_error("wrinting key record failed\n"); return G10ERR_TRUSTDB; } - pkc->local_id = recnum; + pkc->local_id = dnum; return 0; } @@ -1799,19 +1845,21 @@ int update_ownertrust( ulong lid, unsigned new_trust ) { TRUSTREC rec; + ulong recnum; - if( read_record( lid, &rec ) ) { - log_error("update_ownertrust: read failed\n"); + if( read_record( lid, &rec, RECTYPE_DIR ) ) { + log_error("update_ownertrust: read dir failed\n"); + return G10ERR_TRUSTDB; + } + recnum = rec.r.dir.keyrec; + if( read_record( recnum, &rec, RECTYPE_KEY ) ) { + log_error("update_ownertrust: read key failed\n"); return G10ERR_TRUSTDB; } /* check keyid, fingerprint etc ? */ - if( rec.rectype != 2 ) { - log_error("update_ownertrust: invalid record type\n"); - return G10ERR_TRUSTDB; - } - rec.r.pubkey.ownertrust = new_trust; - if( write_record( lid, &rec ) ) { + rec.r.key.ownertrust = new_trust; + if( write_record( recnum, &rec ) ) { log_error("update_ownertrust: write failed\n"); return G10ERR_TRUSTDB; } @@ -1830,17 +1878,12 @@ update_no_sigs( ulong lid, int no_sigs ) { TRUSTREC rec; - if( read_record( lid, &rec ) ) { + if( read_record( lid, &rec, RECTYPE_DIR ) ) { 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; + rec.r.dir.no_sigs = !!no_sigs; if( write_record( lid, &rec ) ) { log_error("update_no_sigs: write failed\n"); return G10ERR_TRUSTDB;