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