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