release 0.2.3
[gnupg.git] / g10 / trustdb.c
1 /* trustdb.c
2  *      Copyright (c) 1997 by Werner Koch (dd9jn)
3  *
4  * This file is part of G10.
5  *
6  * G10 is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * G10 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <fcntl.h>
29
30 #include "errors.h"
31 #include "iobuf.h"
32 #include "keydb.h"
33 #include "memory.h"
34 #include "util.h"
35 #include "trustdb.h"
36 #include "options.h"
37 #include "packet.h"
38 #include "main.h"
39
40
41 #define TRUST_RECORD_LEN 40
42 #define SIGS_PER_RECORD         ((TRUST_RECORD_LEN-10)/5)
43 #define ITEMS_PER_HTBL_RECORD   ((TRUST_RECORD_LEN-2)/4)
44 #define ITEMS_PER_HLST_RECORD   ((TRUST_RECORD_LEN-6)/5)
45 #define MAX_LIST_SIGS_DEPTH  20
46
47
48 #define RECTYPE_VER  1
49 #define RECTYPE_DIR  2
50 #define RECTYPE_KEY  3
51 #define RECTYPE_CTL  4
52 #define RECTYPE_SIG  5
53 #define RECTYPE_HTBL 6
54 #define RECTYPE_HLST 7
55
56
57 struct trust_record {
58     int  rectype;
59     union {
60         struct {            /* version record: */
61             byte version;   /* should be 1 */
62             ulong locked;    /* pid of process which holds a lock */
63             ulong created;   /* timestamp of trustdb creation  */
64             ulong modified;  /* timestamp of last modification */
65             ulong validated; /* timestamp of last validation   */
66             byte marginals_needed;
67             byte completes_needed;
68             byte max_cert_depth;
69         } ver;
70         struct {            /* directory record */
71             ulong local_id;
72             u32  keyid[2];
73             ulong keyrec;   /* recno of public key record */
74             ulong ctlrec;   /* recno of control record */
75             ulong sigrec;   /* recno of first signature record */
76             ulong link;     /* to next dir record */
77             byte no_sigs;   /* does not have sigature and checked */
78         } dir;
79         struct {            /* public key record */
80             ulong owner;
81             u32  keyid[2];
82             byte pubkey_algo;
83             byte fingerprint[20];
84             byte ownertrust;
85         } key;
86         struct {            /* control record */
87             ulong owner;
88             byte blockhash[20];
89             byte trustlevel;   /* calculated trustlevel */
90         } ctl;
91         struct {            /* signature record */
92             ulong owner;  /* local_id of record owner (pubkey record) */
93             ulong chain;  /* offset of next record or NULL for last one */
94             struct {
95                 ulong  local_id; /* of pubkey record of signator (0=unused) */
96                 byte flag;     /* reserved */
97             } sig[SIGS_PER_RECORD];
98         } sig;
99         struct {
100             ulong item[ITEMS_PER_HTBL_RECORD];
101         } htbl;
102         struct {
103             ulong chain;
104             struct {
105                 byte hash;
106                 ulong rnum;
107             } item[ITEMS_PER_HLST_RECORD];
108         } hlst;
109     } r;
110 };
111 typedef struct trust_record TRUSTREC;
112
113 typedef struct {
114     ulong     local_id;    /* localid of the pubkey */
115     ulong     sigrec;
116     ulong     sig_id;      /* returned signature id */
117     unsigned  sig_flag;    /* returned signature record flag */
118     struct {               /* internal data */
119         int init_done;
120         int eof;
121         TRUSTREC rec;
122         int index;
123     } ctl;
124 } SIGREC_CONTEXT;
125
126 typedef struct local_id_info *LOCAL_ID_INFO;
127 struct local_id_info {
128     LOCAL_ID_INFO next;
129     ulong lid;
130     unsigned flag;
131 };
132
133
134 typedef struct trust_info TRUST_INFO;
135 struct trust_info {
136     ulong    lid;
137     unsigned trust;
138 };
139
140
141 typedef struct trust_seg_list *TRUST_SEG_LIST;
142 struct trust_seg_list {
143     TRUST_SEG_LIST next;
144     int   nseg;     /* number of segmens */
145     int   dup;
146     TRUST_INFO seg[1];   /* segment list */
147 };
148
149
150 typedef struct {
151     TRUST_SEG_LIST tsl;
152     int index;
153 } ENUM_TRUST_WEB_CONTEXT;
154
155
156 static void create_db( const char *fname );
157 static void open_db(void);
158 static void dump_record( ulong rnum, TRUSTREC *rec, FILE *fp );
159 static int  read_record( ulong recnum, TRUSTREC *rec, int expected );
160 static int  write_record( ulong recnum, TRUSTREC *rec );
161 static ulong new_recnum(void);
162 static int search_record( PKT_public_cert *pkc, TRUSTREC *rec );
163 static int walk_sigrecs( SIGREC_CONTEXT *c, int create );
164
165 static LOCAL_ID_INFO *new_lid_table(void);
166 static void release_lid_table( LOCAL_ID_INFO *tbl );
167 static int ins_lid_table_item( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
168 static int qry_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned *flag );
169 static void upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
170
171 static void print_user_id( const char *text, u32 *keyid );
172 static int do_list_path( TRUST_INFO *stack, int depth, int max_depth,
173                          LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist );
174
175 static int list_sigs( ulong pubkey_id );
176 static int build_sigrecs( ulong pubkeyid );
177 static int propagate_trust( TRUST_SEG_LIST tslist );
178 static int do_check( ulong pubkeyid, TRUSTREC *drec, unsigned *trustlevel );
179
180 static int update_no_sigs( ulong lid, int no_sigs );
181
182 static char *db_name;
183 static int  db_fd = -1;
184 /* a table used to keep track of ultimately trusted keys
185  * which are the ones from our secrings */
186 static LOCAL_ID_INFO *ultikey_table;
187
188 static ulong last_trust_web_key;
189 static TRUST_SEG_LIST last_trust_web_tslist;
190
191 #define buftoulong( p )  ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
192                        (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
193 #define buftoushort( p )  ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
194 #define ulongtobuf( p, a ) do {                           \
195                             ((byte*)p)[0] = a >> 24;    \
196                             ((byte*)p)[1] = a >> 16;    \
197                             ((byte*)p)[2] = a >>  8;    \
198                             ((byte*)p)[3] = a      ;    \
199                         } while(0)
200 #define ushorttobuf( p, a ) do {                           \
201                             ((byte*)p)[0] = a >>  8;    \
202                             ((byte*)p)[1] = a      ;    \
203                         } while(0)
204 #define buftou32( p)    buftoulong( (p) )
205 #define u32tobuf( p, a) ulongtobuf( (p), (a) )
206
207
208 /**************************************************
209  ************** read and write helpers ************
210  **************************************************/
211
212 static void
213 fwrite_8(FILE *fp, byte a)
214 {
215     if( putc( a & 0xff, fp ) == EOF )
216         log_fatal("error writing byte to trustdb: %s\n", strerror(errno) );
217 }
218
219
220 static void
221 fwrite_32( FILE*fp, ulong a)
222 {
223     putc( (a>>24) & 0xff, fp );
224     putc( (a>>16) & 0xff, fp );
225     putc( (a>> 8) & 0xff, fp );
226     if( putc( a & 0xff, fp ) == EOF )
227         log_fatal("error writing ulong to trustdb: %s\n", strerror(errno) );
228 }
229
230 static void
231 fwrite_zeros( FILE *fp, size_t n)
232 {
233     while( n-- )
234         if( putc( 0, fp ) == EOF )
235             log_fatal("error writing zeros to trustdb: %s\n", strerror(errno) );
236 }
237
238
239 /**********************************************
240  ************* list helpers *******************
241  **********************************************/
242
243 static LOCAL_ID_INFO *
244 new_lid_table(void)
245 {
246     return m_alloc_clear( 16 * sizeof(LOCAL_ID_INFO));
247 }
248
249 static void
250 release_lid_table( LOCAL_ID_INFO *tbl )
251 {
252     LOCAL_ID_INFO a, a2;
253     int i;
254
255     for(i=0; i < 16; i++ ) {
256         for(a=tbl[i]; a; a = a2 ) {
257             a2 = a->next;
258             m_free(a);
259         }
260     }
261     m_free(tbl);
262 }
263
264 /****************
265  * Add a new item to the table or return 1 if we already have this item
266  * fixme: maybe its a good idea to take items from an unused item list.
267  */
268 static int
269 ins_lid_table_item( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag )
270 {
271     LOCAL_ID_INFO a;
272
273     for( a = tbl[lid & 0x0f]; a; a = a->next )
274         if( a->lid == lid )
275             return 1;
276     a = m_alloc( sizeof *a );
277     a->lid = lid;
278     a->flag = flag;
279     a->next = tbl[lid & 0x0f];
280     tbl[lid & 0x0f] = a;
281     return 0;
282 }
283
284 static int
285 qry_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned *flag )
286 {
287     LOCAL_ID_INFO a;
288
289     for( a = tbl[lid & 0x0f]; a; a = a->next )
290         if( a->lid == lid ) {
291             if( flag )
292                 *flag = a->flag;
293             return 0;
294         }
295     return -1;
296 }
297
298 static void
299 upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag )
300 {
301     LOCAL_ID_INFO a;
302
303     for( a = tbl[lid & 0x0f]; a; a = a->next )
304         if( a->lid == lid ) {
305             a->flag = flag;
306             return;
307         }
308     BUG();
309 }
310
311
312 /**************************************************
313  ************** read and write stuff **************
314  **************************************************/
315
316
317 /****************
318  * Create a new trustdb
319  */
320 static void
321 create_db( const char *fname )
322 {
323     FILE *fp;
324
325     fp =fopen( fname, "w" );
326     if( !fp )
327         log_fatal("can't create %s: %s\n", fname, strerror(errno) );
328     fwrite_8( fp, 1 );
329     fwrite_8( fp, 'g' );
330     fwrite_8( fp, '1' );
331     fwrite_8( fp, '0' );
332     fwrite_8( fp, 1 );  /* version */
333     fwrite_zeros( fp, 3 ); /* reserved */
334     fwrite_32( fp, 0 ); /* not locked */
335     fwrite_32( fp, make_timestamp() ); /* created */
336     fwrite_32( fp, 0 ); /* not yet modified */
337     fwrite_32( fp, 0 ); /* not yet validated*/
338     fwrite_32( fp, 0 ); /* reserved */
339     fwrite_8( fp, 3 );  /* marginals needed */
340     fwrite_8( fp, 1 );  /* completes needed */
341     fwrite_8( fp, 4 );  /* max_cet_depth */
342     fwrite_zeros( fp, 9 ); /* filler */
343     fclose(fp);
344 }
345
346 static void
347 open_db()
348 {
349     TRUSTREC rec;
350     assert( db_fd == -1 );
351
352     db_fd = open( db_name, O_RDWR );
353     if( db_fd == -1 )
354         log_fatal("can't open %s: %s\n", db_name, strerror(errno) );
355     if( read_record( 0, &rec, RECTYPE_VER ) )
356         log_fatal("TrustDB %s is invalid\n", db_name );
357     /* fixme: check ->locked and other stuff */
358 }
359
360
361 static void
362 dump_record( ulong rnum, TRUSTREC *rec, FILE *fp  )
363 {
364     int i, any;
365
366     fprintf(fp, "trust record %lu, type=", rnum );
367
368     switch( rec->rectype ) {
369       case 0: fprintf(fp, "free\n");
370         break;
371       case RECTYPE_VER: fprintf(fp, "version\n");
372         break;
373       case RECTYPE_DIR:
374         fprintf(fp, "dir keyid=%08lX, key=%lu, ctl=%lu, sig=%lu",
375                     (ulong)rec->r.dir.keyid[1],
376                     rec->r.dir.keyrec, rec->r.dir.ctlrec, rec->r.dir.sigrec );
377         if( rec->r.dir.no_sigs == 1 )
378             fputs(", (none)", fp );
379         else if( rec->r.dir.no_sigs == 2 )
380             fputs(", (invalid)", fp );
381         else if( rec->r.dir.no_sigs )
382             fputs(", (revoked)", fp );
383         putc('\n', fp);
384         break;
385       case RECTYPE_KEY: fprintf(fp, "key keyid=%08lX, own=%lu, ownertrust=%02x\n",
386                    (ulong)rec->r.key.keyid[1],
387                    rec->r.key.owner, rec->r.key.ownertrust );
388         break;
389       case RECTYPE_CTL: fprintf(fp, "ctl\n");
390         break;
391       case RECTYPE_SIG:
392         fprintf(fp, "sigrec, owner=%lu, chain=%lu\n",
393                          rec->r.sig.owner, rec->r.sig.chain );
394         for(i=any=0; i < SIGS_PER_RECORD; i++ ) {
395             if( rec->r.sig.sig[i].local_id ) {
396                 if( !any ) {
397                     putc('\t', fp);
398                     any++;
399                 }
400                 fprintf(fp, "  %lu:%02x", rec->r.sig.sig[i].local_id,
401                                               rec->r.sig.sig[i].flag );
402             }
403         }
404         if( any )
405             putc('\n', fp);
406         break;
407       default:
408         fprintf(fp, "%d (unknown)\n", rec->rectype );
409         break;
410     }
411 }
412
413 /****************
414  * read the record with number recnum
415  * returns: -1 on error, 0 on success
416  */
417 static int
418 read_record( ulong recnum, TRUSTREC *rec, int expected )
419 {
420     byte buf[TRUST_RECORD_LEN], *p;
421     int rc = 0;
422     int n, i;
423
424     if( db_fd == -1 )
425         open_db();
426     if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
427         log_error("trustdb: lseek failed: %s\n", strerror(errno) );
428         return G10ERR_READ_FILE;
429     }
430     n = read( db_fd, buf, TRUST_RECORD_LEN);
431     if( !n ) {
432         return -1; /* eof */
433     }
434     else if( n != TRUST_RECORD_LEN ) {
435         log_error("trustdb: read failed (n=%d): %s\n", n, strerror(errno) );
436         return G10ERR_READ_FILE;
437     }
438     p = buf;
439     rec->rectype = *p++;
440     if( expected && rec->rectype != expected ) {
441         log_error("%lu: read expected rec type %d, got %d\n",
442                     recnum, expected, rec->rectype );
443         return G10ERR_TRUSTDB;
444     }
445     p++;
446     switch( rec->rectype ) {
447       case 0:  /* unused record */
448         break;
449       case RECTYPE_VER: /* version record */
450         if( memcmp(buf+1, "g10", 3 ) ) {
451             log_error("%s: not a trustdb file\n", db_name );
452             rc = G10ERR_TRUSTDB;
453         }
454         p += 2; /* skip magic */
455         rec->r.ver.version  = *p++;
456         rec->r.ver.locked   = buftoulong(p); p += 4;
457         rec->r.ver.created  = buftoulong(p); p += 4;
458         rec->r.ver.modified = buftoulong(p); p += 4;
459         rec->r.ver.validated= buftoulong(p); p += 4;
460         rec->r.ver.marginals_needed = *p++;
461         rec->r.ver.completes_needed = *p++;
462         rec->r.ver.max_cert_depth = *p++;
463         if( recnum ) {
464             log_error("%s: version record with recnum %lu\n",
465                                                     db_name, (ulong)recnum );
466             rc = G10ERR_TRUSTDB;
467         }
468         if( rec->r.ver.version != 1 ) {
469             log_error("%s: invalid file version %d\n",
470                                        db_name, rec->r.ver.version );
471             rc = G10ERR_TRUSTDB;
472         }
473         break;
474       case RECTYPE_DIR:   /*directory record */
475         rec->r.dir.local_id = buftoulong(p); p += 4;
476         rec->r.dir.keyid[0] = buftou32(p); p += 4;
477         rec->r.dir.keyid[1] = buftou32(p); p += 4;
478         rec->r.dir.keyrec   = buftoulong(p); p += 4;
479         rec->r.dir.ctlrec   = buftoulong(p); p += 4;
480         rec->r.dir.sigrec   = buftoulong(p); p += 4;
481         rec->r.dir.no_sigs = *p++;
482         if( rec->r.dir.local_id != recnum ) {
483             log_error("%s: dir local_id != recnum (%lu,%lu)\n",
484                                         db_name,
485                                         (ulong)rec->r.dir.local_id,
486                                         (ulong)recnum );
487             rc = G10ERR_TRUSTDB;
488         }
489         break;
490       case RECTYPE_KEY:   /* public key record */
491         rec->r.key.owner    = buftoulong(p); p += 4;
492         rec->r.dir.keyid[0] = buftou32(p); p += 4;
493         rec->r.dir.keyid[1] = buftou32(p); p += 4;
494         rec->r.key.pubkey_algo = *p++; p++;
495         memcpy( rec->r.key.fingerprint, p, 20); p += 20;
496         rec->r.key.ownertrust = *p++;
497         break;
498       case RECTYPE_CTL:   /* control record */
499         rec->r.ctl.owner    = buftoulong(p); p += 4;
500         memcpy(rec->r.ctl.blockhash, p, 20); p += 20;
501         rec->r.ctl.trustlevel = *p++;
502         break;
503       case RECTYPE_SIG:
504         rec->r.sig.owner   = buftoulong(p); p += 4;
505         rec->r.sig.chain   = buftoulong(p); p += 4;
506         for(i=0; i < SIGS_PER_RECORD; i++ ) {
507             rec->r.sig.sig[i].local_id = buftoulong(p); p += 4;
508             rec->r.sig.sig[i].flag = *p++;
509         }
510         break;
511       default:
512         log_error("%s: invalid record type %d at recnum %lu\n",
513                                         db_name, rec->rectype, (ulong)recnum );
514         rc = G10ERR_TRUSTDB;
515         break;
516     }
517
518     return rc;
519 }
520
521 /****************
522  * Write the record at RECNUM
523  */
524 static int
525 write_record( ulong recnum, TRUSTREC *rec )
526 {
527     byte buf[TRUST_RECORD_LEN], *p;
528     int rc = 0;
529     int i, n;
530
531     if( db_fd == -1 )
532         open_db();
533
534     memset(buf, 0, TRUST_RECORD_LEN);
535     p = buf;
536     *p++ = rec->rectype; p++;
537     switch( rec->rectype ) {
538       case 0:  /* unused record */
539         break;
540       case 1: /* version record */
541         BUG();
542         break;
543
544       case RECTYPE_DIR:   /*directory record */
545         ulongtobuf(p, rec->r.dir.local_id); p += 4;
546         u32tobuf(p, rec->r.key.keyid[0]); p += 4;
547         u32tobuf(p, rec->r.key.keyid[1]); p += 4;
548         ulongtobuf(p, rec->r.dir.keyrec); p += 4;
549         ulongtobuf(p, rec->r.dir.ctlrec); p += 4;
550         ulongtobuf(p, rec->r.dir.sigrec); p += 4;
551         *p++ = rec->r.dir.no_sigs;
552         assert( rec->r.dir.local_id == recnum );
553         break;
554
555       case RECTYPE_KEY:
556         ulongtobuf(p, rec->r.key.owner); p += 4;
557         u32tobuf(p, rec->r.key.keyid[0]); p += 4;
558         u32tobuf(p, rec->r.key.keyid[1]); p += 4;
559         *p++ = rec->r.key.pubkey_algo; p++;
560         memcpy( p, rec->r.key.fingerprint, 20); p += 20;
561         *p++ = rec->r.key.ownertrust;
562         break;
563
564       case RECTYPE_CTL:   /* control record */
565         ulongtobuf(p, rec->r.ctl.owner); p += 4;
566         memcpy(p, rec->r.ctl.blockhash, 20); p += 20;
567         *p++ = rec->r.ctl.trustlevel;
568         break;
569
570       case RECTYPE_SIG:
571         ulongtobuf(p, rec->r.sig.owner); p += 4;
572         ulongtobuf(p, rec->r.sig.chain); p += 4;
573         for(i=0; i < SIGS_PER_RECORD; i++ ) {
574             ulongtobuf(p, rec->r.sig.sig[i].local_id); p += 4;
575             *p++ = rec->r.sig.sig[i].flag;
576         }
577         break;
578       default:
579         BUG();
580     }
581
582     if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
583         log_error("trustdb: lseek failed: %s\n", strerror(errno) );
584         return G10ERR_WRITE_FILE;
585     }
586     n = write( db_fd, buf, TRUST_RECORD_LEN);
587     if( n != TRUST_RECORD_LEN ) {
588         log_error("trustdb: write failed (n=%d): %s\n", n, strerror(errno) );
589         return G10ERR_WRITE_FILE;
590     }
591
592     return rc;
593 }
594
595
596 /****************
597  * create a new record and return its record number
598  */
599 static ulong
600 new_recnum()
601 {
602     off_t offset;
603     ulong recnum;
604     TRUSTREC rec;
605     int rc;
606
607     /* fixme: look for unused records */
608     offset = lseek( db_fd, 0, SEEK_END );
609     if( offset == -1 )
610         log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) );
611     recnum = offset / TRUST_RECORD_LEN;
612     assert(recnum); /* this is will never be the first record */
613
614     /* we must write a record, so that the next call to this function
615      * returns another recnum */
616     memset( &rec, 0, sizeof rec );
617     rec.rectype = 0; /* free record */
618     rc = write_record(recnum, &rec );
619     if( rc )
620         log_fatal("%s: failed to append a record: %s\n",
621                                             db_name, g10_errstr(rc));
622     return recnum ;
623 }
624
625 /****************
626  * Search the trustdb for a key which matches PKC and return the dir record
627  * The local_id of PKC is set to the correct value
628  *
629  * Note: To increase performance, we could use a index search here.
630  */
631 static int
632 search_record( PKT_public_cert *pkc, TRUSTREC *rec )
633 {
634     ulong recnum;
635     u32 keyid[2];
636     byte *fingerprint;
637     size_t fingerlen;
638     int rc;
639
640     keyid_from_pkc( pkc, keyid );
641     fingerprint = fingerprint_from_pkc( pkc, &fingerlen );
642     assert( fingerlen == 20 || fingerlen == 16 );
643
644     for(recnum=1; !(rc=read_record( recnum, rec, 0)); recnum++ ) {
645         if( rec->rectype != RECTYPE_DIR )
646             continue;
647         if( rec->r.dir.keyid[0] == keyid[0]
648             && rec->r.dir.keyid[1] == keyid[1]){
649             TRUSTREC keyrec;
650
651             if( read_record( rec->r.dir.keyrec, &keyrec, RECTYPE_KEY ) ) {
652                 log_error("%lu: ooops: invalid key record\n", recnum );
653                 break;
654             }
655             if( keyrec.r.key.pubkey_algo == pkc->pubkey_algo
656                 && !memcmp(keyrec.r.key.fingerprint, fingerprint, fingerlen) ){
657                 if( pkc->local_id && pkc->local_id != recnum )
658                     log_error("%s: found record, but local_id from mem does "
659                                "not match recnum (%lu,%lu)\n", db_name,
660                                      (ulong)pkc->local_id, (ulong)recnum );
661                 pkc->local_id = recnum;
662                 return 0;
663             }
664         }
665     }
666     if( rc != -1 )
667         log_error("%s: search_db failed: %s\n",db_name, g10_errstr(rc) );
668     return rc;
669 }
670
671
672 /****************
673  * If we do not have a local_id in a signature packet, find the owner of
674  * the signature packet in our trustdb or insert him into the trustdb
675  */
676 static int
677 set_signature_packets_local_id( PKT_signature *sig )
678 {
679     PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
680     TRUSTREC rec;
681     int rc;
682
683     rc = get_pubkey( pkc, sig->keyid );
684     if( rc)
685         goto leave;
686     if( !pkc->local_id ) {
687         rc = search_record( pkc, &rec );
688         if( rc == -1 )
689             rc = insert_trust_record( pkc );
690         if( rc )
691             goto leave;
692         /* fixme: we should propagate the local_id to all copies of the PKC */
693     }
694     sig->local_id = pkc->local_id;
695
696   leave:
697     free_public_cert( pkc );
698     return rc;
699 }
700
701
702
703 static int
704 keyid_from_local_id( ulong lid, u32 *keyid )
705 {
706     TRUSTREC rec;
707     int rc;
708
709     rc = read_record( lid, &rec, RECTYPE_DIR );
710     if( rc ) {
711         log_error("error reading record with local_id %lu: %s\n",
712                                                     lid, g10_errstr(rc));
713         return G10ERR_TRUSTDB;
714     }
715     if( rec.rectype != RECTYPE_DIR ) {
716         log_error("record with local_id %lu is not a dir record\n", lid);
717         return G10ERR_TRUSTDB;
718     }
719     keyid[0] = rec.r.dir.keyid[0];
720     keyid[1] = rec.r.dir.keyid[1];
721     return 0;
722 }
723
724 /****************
725  * Walk throug the signatures of a public key.
726  * The caller must provide a context structure, with all fields set
727  * to zero, but the local_id field set to the requested key;
728  * This function does not change this field.  On return the context
729  * is filled with the local-id of the signature and the signature flag.
730  * No fields should be changed (clearing all fields and setting
731  * pubkeyid is okay to continue with an other pubkey)
732  * Returns: 0 - okay, -1 for eof (no more sigs) or any other errorcode
733  */
734 static int
735 walk_sigrecs( SIGREC_CONTEXT *c, int create )
736 {
737     int rc=0;
738     TRUSTREC *r;
739     ulong rnum;
740
741     if( c->ctl.eof )
742         return -1;
743     r = &c->ctl.rec;
744     if( !c->ctl.init_done ) {
745         c->ctl.init_done = 1;
746         if( !c->sigrec ) {
747             rc = read_record( c->local_id, r, RECTYPE_DIR );
748             if( rc ) {
749                 log_error("%lu: error reading dir record: %s\n",
750                                         c->local_id, g10_errstr(rc));
751                 return rc;
752             }
753             c->sigrec = r->r.dir.sigrec;
754             if( !c->sigrec && create && !r->r.dir.no_sigs ) {
755                 rc = build_sigrecs( c->local_id );
756                 if( rc ) {
757                     if( rc == G10ERR_BAD_CERT )
758                         rc = -1;  /* maybe no selcficnature */
759                     if( rc != -1 )
760                         log_info("%lu: error building sigs on the fly: %s\n",
761                                c->local_id, g10_errstr(rc) );
762                     c->ctl.eof = 1;
763                     return rc;
764                 }
765                 rc = read_record( c->local_id, r, RECTYPE_DIR );
766                 if( rc ) {
767                     log_error("%lu: error re-reading dir record: %s\n",
768                                             c->local_id, g10_errstr(rc));
769                     return rc;
770                 }
771                 c->sigrec = r->r.dir.sigrec;
772             }
773             if( !c->sigrec ) {
774                 c->ctl.eof = 1;
775                 return -1;
776             }
777         }
778         /* force a read */
779         c->ctl.index = SIGS_PER_RECORD;
780         r->r.sig.chain = c->sigrec;
781     }
782
783     /* enter loop to skip deleted sigs */
784     do {
785         if( c->ctl.index >= SIGS_PER_RECORD ) {
786             /* read the record */
787             rnum = r->r.sig.chain;
788             if( !rnum ) {
789                 c->ctl.eof = 1;
790                 return -1;  /* return eof */
791             }
792             rc = read_record( rnum, r, RECTYPE_SIG );
793             if( rc ) {
794                 log_error("error reading sigrec: %s\n", g10_errstr(rc));
795                 c->ctl.eof = 1;
796                 return rc;
797             }
798             if( r->r.sig.owner != c->local_id ) {
799                 log_error("chained sigrec %lu has a wrong owner\n", rnum );
800                 c->ctl.eof = 1;
801                 return G10ERR_TRUSTDB;
802             }
803             c->ctl.index = 0;
804         }
805     } while( !r->r.sig.sig[c->ctl.index++].local_id );
806     c->sig_id = r->r.sig.sig[c->ctl.index-1].local_id;
807     c->sig_flag = r->r.sig.sig[c->ctl.index-1].flag;
808     return 0;
809 }
810
811
812
813
814 /***********************************************
815  *************  Trust  stuff  ******************
816  ***********************************************/
817
818
819 /****************
820  * Verify, that all our public keys are in the trustDB.
821  */
822 static int
823 verify_own_certs()
824 {
825     int rc;
826     void *enum_context = NULL;
827     PKT_secret_cert *skc = m_alloc_clear( sizeof *skc );
828     PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
829     u32 keyid[2];
830
831     while( !(rc=enum_secret_keys( &enum_context, skc) ) ) {
832         /* fixed: to be sure that it is a secret key of our own,
833          *        we should check it, but this needs a passphrase
834          *        for every key and this boring for the user.
835          *        Solution:  Sign the secring and the trustring
836          *                   and verify this signature during
837          *                   startup
838          */
839
840         keyid_from_skc( skc, keyid );
841
842         if( DBG_TRUST )
843             log_debug("checking secret key %08lX\n", (ulong)keyid[1] );
844
845         /* look wether we can access the public key of this secret key */
846         rc = get_pubkey( pkc, keyid );
847         if( rc ) {
848             log_error("keyid %08lX: secret key without public key\n",
849                                                             (ulong)keyid[1] );
850             goto leave;
851         }
852         if( cmp_public_secret_cert( pkc, skc ) ) {
853             log_error("keyid %08lX: secret and public key don't match\n",
854                                                             (ulong)keyid[1] );
855             rc = G10ERR_GENERAL;
856             goto leave;
857         }
858
859         /* make sure that the pubkey is in the trustdb */
860         rc = query_trust_record( pkc );
861         if( rc == -1 ) { /* put it into the trustdb */
862             rc = insert_trust_record( pkc );
863             if( rc ) {
864                 log_error("keyid %08lX: can't put it into the trustdb\n",
865                                                             (ulong)keyid[1] );
866                 goto leave;
867             }
868         }
869         else if( rc ) {
870             log_error("keyid %08lX: query record failed\n", (ulong)keyid[1] );
871             goto leave;
872
873         }
874
875         if( DBG_TRUST )
876             log_debug("putting %08lX(%lu) into ultikey_table\n",
877                                     (ulong)keyid[1], pkc->local_id );
878         if( ins_lid_table_item( ultikey_table, pkc->local_id, 0 ) )
879             log_error("keyid %08lX: already in ultikey_table\n",
880                                                         (ulong)keyid[1]);
881
882
883         release_secret_cert_parts( skc );
884         release_public_cert_parts( pkc );
885     }
886     if( rc != -1 )
887         log_error("enum_secret_keys failed: %s\n", g10_errstr(rc) );
888     else
889         rc = 0;
890
891   leave:
892     free_secret_cert( skc );
893     free_public_cert( pkc );
894     return rc;
895 }
896
897
898 static void
899 print_user_id( const char *text, u32 *keyid )
900 {
901     char *p;
902     size_t n;
903
904     p = get_user_id( keyid, &n );
905     if( *text ) {
906         fputs( text, stdout);
907         putchar(' ');
908     }
909     putchar('\"');
910     print_string( stdout, p, n );
911     putchar('\"');
912     putchar('\n');
913     m_free(p);
914 }
915
916 /* (a non-recursive algorithm would be easier) */
917 static int
918 do_list_sigs( ulong root, ulong pubkey, int depth,
919               LOCAL_ID_INFO *lids, unsigned *lineno )
920 {
921     SIGREC_CONTEXT sx;
922     int rc;
923     u32 keyid[2];
924
925     memset( &sx, 0, sizeof sx );
926     sx.local_id = pubkey;
927     for(;;) {
928         rc = walk_sigrecs( &sx, 0 );
929         if( rc )
930             break;
931         rc = keyid_from_local_id( sx.sig_id, keyid );
932         if( rc ) {
933             printf("%6u: %*s????????(%lu:%02x)\n", *lineno, depth*4, "",
934                                                    sx.sig_id, sx.sig_flag );
935             ++*lineno;
936         }
937         else {
938             printf("%6u: %*s%08lX(%lu:%02x) ", *lineno, depth*4, "",
939                               (ulong)keyid[1], sx.sig_id, sx.sig_flag );
940             /* check wether we already checked this pubkey */
941             if( !qry_lid_table_flag( ultikey_table, sx.sig_id, NULL ) ) {
942                 print_user_id("[ultimately trusted]", keyid);
943                 ++*lineno;
944             }
945             else if( sx.sig_id == pubkey ) {
946                 printf("[self-signature]\n");
947                 ++*lineno;
948             }
949             else if( sx.sig_id == root ) {
950                 printf("[closed]\n");
951                 ++*lineno;
952             }
953             else if( ins_lid_table_item( lids, sx.sig_id, *lineno ) ) {
954                 unsigned refline;
955                 qry_lid_table_flag( lids, sx.sig_id, &refline );
956                 printf("[see line %u]\n", refline);
957                 ++*lineno;
958             }
959             else if( depth+1 >= MAX_LIST_SIGS_DEPTH  ) {
960                 print_user_id( "[too deeply nested]", keyid );
961                 ++*lineno;
962             }
963             else {
964                 print_user_id( "", keyid );
965                 ++*lineno;
966                 rc = do_list_sigs( root, sx.sig_id, depth+1, lids, lineno );
967                 if( rc )
968                     break;
969             }
970         }
971     }
972     return rc==-1? 0 : rc;
973 }
974
975 /****************
976  * List all signatures of a public key
977  */
978 static int
979 list_sigs( ulong pubkey_id )
980 {
981     int rc;
982     u32 keyid[2];
983     LOCAL_ID_INFO *lids;
984     unsigned lineno = 1;
985
986     rc = keyid_from_local_id( pubkey_id, keyid );
987     if( rc ) {
988         log_error("Hmmm, no pubkey record for local_id %lu\n", pubkey_id);
989         return rc;
990     }
991     printf("Signatures of %08lX(%lu) ", (ulong)keyid[1], pubkey_id );
992     print_user_id("", keyid);
993     printf("----------------------\n");
994
995     lids = new_lid_table();
996     rc = do_list_sigs( pubkey_id, pubkey_id, 0, lids, &lineno );
997     putchar('\n');
998     release_lid_table(lids);
999     return rc;
1000 }
1001
1002
1003
1004 /****************
1005  * Function to collect all trustpaths
1006  */
1007 static int
1008 do_list_path( TRUST_INFO *stack, int depth, int max_depth,
1009               LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist )
1010 {
1011     SIGREC_CONTEXT sx;
1012     unsigned last_depth;
1013     int rc;
1014
1015     assert(depth);
1016
1017     /*printf("%2lu/%d: scrutinizig\n", stack[depth-1], depth);*/
1018     if( depth >= max_depth || depth >= MAX_LIST_SIGS_DEPTH-1 ) {
1019         /*printf("%2lu/%d: to deeply nested\n", stack[depth-1], depth);*/
1020         return 0;
1021     }
1022     memset( &sx, 0, sizeof sx );
1023     sx.local_id = stack[depth-1].lid;
1024     /* loop over all signatures. If we do not have any, try to
1025      * create them */
1026     while( !(rc = walk_sigrecs( &sx, 1 )) ) {
1027         TRUST_SEG_LIST tsl, t2, tl;
1028         int i;
1029
1030         stack[depth].lid = sx.sig_id;
1031         stack[depth].trust = 0;
1032         if( qry_lid_table_flag( lids, sx.sig_id, &last_depth) ) {
1033             /*printf("%2lu/%d: marked\n", sx.sig_id, depth );*/
1034             ins_lid_table_item( lids, sx.sig_id, depth);
1035             last_depth = depth;
1036         }
1037         else if( depth  < last_depth ) {
1038             /*printf("%2lu/%d: last_depth=%u - updated\n", sx.sig_id, depth, last_depth);*/
1039             last_depth = depth;
1040             upd_lid_table_flag( lids, sx.sig_id, depth);
1041         }
1042
1043         if( last_depth < depth )
1044             /*printf("%2lu/%d: already visited\n", sx.sig_id, depth)*/;
1045         else if( !qry_lid_table_flag( ultikey_table, sx.sig_id, NULL ) ) {
1046             /* found end of path; store it, ordered by path length */
1047             tsl = m_alloc( sizeof *tsl + depth*sizeof(TRUST_INFO) );
1048             tsl->nseg = depth+1;
1049             tsl->dup = 0;
1050             for(i=0; i <= depth; i++ )
1051                 tsl->seg[i] = stack[i];
1052             for(t2=*tslist,tl=NULL; t2; tl=t2, t2 = t2->next )
1053                 if( depth < t2->nseg )
1054                     break;
1055             if( !tl ) {
1056                 tsl->next = t2;
1057                 *tslist = tsl;
1058             }
1059             else {
1060                 tsl->next = t2;
1061                 tl->next = tsl;
1062             }
1063             /*putchar('.'); fflush(stdout);*/
1064             /*printf("%2lu/%d: found\n", sx.sig_id, depth);*/
1065         }
1066         else {
1067             rc = do_list_path( stack, depth+1, max_depth, lids, tslist);
1068             if( rc && rc != -1 )
1069                 break;
1070         }
1071     }
1072     return rc==-1? 0 : rc;
1073 }
1074
1075
1076
1077 /****************
1078  * Check all the sigs of the given keyblock and mark them
1079  * as checked. Valid signatures which are duplicates are
1080  * also marked [shall we check them at all?]
1081  * FIXME: what shall we do if we have duplicate signatures were only
1082  *        some of them are bad?
1083  */
1084 static int
1085 check_sigs( KBNODE keyblock, int *selfsig_okay )
1086 {
1087     KBNODE kbctx;
1088     KBNODE node;
1089     int rc;
1090     LOCAL_ID_INFO *dups = NULL;
1091
1092     *selfsig_okay = 0;
1093     for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
1094         if( node->pkt->pkttype == PKT_SIGNATURE
1095             && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
1096             int selfsig;
1097             rc = check_key_signature( keyblock, node, &selfsig );
1098             if( !rc ) {
1099                 rc = set_signature_packets_local_id( node->pkt->pkt.signature );
1100                 if( rc )
1101                     log_fatal("set_signature_packets_local_id failed: %s\n",
1102                                                               g10_errstr(rc));
1103                 if( selfsig ) {
1104                     node->flag |= 2; /* mark signature valid */
1105                     *selfsig_okay = 1;
1106                 }
1107                 else
1108                     node->flag |= 1; /* mark signature valid */
1109                 if( !dups )
1110                     dups = new_lid_table();
1111                 if( ins_lid_table_item( dups,
1112                                     node->pkt->pkt.signature->local_id, 0) )
1113                     node->flag |= 4; /* mark as duplicate */
1114             }
1115             if( DBG_TRUST )
1116                 log_debug("trustdb: sig from %08lX(%lu): %s%s\n",
1117                                 (ulong)node->pkt->pkt.signature->keyid[1],
1118                                 node->pkt->pkt.signature->local_id,
1119                                 g10_errstr(rc), (node->flag&4)?"  (dup)":"" );
1120         }
1121     }
1122     if( dups )
1123         release_lid_table(dups);
1124     return 0;
1125 }
1126
1127
1128 /****************
1129  * If we do not have sigrecs for the given key, build them and write them
1130  * to the trustdb
1131  */
1132 static int
1133 build_sigrecs( ulong pubkeyid )
1134 {
1135     TRUSTREC rec, krec, rec2;
1136     PUBKEY_FIND_INFO finfo=NULL;
1137     KBPOS kbpos;
1138     KBNODE keyblock = NULL;
1139     KBNODE kbctx;
1140     KBNODE node;
1141     int rc=0;
1142     int i, selfsig;
1143     ulong rnum, rnum2;
1144     ulong first_sigrec = 0;
1145
1146     if( DBG_TRUST )
1147         log_debug("trustdb: build_sigrecs for pubkey %lu\n", (ulong)pubkeyid );
1148
1149     /* get the keyblock */
1150     if( (rc=read_record( pubkeyid, &rec, RECTYPE_DIR )) ) {
1151         log_error("%lu: build_sigrecs: can't read dir record\n", pubkeyid );
1152         goto leave;
1153     }
1154     finfo = m_alloc_clear( sizeof *finfo );
1155     finfo->keyid[0] = rec.r.dir.keyid[0];
1156     finfo->keyid[1] = rec.r.dir.keyid[1];
1157     if( (rc=read_record( rec.r.dir.keyrec, &krec, RECTYPE_KEY )) ) {
1158         log_error("%lu: build_sigrecs: can't read key record\n", pubkeyid);
1159         goto leave;
1160     }
1161     finfo->pubkey_algo = krec.r.key.pubkey_algo;
1162     memcpy( finfo->fingerprint, krec.r.key.fingerprint, 20);
1163     rc = find_keyblock( finfo, &kbpos );
1164     if( rc ) {
1165         log_error("build_sigrecs: find_keyblock failed\n" );
1166         goto leave;
1167     }
1168     rc = read_keyblock( &kbpos, &keyblock );
1169     if( rc ) {
1170         log_error("build_sigrecs: read_keyblock failed\n" );
1171         goto leave;
1172     }
1173     /* check all key signatures */
1174     rc = check_sigs( keyblock, &selfsig );
1175     if( rc ) {
1176         log_error("build_sigrecs: check_sigs failed\n" );
1177         goto leave;
1178     }
1179     if( !selfsig ) {
1180         log_error("build_sigrecs: self-certificate missing\n" );
1181         update_no_sigs( pubkeyid, 2 );
1182         rc = G10ERR_BAD_CERT;
1183         goto leave;
1184     }
1185     update_no_sigs( pubkeyid, 0 ); /* assume we have sigs */
1186
1187     /* valid key signatures are now marked; we can now build the
1188      * sigrecs */
1189     memset( &rec, 0, sizeof rec );
1190     rec.rectype = RECTYPE_SIG;
1191     i = 0;
1192     rnum = rnum2 = 0;
1193     for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
1194         /* insert sigs which are not a selfsig nor a duplicate */
1195         if( (node->flag & 1) && !(node->flag & 4) ) {
1196             assert( node->pkt->pkttype == PKT_SIGNATURE );
1197             if( !node->pkt->pkt.signature->local_id )  {
1198                 /* the next function should always succeed, because
1199                  * we have already checked the signature, and for this
1200                  * it was necessary to have the pubkey. The only reason
1201                  * this can fail are I/o errors of the trustdb or a
1202                  * remove operation on the pubkey database - which should
1203                  * not disturb us, because we have to chace them anyway. */
1204                 rc = set_signature_packets_local_id( node->pkt->pkt.signature );
1205                 if( rc )
1206                     log_fatal("set_signature_packets_local_id failed: %s\n",
1207                                                               g10_errstr(rc));
1208             }
1209             if( i == SIGS_PER_RECORD ) {
1210                 /* write the record */
1211                 rnum = new_recnum();
1212                 if( rnum2 ) { /* write the stored record */
1213                     rec2.r.sig.owner = pubkeyid;
1214                     rec2.r.sig.chain = rnum; /* the next record number */
1215                     rc = write_record( rnum2, &rec2 );
1216                     if( rc ) {
1217                         log_error("build_sigrecs: write_record failed\n" );
1218                         goto leave;
1219                     }
1220                     if( !first_sigrec )
1221                         first_sigrec = rnum2;
1222                 }
1223                 rec2 = rec;
1224                 rnum2 = rnum;
1225                 memset( &rec, 0, sizeof rec );
1226                 rec.rectype = RECTYPE_SIG;
1227                 i = 0;
1228             }
1229             rec.r.sig.sig[i].local_id = node->pkt->pkt.signature->local_id;
1230             rec.r.sig.sig[i].flag = 0;
1231             i++;
1232         }
1233     }
1234     if( i || rnum2 ) {
1235         /* write the record */
1236         rnum = new_recnum();
1237         if( rnum2 ) { /* write the stored record */
1238             rec2.r.sig.owner = pubkeyid;
1239             rec2.r.sig.chain = rnum;
1240             rc = write_record( rnum2, &rec2 );
1241             if( rc ) {
1242                 log_error("build_sigrecs: write_record failed\n" );
1243                 goto leave;
1244             }
1245             if( !first_sigrec )
1246                 first_sigrec = rnum2;
1247         }
1248         if( i ) { /* write the pending record */
1249             rec.r.sig.owner = pubkeyid;
1250             rec.r.sig.chain = 0;
1251             rc = write_record( rnum, &rec );
1252             if( rc ) {
1253                 log_error("build_sigrecs: write_record failed\n" );
1254                 goto leave;
1255             }
1256             if( !first_sigrec )
1257                 first_sigrec = rnum;
1258         }
1259     }
1260     if( first_sigrec ) {
1261         /* update the dir record */
1262         if( (rc =read_record( pubkeyid, &rec, RECTYPE_DIR )) ) {
1263             log_error("update_dir_record: read failed\n");
1264             goto leave;
1265         }
1266         rec.r.dir.sigrec = first_sigrec;
1267         if( (rc=write_record( pubkeyid, &rec )) ) {
1268             log_error("update_dir_record: write failed\n");
1269             goto leave;
1270         }
1271     }
1272     else
1273         update_no_sigs( pubkeyid, 1 ); /* no signatures */
1274
1275   leave:
1276     m_free( finfo );
1277     release_kbnode( keyblock );
1278     if( DBG_TRUST )
1279         log_debug("trustdb: build_sigrecs: %s\n", g10_errstr(rc) );
1280     return rc;
1281 }
1282
1283 /****************
1284  * Make a list of trust paths
1285  */
1286 static int
1287 make_tsl( ulong pubkey_id, TRUST_SEG_LIST *ret_tslist )
1288 {
1289     int i, rc;
1290     LOCAL_ID_INFO *lids = new_lid_table();
1291     TRUST_INFO stack[MAX_LIST_SIGS_DEPTH];
1292     TRUST_SEG_LIST tsl, tslist;
1293     int max_depth = 4;
1294
1295     tslist = *ret_tslist = NULL;
1296
1297     if( !qry_lid_table_flag( ultikey_table, pubkey_id, NULL ) ) {
1298         tslist = m_alloc( sizeof *tslist );
1299         tslist->nseg = 1;
1300         tslist->dup = 0;
1301         tslist->seg[0].lid = pubkey_id;
1302         tslist->seg[0].trust = 0;
1303         tslist->next = NULL;
1304         rc = 0;
1305     }
1306     else {
1307         stack[0].lid = pubkey_id;
1308         stack[0].trust = 0;
1309         rc = do_list_path( stack, 1, max_depth, lids, &tslist );
1310     }
1311     if( !rc ) { /* wipe out duplicates */
1312         LOCAL_ID_INFO *work = new_lid_table();
1313         for( tsl=tslist; tsl; tsl = tsl->next ) {
1314             for(i=1; i < tsl->nseg-1; i++ ) {
1315                 if( ins_lid_table_item( work, tsl->seg[i].lid, 0 ) ) {
1316                     tsl->dup = 1; /* mark as duplicate */
1317                     break;
1318                 }
1319             }
1320         }
1321         release_lid_table(work);
1322         *ret_tslist = tslist;
1323     }
1324     else
1325         ; /* FIXME: release tslist */
1326     release_lid_table(lids);
1327     return rc;
1328 }
1329
1330
1331 /****************
1332  * Given a trust segment list tslist, walk over all paths and fill in
1333  * the trust information for each segment.  What this function does is
1334  * to assign a trustvalue to the first segment (which is the requested key)
1335  * of each path.
1336  *
1337  * FIXME: We have to do more thinks here. e.g. we should never increase
1338  *        the trust value.
1339  *
1340  * Do not do it for duplicates.
1341  */
1342 static int
1343 propagate_trust( TRUST_SEG_LIST tslist )
1344 {
1345     int i, rc;
1346     unsigned trust, tr;
1347     TRUST_SEG_LIST tsl;
1348
1349     for(tsl = tslist; tsl; tsl = tsl->next ) {
1350         if( tsl->dup )
1351             continue;
1352         assert( tsl->nseg );
1353         /* the last segment is always a ultimately trusted one, so we can
1354          * assign a fully trust to the next one */
1355         i = tsl->nseg-1;
1356         tsl->seg[i].trust = TRUST_ULTIMATE;
1357         trust = TRUST_FULLY;
1358         for(i-- ; i >= 0; i-- ) {
1359             tsl->seg[i].trust = trust;
1360             if( i > 0 ) {
1361                 /* get the trust of this pubkey */
1362                 rc = get_ownertrust( tsl->seg[i].lid, &tr );
1363                 if( rc )
1364                     return rc;
1365                 if( tr < trust )
1366                     trust = tr;
1367             }
1368         }
1369     }
1370     return 0;
1371 }
1372
1373
1374 /****************
1375  * we have the pubkey record but nothing more is known
1376  * function may re-read dr.
1377  */
1378 static int
1379 do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel )
1380 {
1381     int i, rc=0;
1382     TRUST_SEG_LIST tsl, tsl2, tslist;
1383     int marginal, fully;
1384     int fully_needed = opt.completes_needed;
1385     int marginal_needed = opt.marginals_needed;
1386
1387     assert( fully_needed > 0 && marginal_needed > 1 );
1388
1389
1390     *trustlevel = TRUST_UNDEFINED;
1391
1392     /* verify the cache */
1393
1394     /* do we have sigrecs */
1395     if( !dr->r.dir.sigrec && !dr->r.dir.no_sigs) {
1396         /* no sigrecs, so build them */
1397         rc = build_sigrecs( pubkeyid );
1398         if( !rc ) /* and read again */
1399             rc = read_record( pubkeyid, dr, RECTYPE_DIR );
1400     }
1401     if( !rc && !dr->r.dir.sigrec ) {
1402         /* See wether this is our own key */
1403         if( !qry_lid_table_flag( ultikey_table, pubkeyid, NULL ) ) {
1404             *trustlevel = TRUST_ULTIMATE;
1405             return 0;
1406         }
1407         else
1408             rc = -1;
1409     }
1410     if( rc )
1411         return rc;  /* error while looking for sigrec or building sigrecs */
1412
1413     /* fixme: take it from the cache if it is valid */
1414
1415     /* Make a list of all possible trust-paths */
1416     rc = make_tsl( pubkeyid, &tslist );
1417     if( rc )
1418         return rc;
1419     rc = propagate_trust( tslist );
1420     if( rc )
1421         return rc;
1422     for(tsl = tslist; tsl; tsl = tsl->next ) {
1423         if( tsl->dup )
1424             continue;
1425
1426         log_debug("tslist segs:" );
1427         for(i=0; i < tsl->nseg; i++ )
1428             fprintf(stderr, "  %lu/%02x", tsl->seg[i].lid, tsl->seg[i].trust );
1429         putc('\n',stderr);
1430     }
1431
1432     /* and look wether there is a trusted path.
1433      * We only have to look at the first segment, because
1434      * propagate_trust has investigated all other segments */
1435     marginal = fully = 0;
1436     for(tsl = tslist; tsl; tsl = tsl->next ) {
1437         if( tsl->dup )
1438             continue;
1439         if( tsl->seg[0].trust == TRUST_ULTIMATE ) {
1440             *trustlevel = TRUST_ULTIMATE; /* our own key */
1441             break;
1442         }
1443         if( tsl->seg[0].trust == TRUST_FULLY ) {
1444             marginal++;
1445             fully++;
1446         }
1447         else if( tsl->seg[0].trust == TRUST_MARGINAL )
1448             marginal++;
1449
1450         if( fully >= fully_needed ) {
1451             *trustlevel = TRUST_FULLY;
1452             break;
1453         }
1454     }
1455     if( !tsl && marginal >= marginal_needed )
1456         *trustlevel = TRUST_MARGINAL;
1457
1458     /* cache the tslist */
1459     if( last_trust_web_key ) {
1460         for( tsl = last_trust_web_tslist; tsl; tsl = tsl2 ) {
1461             tsl2 = tsl->next;
1462             m_free(tsl);
1463         }
1464     }
1465     last_trust_web_key = pubkeyid;
1466     last_trust_web_tslist = tslist;
1467     return 0;
1468 }
1469
1470
1471 /*********************************************************
1472  ****************  API Interface  ************************
1473  *********************************************************/
1474
1475 /****************
1476  * Perform some checks over the trustdb
1477  *  level 0: only open the db
1478  *        1: used for initial program startup
1479  */
1480 int
1481 init_trustdb( int level, const char *dbname )
1482 {
1483     int rc=0;
1484
1485     if( !ultikey_table )
1486         ultikey_table = new_lid_table();
1487
1488     if( !level || level==1 ) {
1489         char *fname = dbname? m_strdup( dbname )
1490                             : make_filename("~/.g10", "trustdb.g10", NULL );
1491         if( access( fname, R_OK ) ) {
1492             if( errno != ENOENT ) {
1493                 log_error("can't access %s: %s\n", fname, strerror(errno) );
1494                 m_free(fname);
1495                 return G10ERR_TRUSTDB;
1496             }
1497             if( level )
1498                 create_db( fname );
1499         }
1500         m_free(db_name);
1501         db_name = fname;
1502
1503         if( !level )
1504             return 0;
1505
1506         /* we can verify a signature about our local data (secring and trustdb)
1507          * in ~/.g10/ here */
1508         rc = verify_private_data();
1509         if( !rc ) {
1510             /* verify, that our own certificates are in the trustDB
1511              * or move them to the trustdb. */
1512             rc = verify_own_certs();
1513
1514             /* should we check wether there is no other ultimately trusted
1515              * key in the database? */
1516
1517         }
1518     }
1519     else
1520         BUG();
1521
1522     return rc;
1523 }
1524
1525
1526 void
1527 list_trustdb( const char *username )
1528 {
1529     TRUSTREC rec;
1530
1531     if( username ) {
1532         PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
1533         int rc;
1534
1535         if( (rc = get_pubkey_byname( pkc, username )) )
1536             log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
1537         else if( (rc=search_record( pkc, &rec )) && rc != -1 )
1538             log_error("problem finding '%s' in trustdb: %s\n",
1539                                                 username, g10_errstr(rc));
1540         else if( rc == -1 )
1541             log_error("user '%s' not in trustdb\n", username);
1542         else if( (rc = list_sigs( pkc->local_id )) )
1543             log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
1544         free_public_cert( pkc );
1545     }
1546     else {
1547         ulong recnum;
1548         int i;
1549
1550         printf("TrustDB: %s\n", db_name );
1551         for(i=9+strlen(db_name); i > 0; i-- )
1552             putchar('-');
1553         putchar('\n');
1554         for(recnum=0; !read_record( recnum, &rec, 0); recnum++ )
1555             dump_record( recnum, &rec, stdout );
1556     }
1557 }
1558
1559 void
1560 list_trust_path( int max_depth, const char *username )
1561 {
1562     int rc;
1563     int wipe=0;
1564     int i;
1565     TRUSTREC rec;
1566     PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
1567
1568     if( max_depth < 0 ) {
1569         wipe = 1;
1570         max_depth = -max_depth;
1571     }
1572
1573     if( (rc = get_pubkey_byname( pkc, username )) )
1574         log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
1575     else if( (rc=search_record( pkc, &rec )) && rc != -1 )
1576         log_error("problem finding '%s' in trustdb: %s\n",
1577                                             username, g10_errstr(rc));
1578     else if( rc == -1 ) {
1579         log_info("user '%s' not in trustdb - inserting\n", username);
1580         rc = insert_trust_record( pkc );
1581         if( rc )
1582             log_error("failed to put '%s' into trustdb: %s\n", username, g10_errstr(rc));
1583         else {
1584             assert( pkc->local_id );
1585         }
1586     }
1587
1588     if( !rc ) {
1589         TRUST_SEG_LIST tsl, tslist = NULL;
1590
1591         if( !qry_lid_table_flag( ultikey_table, pkc->local_id, NULL ) ) {
1592             tslist = m_alloc( sizeof *tslist );
1593             tslist->nseg = 1;
1594             tslist->dup = 0;
1595             tslist->seg[0].lid = pkc->local_id;
1596             tslist->seg[0].trust = 0;
1597             tslist->next = NULL;
1598             rc = 0;
1599         }
1600         else {
1601             LOCAL_ID_INFO *lids = new_lid_table();
1602             TRUST_INFO stack[MAX_LIST_SIGS_DEPTH];
1603
1604             stack[0].lid = pkc->local_id;
1605             stack[0].trust = 0;
1606             rc = do_list_path( stack, 1, max_depth, lids, &tslist );
1607             if( wipe ) { /* wipe out duplicates */
1608                 LOCAL_ID_INFO *work;
1609
1610                 work = new_lid_table();
1611                 for( tsl=tslist; tsl; tsl = tsl->next ) {
1612                     for(i=1; i < tsl->nseg-1; i++ ) {
1613                         if( ins_lid_table_item( work, tsl->seg[i].lid, 0 ) ) {
1614                             tsl->dup = 1; /* mark as duplicate */
1615                             break;
1616                         }
1617                     }
1618                 }
1619                 release_lid_table(work);
1620             }
1621             release_lid_table(lids);
1622         }
1623         if( rc )
1624             log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
1625         rc = propagate_trust( tslist );
1626         if( rc )
1627             log_error("user '%s' trust problem: %s\n", username, g10_errstr(rc));
1628         for(tsl = tslist; tsl; tsl = tsl->next ) {
1629             int i;
1630
1631             if( tsl->dup )
1632                 continue;
1633             printf("trust path:" );
1634             for(i=0; i < tsl->nseg; i++ )
1635                 printf("  %lu/%02x", tsl->seg[i].lid, tsl->seg[i].trust );
1636             putchar('\n');
1637         }
1638     }
1639
1640     free_public_cert( pkc );
1641 }
1642
1643
1644 /****************
1645  * Get the trustlevel for this PKC.
1646  * Note: This does not ask any questions
1647  * Returns: 0 okay of an errorcode
1648  *
1649  * It operates this way:
1650  *  locate the pkc in the trustdb
1651  *      found:
1652  *          Do we have a valid cache record for it?
1653  *              yes: return trustlevel from cache
1654  *              no:  make a cache record and all the other stuff
1655  *      not found:
1656  *          Return with a trustlevel, saying that we do not have
1657  *          a trust record for it. The caller may use insert_trust_record()
1658  *          and then call this function here again.
1659  *
1660  * Problems: How do we get the complete keyblock to check that the
1661  *           cache record is actually valid?  Think we need a clever
1662  *           cache in getkey.c  to keep track of this stuff. Maybe it
1663  *           is not necessary to check this if we use a local pubring. Hmmmm.
1664  */
1665 int
1666 check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel )
1667 {
1668     TRUSTREC rec;
1669     unsigned trustlevel = TRUST_UNKNOWN;
1670     int rc=0;
1671
1672     if( DBG_TRUST )
1673         log_info("check_trust() called.\n");
1674
1675     /* get the pubkey record */
1676     if( pkc->local_id ) {
1677         if( read_record( pkc->local_id, &rec, RECTYPE_DIR ) ) {
1678             log_error("check_trust: read record failed\n");
1679             return G10ERR_TRUSTDB;
1680         }
1681     }
1682     else { /* no local_id: scan the trustdb */
1683         if( (rc=search_record( pkc, &rec )) && rc != -1 ) {
1684             log_error("check_trust: search_record failed: %s\n",
1685                                                             g10_errstr(rc));
1686             return rc;
1687         }
1688         else if( rc == -1 ) {
1689             rc = insert_trust_record( pkc );
1690             if( rc ) {
1691                 log_error("failed to insert pubkey into trustdb: %s\n",
1692                                                             g10_errstr(rc));
1693                 goto leave;
1694             }
1695             log_info("pubkey not in trustdb - inserted as %lu\n",
1696                                     pkc->local_id );
1697         }
1698     }
1699     /* fixme: do some additional checks on the pubkey record */
1700
1701     rc = do_check( pkc->local_id, &rec, &trustlevel );
1702     if( rc ) {
1703         log_error("check_trust: do_check failed: %s\n", g10_errstr(rc));
1704         return rc;
1705     }
1706
1707
1708   leave:
1709     if( DBG_TRUST )
1710         log_info("check_trust() returns trustlevel %04x.\n", trustlevel);
1711     *r_trustlevel = trustlevel;
1712     return 0;
1713 }
1714
1715
1716
1717
1718 /****************
1719  * Enumerate all keys, which are needed to build all trust paths for
1720  * the given key.  This function does not return the key itself or
1721  * the ultimate key.
1722  *
1723  *  1) create a void pointer and initialize it to NULL
1724  *  2) pass this void pointer by reference to this function.
1725  *     Set lid to the key you want to enumerate and pass it by reference.
1726  *  3) call this function as long as it does not return -1
1727  *     to indicate EOF. LID does contain the next key used to build the web
1728  *  4) Always call this function a last time with LID set to NULL,
1729  *     so that it can free it's context.
1730  */
1731 int
1732 enum_trust_web( void **context, ulong *lid )
1733 {
1734     ENUM_TRUST_WEB_CONTEXT *c = *context;
1735
1736     if( !c ) { /* make a new context */
1737         c = m_alloc_clear( sizeof *c );
1738         *context = c;
1739         if( *lid != last_trust_web_key )
1740             log_bug("enum_trust_web: nyi\n");
1741         c->tsl = last_trust_web_tslist;
1742         c->index = 1;
1743     }
1744
1745     if( !lid ) { /* free the context */
1746         m_free( c );
1747         *context = NULL;
1748         return 0;
1749     }
1750
1751     while( c->tsl ) {
1752         if( !c->tsl->dup && c->index < c->tsl->nseg-1 ) {
1753             *lid = c->tsl->seg[c->index].lid;
1754             c->index++;
1755             return 0;
1756         }
1757         c->index = 1;
1758         c->tsl = c->tsl->next;
1759     }
1760     return -1; /* eof */
1761 }
1762
1763
1764 /****************
1765  * Return the assigned ownertrust value for the given LID
1766  */
1767 int
1768 get_ownertrust( ulong lid, unsigned *r_otrust )
1769 {
1770     TRUSTREC rec;
1771
1772     if( read_record( lid, &rec, RECTYPE_DIR ) ) {
1773         log_error("get_ownertrust: read dir record failed\n");
1774         return G10ERR_TRUSTDB;
1775     }
1776     if( read_record( rec.r.dir.keyrec, &rec, RECTYPE_KEY ) ) {
1777         log_error("get_ownertrust: read key record failed\n");
1778         return G10ERR_TRUSTDB;
1779     }
1780     if( r_otrust )
1781         *r_otrust = rec.r.key.ownertrust;
1782     return 0;
1783 }
1784
1785 int
1786 keyid_from_trustdb( ulong lid, u32 *keyid )
1787 {
1788     TRUSTREC rec;
1789
1790     if( read_record( lid, &rec, RECTYPE_DIR ) ) {
1791         log_error("keyid_from_trustdb: read record failed\n");
1792         return G10ERR_TRUSTDB;
1793     }
1794     if( keyid ) {
1795         keyid[0] = rec.r.dir.keyid[0];
1796         keyid[1] = rec.r.dir.keyid[1];
1797     }
1798     return 0;
1799 }
1800
1801
1802 /****************
1803  * This function simply looks for the key in the trustdb
1804  * and sets PKC->local_id.
1805  * Return: 0 = found
1806  *         -1 = not found
1807  *        other = error
1808  */
1809 int
1810 query_trust_record( PKT_public_cert *pkc )
1811 {
1812     TRUSTREC rec;
1813     int rc=0;
1814
1815     if( pkc->local_id ) {
1816         if( read_record( pkc->local_id, &rec, RECTYPE_DIR ) ) {
1817             log_error("query_trust_record: read record failed\n");
1818             return G10ERR_TRUSTDB;
1819         }
1820     }
1821     else { /* no local_id: scan the trustdb */
1822         if( (rc=search_record( pkc, &rec )) && rc != -1 ) {
1823             log_error("query_trust_record: search_record failed: %s\n",
1824                                                             g10_errstr(rc));
1825             return rc;
1826         }
1827     }
1828     return rc;
1829 }
1830
1831
1832 /****************
1833  * Insert a trust record into the TrustDB
1834  * This function failes if this record already exists.
1835  */
1836 int
1837 insert_trust_record( PKT_public_cert *pkc )
1838 {
1839     TRUSTREC rec;
1840     u32 keyid[2];
1841     ulong knum, dnum;
1842     byte *fingerprint;
1843     size_t fingerlen;
1844
1845
1846     if( pkc->local_id )
1847         log_bug("pkc->local_id=%lu\n", (ulong)pkc->local_id );
1848
1849     keyid_from_pkc( pkc, keyid );
1850     fingerprint = fingerprint_from_pkc( pkc, &fingerlen );
1851
1852     /* FIXME: check that we do not have this record. */
1853
1854     dnum = new_recnum();
1855     knum = new_recnum();
1856     /* build dir record */
1857     memset( &rec, 0, sizeof rec );
1858     rec.rectype = RECTYPE_DIR;
1859     rec.r.dir.local_id = dnum;
1860     rec.r.dir.keyid[0] = keyid[0];
1861     rec.r.dir.keyid[1] = keyid[1];
1862     rec.r.dir.keyrec   = knum;
1863     rec.r.dir.no_sigs = 0;
1864     if( write_record( dnum, &rec ) ) {
1865         log_error("writing dir record failed\n");
1866         return G10ERR_TRUSTDB;
1867     }
1868     /* and the key record */
1869     memset( &rec, 0, sizeof rec );
1870     rec.rectype = RECTYPE_KEY;
1871     rec.r.key.owner    = dnum;
1872     rec.r.key.keyid[0] = keyid[0];
1873     rec.r.key.keyid[1] = keyid[1];
1874     rec.r.key.pubkey_algo = pkc->pubkey_algo;
1875     memcpy(rec.r.key.fingerprint, fingerprint, fingerlen );
1876     rec.r.key.ownertrust = 0;
1877     if( write_record( knum, &rec ) ) {
1878         log_error("wrinting key record failed\n");
1879         return G10ERR_TRUSTDB;
1880     }
1881
1882     pkc->local_id = dnum;
1883
1884     return 0;
1885 }
1886
1887
1888 int
1889 update_ownertrust( ulong lid, unsigned new_trust )
1890 {
1891     TRUSTREC rec;
1892     ulong recnum;
1893
1894     if( read_record( lid, &rec, RECTYPE_DIR ) ) {
1895         log_error("update_ownertrust: read dir failed\n");
1896         return G10ERR_TRUSTDB;
1897     }
1898     recnum = rec.r.dir.keyrec;
1899     if( read_record( recnum, &rec, RECTYPE_KEY ) ) {
1900         log_error("update_ownertrust: read key failed\n");
1901         return G10ERR_TRUSTDB;
1902     }
1903     /* check keyid, fingerprint etc ? */
1904
1905     rec.r.key.ownertrust = new_trust;
1906     if( write_record( recnum, &rec ) ) {
1907         log_error("update_ownertrust: write failed\n");
1908         return G10ERR_TRUSTDB;
1909     }
1910
1911     return 0;
1912 }
1913
1914
1915
1916 /****************
1917  * Kludge to prevent duplicate build_sigrecs() due to an invalid
1918  * certificate (no selfsignature or something like this)
1919  */
1920 static int
1921 update_no_sigs( ulong lid, int no_sigs )
1922 {
1923     TRUSTREC rec;
1924
1925     if( read_record( lid, &rec, RECTYPE_DIR ) ) {
1926         log_error("update_no_sigs: read failed\n");
1927         return G10ERR_TRUSTDB;
1928     }
1929
1930     rec.r.dir.no_sigs = no_sigs;
1931     if( write_record( lid, &rec ) ) {
1932         log_error("update_no_sigs: write failed\n");
1933         return G10ERR_TRUSTDB;
1934     }
1935
1936     return 0;
1937 }
1938
1939
1940 int
1941 verify_private_data()
1942 {
1943     int rc = 0;
1944     char *sigfile = make_filename("~/.g10", "sig", NULL );
1945
1946     if( access( sigfile, R_OK ) ) {
1947         if( errno != ENOENT ) {
1948             log_error("can't access %s: %s\n", sigfile, strerror(errno) );
1949             rc = G10ERR_TRUSTDB;
1950             goto leave;
1951         }
1952         log_info("private data signature missing; creating ...\n");
1953         rc = sign_private_data();
1954         if( rc ) {
1955             log_error("error creating %s: %s\n", sigfile, g10_errstr(rc) );
1956             goto leave;
1957         }
1958     }
1959
1960     /* FIXME: verify this signature */
1961
1962   leave:
1963     m_free(sigfile);
1964     return rc;
1965 }
1966
1967
1968 int
1969 sign_private_data()
1970 {
1971     int rc;
1972     char *sigfile = make_filename("~/.g10", "sig", NULL );
1973     char *secring = make_filename("~/.g10", "secring.g10", NULL );
1974     STRLIST list = NULL;
1975
1976     add_to_strlist( &list, db_name );
1977     add_to_strlist( &list, secring );
1978
1979     rc = sign_file( list, 1, NULL, 0, NULL, sigfile);
1980
1981     m_free(sigfile);
1982     m_free(secring);
1983     free_strlist(list);
1984     return rc;
1985 }
1986