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