See ChangeLog: Fri Jul 14 19:38:23 CEST 2000 Werner Koch
[gnupg.git] / g10 / trustdb.c
1 /* trustdb.c
2  *      Copyright (C) 1998, 1999, 2000 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 <ctype.h>
27 #include <assert.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32
33 #include "errors.h"
34 #include "iobuf.h"
35 #include "keydb.h"
36 #include <gcrypt.h>
37 #include "util.h"
38 #include "trustdb.h"
39 #include "options.h"
40 #include "packet.h"
41 #include "main.h"
42 #include "i18n.h"
43 #include "tdbio.h"
44 #include "ttyio.h"
45
46 #if MAX_FINGERPRINT_LEN > 20
47   #error Must change structure of trustdb
48 #endif
49
50 struct keyid_list {
51     struct keyid_list *next;
52     u32 keyid[2];
53 };
54
55 struct local_id_item {
56     struct local_id_item *next;
57     ulong lid;
58     unsigned flag;
59 };
60
61 struct local_id_table {
62     struct local_id_table *next; /* only used to keep a list of unused tables */
63     struct local_id_item *items[16];
64 };
65
66
67 typedef struct local_id_table *LOCAL_ID_TABLE;
68
69
70 struct enum_cert_paths_ctx {
71    int init;
72    int idx;
73 };
74
75
76 struct recno_list_struct {
77     struct recno_list_struct *next;
78     ulong recno;
79     int type;
80 };
81 typedef struct recno_list_struct *RECNO_LIST;
82
83
84
85 typedef struct trust_node *TN;
86 struct trust_node {
87     TN    back;  /* parent */
88     TN    list;  /* list of other node (should all be of the same type)*/
89     TN    next;  /* used to build the list */
90     int   is_uid; /* set if this is an uid node */
91     ulong lid;   /* key or uid recordnumber */
92     union {
93         struct {
94             int ownertrust;
95             int validity;
96             /* helper */
97             int buckstop;
98         } k;
99         struct {
100             int marginal_count;
101             int fully_count;
102             int validity;
103         } u;
104     } n;
105 };
106
107
108 static TN used_tns;
109 static int alloced_tns;
110 static int max_alloced_tns;
111
112
113 static LOCAL_ID_TABLE new_lid_table(void);
114 static int ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag );
115 static int qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag );
116
117
118 static int propagate_validity( TN root, TN node,
119                                int (*add_fnc)(ulong), unsigned *retflgs );
120
121 static void print_user_id( FILE *fp, const char *text, u32 *keyid );
122 static int do_check( TRUSTREC *drec, unsigned *trustlevel,
123                      const char *nhash, int (*add_fnc)(ulong),
124                                                 unsigned *retflgs);
125 static int get_dir_record( PKT_public_key *pk, TRUSTREC *rec );
126 static int do_update_trust_record( KBNODE keyblock, TRUSTREC *drec,
127                                    int sigs_only, int *modified );
128 static int check_trust_record( TRUSTREC *drec, int sigs_only );
129 static void mark_fresh_keys(void);
130
131 /* a table used to keep track of ultimately trusted keys
132  * which are the ones from our secrings and the trusted keys */
133 static LOCAL_ID_TABLE ultikey_table;
134
135
136 /* a table to keep track of newly importted keys.  This one is
137  * create by the insert_trust_record function and from time to time
138  * used to verify key signature which have been done with these new keys */
139 static LOCAL_ID_TABLE fresh_imported_keys;
140 static int fresh_imported_keys_count;
141 #define FRESH_KEY_CHECK_THRESHOLD 200
142
143 /* list of unused lid items and tables */
144 static LOCAL_ID_TABLE unused_lid_tables;
145 static struct local_id_item *unused_lid_items;
146
147 static struct {
148     int init;
149     int level;
150     char *dbname;
151 } trustdb_args;
152
153 \f
154 /**********************************************
155  ***********  record read write  **************
156  **********************************************/
157
158
159 /****************
160  * Read a record but die if it does not exist
161  */
162 static void
163 read_record( ulong recno, TRUSTREC *rec, int rectype )
164 {
165     int rc = tdbio_read_record( recno, rec, rectype );
166     if( !rc )
167         return;
168     log_error(_("trust record %lu, req type %d: read failed: %s\n"),
169                                     recno, rectype,  gpg_errstr(rc) );
170     tdbio_invalid();
171 }
172
173
174 /****************
175  * Wirte a record but die on error
176  */
177 static void
178 write_record( TRUSTREC *rec )
179 {
180     int rc = tdbio_write_record( rec );
181     if( !rc )
182         return;
183     log_error(_("trust record %lu, type %d: write failed: %s\n"),
184                             rec->recnum, rec->rectype, gpg_errstr(rc) );
185     tdbio_invalid();
186 }
187
188 /****************
189  * Delete a record but die on error
190  */
191 static void
192 delete_record( ulong recno )
193 {
194     int rc = tdbio_delete_record( recno );
195     if( !rc )
196         return;
197     log_error(_("trust record %lu: delete failed: %s\n"),
198                                               recno, gpg_errstr(rc) );
199     tdbio_invalid();
200 }
201
202 /****************
203  * sync the db
204  */
205 static void
206 do_sync(void)
207 {
208     int rc = tdbio_sync();
209     if( !rc )
210         return;
211     log_error(_("trustdb: sync failed: %s\n"), gpg_errstr(rc) );
212     gpg_exit(2);
213 }
214
215
216 \f
217 /**********************************************
218  *****************  helpers  ******************
219  **********************************************/
220
221
222 static LOCAL_ID_TABLE
223 new_lid_table(void)
224 {
225     LOCAL_ID_TABLE a;
226
227     a = unused_lid_tables;
228     if( a ) {
229         unused_lid_tables = a->next;
230         memset( a, 0, sizeof *a );
231     }
232     else
233         a = gcry_xcalloc( 1, sizeof *a );
234     return a;
235 }
236
237 #if 0
238 static void
239 release_lid_table( LOCAL_ID_TABLE tbl )
240 {
241     struct local_id_item *a, *a2;
242     int i;
243
244     for(i=0; i < 16; i++ ) {
245         for(a=tbl->items[i]; a; a = a2 ) {
246             a2 = a->next;
247             a->next = unused_lid_items;
248             unused_lid_items = a;
249         }
250     }
251     tbl->next = unused_lid_tables;
252     unused_lid_tables = tbl;
253 }
254 #endif
255
256
257 /****************
258  * Remove all items from a LID table
259  */
260 static void
261 clear_lid_table( LOCAL_ID_TABLE tbl )
262 {
263     struct local_id_item *a, *a2;
264     int i;
265
266     for(i=0; i < 16; i++ ) {
267         for(a=tbl->items[i]; a; a = a2 ) {
268             a2 = a->next;
269             a->next = unused_lid_items;
270             unused_lid_items = a;
271         }
272         tbl->items[i] = NULL;
273     }
274 }
275
276
277 /****************
278  * Add a new item to the table or return 1 if we already have this item
279  */
280 static int
281 ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag )
282 {
283     struct local_id_item *a;
284
285     for( a = tbl->items[lid & 0x0f]; a; a = a->next )
286         if( a->lid == lid )
287             return 1;
288     a = unused_lid_items;
289     if( a )
290         unused_lid_items = a->next;
291     else
292         a = gcry_xmalloc( sizeof *a );
293     a->lid = lid;
294     a->flag = flag;
295     a->next = tbl->items[lid & 0x0f];
296     tbl->items[lid & 0x0f] = a;
297     return 0;
298 }
299
300 static int
301 qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag )
302 {
303     struct local_id_item *a;
304
305     for( a = tbl->items[lid & 0x0f]; a; a = a->next )
306         if( a->lid == lid ) {
307             if( flag )
308                 *flag = a->flag;
309             return 0;
310         }
311     return -1;
312 }
313
314
315 static TN
316 new_tn(void)
317 {
318     TN t;
319
320     if( used_tns ) {
321         t = used_tns;
322         used_tns = t->next;
323         memset( t, 0, sizeof *t );
324     }
325     else
326         t = gcry_xcalloc( 1, sizeof *t );
327     if( ++alloced_tns > max_alloced_tns )
328         max_alloced_tns = alloced_tns;
329     return t;
330 }
331
332
333 static void
334 release_tn( TN t )
335 {
336     if( t ) {
337         t->next = used_tns;
338         used_tns = t;
339         alloced_tns--;
340     }
341 }
342
343
344 static void
345 release_tn_tree( TN kr )
346 {
347     TN  kr2;
348
349     for( ; kr; kr = kr2 ) {
350         release_tn_tree( kr->list );
351         kr2 = kr->next;
352         release_tn( kr );
353     }
354 }
355
356
357
358 \f
359 /**********************************************
360  ****** access by LID and other helpers *******
361  **********************************************/
362
363 /****************
364  * Return the keyid from the primary key identified by LID.
365  */
366 int
367 keyid_from_lid( ulong lid, u32 *keyid )
368 {
369     TRUSTREC rec;
370     int rc;
371
372     init_trustdb();
373     keyid[0] = keyid[1] = 0;
374     rc = tdbio_read_record( lid, &rec, 0 );
375     if( rc ) {
376         log_error(_("error reading dir record for LID %lu: %s\n"),
377                                                     lid, gpg_errstr(rc));
378         return GPGERR_TRUSTDB;
379     }
380     if( rec.rectype == RECTYPE_SDIR )
381         return 0;
382     if( rec.rectype != RECTYPE_DIR ) {
383         log_error(_("lid %lu: expected dir record, got type %d\n"),
384                                                     lid, rec.rectype );
385         return GPGERR_TRUSTDB;
386     }
387     if( !rec.r.dir.keylist ) {
388         log_error(_("no primary key for LID %lu\n"), lid );
389         return GPGERR_TRUSTDB;
390     }
391     rc = tdbio_read_record( rec.r.dir.keylist, &rec, RECTYPE_KEY );
392     if( rc ) {
393         log_error(_("error reading primary key for LID %lu: %s\n"),
394                                                     lid, gpg_errstr(rc));
395         return GPGERR_TRUSTDB;
396     }
397     keyid_from_fingerprint( rec.r.key.fingerprint, rec.r.key.fingerprint_len,
398                             keyid );
399
400     return 0;
401 }
402
403
404 ulong
405 lid_from_keyblock( KBNODE keyblock )
406 {
407     KBNODE node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
408     PKT_public_key *pk;
409     if( !node )
410         BUG();
411     pk = node->pkt->pkt.public_key;
412     if( !pk->local_id ) {
413         TRUSTREC rec;
414         init_trustdb();
415
416         get_dir_record( pk, &rec );
417     }
418     return pk->local_id;
419 }
420
421
422 static int
423 get_dir_record( PKT_public_key *pk, TRUSTREC *rec )
424 {
425     int rc=0;
426
427     if( pk->local_id ) {
428         read_record( pk->local_id, rec, RECTYPE_DIR );
429     }
430     else { /* no local_id: scan the trustdb */
431         if( (rc=tdbio_search_dir_bypk( pk, rec )) && rc != -1 )
432             log_error(_("get_dir_record: search_record failed: %s\n"),
433                                                             gpg_errstr(rc));
434     }
435     return rc;
436 }
437
438 static ulong
439 lid_from_keyid_no_sdir( u32 *keyid )
440 {
441     PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
442     TRUSTREC rec;
443     ulong lid = 0;
444     int rc;
445
446     rc = get_pubkey( pk, keyid );
447     if( !rc ) {
448         if( pk->local_id )
449             lid = pk->local_id;
450         else {
451             rc = tdbio_search_dir_bypk( pk, &rec );
452             if( !rc )
453                 lid = rec.recnum;
454         }
455     }
456     free_public_key( pk );
457     return lid;
458 }
459
460
461 \f
462 /***********************************************
463  *************  Initialization  ****************
464  ***********************************************/
465
466 /****************
467  * Verify that all our public keys are in the trustdb.
468  */
469 static int
470 verify_own_keys(void)
471 {
472     int rc;
473     void *enum_context = NULL;
474     PKT_secret_key *sk = gcry_xcalloc( 1, sizeof *sk );
475     PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
476     u32 keyid[2];
477
478     while( !(rc=enum_secret_keys( &enum_context, sk, 0 ) ) ) {
479         int have_pk = 0;
480
481         keyid_from_sk( sk, keyid );
482
483         if( DBG_TRUST )
484             log_debug("key %08lX: checking secret key\n", (ulong)keyid[1] );
485
486         if( !opt.quiet && is_secret_key_protected( sk ) < 1 )
487             log_info(_("NOTE: secret key %08lX is NOT protected.\n"),
488                                                             (ulong)keyid[1] );
489
490
491         /* see whether we can access the public key of this secret key */
492         memset( pk, 0, sizeof *pk );
493         rc = get_pubkey( pk, keyid );
494         if( rc ) {
495             log_info(_("key %08lX: secret key without public key - skipped\n"),
496                                                             (ulong)keyid[1] );
497             goto skip;
498         }
499         have_pk=1;
500
501         if( cmp_public_secret_key( pk, sk ) ) {
502             log_info(_("key %08lX: secret and public key don't match\n"),
503                                                             (ulong)keyid[1] );
504             goto skip;
505         }
506
507         /* make sure that the pubkey is in the trustdb */
508         rc = query_trust_record( pk );
509         if( rc == -1 && opt.dry_run )
510             goto skip;
511         if( rc == -1 ) { /* put it into the trustdb */
512             rc = insert_trust_record_by_pk( pk );
513             if( rc ) {
514                 log_error(_("key %08lX: can't put it into the trustdb\n"),
515                                                             (ulong)keyid[1] );
516                 goto skip;
517             }
518         }
519         else if( rc ) {
520             log_error(_("key %08lX: query record failed\n"), (ulong)keyid[1] );
521             goto skip;
522
523         }
524
525         if( DBG_TRUST )
526             log_debug("key %08lX.%lu: stored into ultikey_table\n",
527                                     (ulong)keyid[1], pk->local_id );
528         if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
529             log_error(_("key %08lX: already in trusted key table\n"),
530                                                         (ulong)keyid[1]);
531         else if( opt.verbose > 1 )
532             log_info(_("key %08lX: accepted as trusted key.\n"),
533                                                         (ulong)keyid[1]);
534       skip:
535         release_secret_key_parts( sk );
536         if( have_pk )
537             release_public_key_parts( pk );
538     }
539     if( rc != -1 )
540         log_error(_("enumerate secret keys failed: %s\n"), gpg_errstr(rc) );
541     else
542         rc = 0;
543
544     enum_secret_keys( &enum_context, NULL, 0 ); /* free context */
545     free_secret_key( sk );
546     free_public_key( pk );
547     return rc;
548 }
549
550
551 /****************
552  * Perform some checks over the trustdb
553  *  level 0: only open the db
554  *        1: used for initial program startup
555  */
556 int
557 setup_trustdb( int level, const char *dbname )
558 {
559     /* just store the args */
560     if( trustdb_args.init )
561         return 0;
562     trustdb_args.level = level;
563     trustdb_args.dbname = dbname? gcry_xstrdup(dbname): NULL;
564     return 0;
565 }
566
567 void
568 init_trustdb()
569 {
570     int rc=0;
571     int level = trustdb_args.level;
572     const char* dbname = trustdb_args.dbname;
573
574     if( trustdb_args.init )
575         return;
576
577     trustdb_args.init = 1;
578
579     if( !ultikey_table )
580         ultikey_table = new_lid_table();
581
582     if( !level || level==1 ) {
583         rc = tdbio_set_dbname( dbname, !!level );
584         if( !rc ) {
585             if( !level )
586                 return;
587
588             /* verify that our own keys are in the trustDB
589              * or move them to the trustdb. */
590             rc = verify_own_keys();
591
592             /* should we check whether there is no other ultimately trusted
593              * key in the database? */
594         }
595     }
596     else
597         BUG();
598     if( rc )
599         log_fatal("can't init trustdb: %s\n", gpg_errstr(rc) );
600 }
601
602
603
604 /****************
605  * This function should be called in certain cases to sync the internal state
606  * of the trustdb with the file image.  Currently it is needed after
607  * a sequence of insert_trust_record() calls.
608  */
609 void
610 sync_trustdb()
611 {
612     if( fresh_imported_keys && fresh_imported_keys_count )
613         mark_fresh_keys();
614 }
615
616
617 \f
618 /***********************************************
619  *************  Print helpers   ****************
620  ***********************************************/
621 static void
622 print_user_id( FILE *fp, const char *text, u32 *keyid )
623 {
624     char *p;
625     size_t n;
626
627     p = get_user_id( keyid, &n );
628     if( fp ) {
629         fprintf( fp, "%s \"", text );
630         print_utf8_string( fp, p, n );
631         putc('\"', fp);
632         putc('\n', fp);
633     }
634     else {
635         tty_printf( "%s \"", text );
636         tty_print_utf8_string( p, n );
637         tty_printf( "\"\n" );
638     }
639     gcry_free(p);
640 }
641
642
643
644 /****************
645  * This function returns a letter for a trustvalue  Trust flags
646  * are ignore.
647  */
648 int
649 trust_letter( unsigned value )
650 {
651     switch( (value & TRUST_MASK) ) {
652       case TRUST_UNKNOWN:   return '-';
653       case TRUST_EXPIRED:   return 'e';
654       case TRUST_UNDEFINED: return 'q';
655       case TRUST_NEVER:     return 'n';
656       case TRUST_MARGINAL:  return 'm';
657       case TRUST_FULLY:     return 'f';
658       case TRUST_ULTIMATE:  return 'u';
659       default:              return  0 ;
660     }
661 }
662
663
664 #if 0
665 static void
666 print_path( int pathlen, TN ME .........., FILE *fp, ulong highlight )
667 {
668     int rc, c, i;
669     u32 keyid[2];
670     char *p;
671     size_t n;
672
673     for( i = 0; i < pathlen; i++ )  {
674         if( highlight )
675             fputs(highlight == path[i].lid? "* ":"  ", fp );
676         rc = keyid_from_lid( path[i].lid, keyid );
677         if( rc )
678             fprintf(fp, "????????.%lu:", path[i].lid );
679         else
680             fprintf(fp,"%08lX.%lu:", (ulong)keyid[1], path[i].lid );
681         c = trust_letter(path[i].otrust);
682         if( c )
683             putc( c, fp );
684         else
685             fprintf( fp, "%02x", path[i].otrust );
686         putc('/', fp);
687         c = trust_letter(path[i].trust);
688         if( c )
689             putc( c, fp );
690         else
691             fprintf( fp, "%02x", path[i].trust );
692         putc(' ', fp);
693         p = get_user_id( keyid, &n );
694         putc(' ', fp);
695         putc('\"', fp);
696         print_utf8_string( fp, p, n > 40? 40:n );
697         putc('\"', fp);
698         gcry_free(p);
699         putc('\n', fp );
700     }
701 }
702 #endif
703
704
705 static void
706 print_default_uid( FILE *fp, ulong lid )
707 {
708     u32 keyid[2];
709
710     if( !keyid_from_lid( lid, keyid ) )
711         print_user_id( fp, "", keyid );
712 }
713
714
715 static void
716 print_uid_from_keyblock( FILE *fp, KBNODE keyblock, ulong urecno )
717 {
718     TRUSTREC urec;
719     KBNODE node;
720     byte uhash[20];
721
722     read_record( urecno, &urec, RECTYPE_UID );
723     for( node=keyblock; node; node = node->next ) {
724         if( node->pkt->pkttype == PKT_USER_ID ) {
725             PKT_user_id *uidpkt = node->pkt->pkt.user_id;
726
727             if( uidpkt->photo ) {
728                 gcry_md_hash_buffer( GCRY_MD_RMD160,  uhash,
729                                      uidpkt->photo, uidpkt->photolen );
730             }
731             else {
732                 gcry_md_hash_buffer( GCRY_MD_RMD160,  uhash,
733                                      uidpkt->name, uidpkt->len );
734             }
735             if( !memcmp( uhash, urec.r.uid.namehash, 20 ) ) {
736                 print_string( fp,  uidpkt->name, uidpkt->len, ':' );
737                 return;
738             }
739         }
740     }
741
742     fputs("[?]", fp );
743 }
744
745
746
747 static void
748 dump_tn_tree( FILE *fp, int level, TN tree )
749 {
750     TN kr, ur;
751
752     for( kr=tree; kr; kr = kr->next ) {
753         if( fp ) {
754             fprintf( fp, "%*s", level*4, "" );
755             fprintf( fp, "K%lu(ot=%d,val=%d)  ", kr->lid,
756                                              kr->n.k.ownertrust,
757                                              kr->n.k.validity  );
758         }
759         else {
760             tty_printf("%*s", level*4, "" );
761             tty_printf("K%lu(ot=%d,val=%d)  ", kr->lid,
762                                              kr->n.k.ownertrust,
763                                              kr->n.k.validity  );
764         }
765         print_default_uid( fp, kr->lid );
766         for( ur=kr->list; ur; ur = ur->next ) {
767             if( fp ) {
768                 fprintf(fp, "%*s  ", level*4, "" );
769                 fprintf(fp, "U%lu(mc=%d,fc=%d,val=%d)\n", ur->lid,
770                                                      ur->n.u.marginal_count,
771                                                      ur->n.u.fully_count,
772                                                      ur->n.u.validity
773                                                 );
774             }
775             else {
776                 tty_printf("%*s  ", level*4, "" );
777                 tty_printf("U%lu(mc=%d,fc=%d,val=%d)\n", ur->lid,
778                                                      ur->n.u.marginal_count,
779                                                      ur->n.u.fully_count,
780                                                      ur->n.u.validity
781                                                 );
782             }
783             dump_tn_tree( fp, level+1, ur->list );
784         }
785     }
786 }
787
788 /****************
789  * Special version of dump_tn_tree, which prints it colon delimited.
790  * Format:
791  *   level:keyid:type:recno:ot:val:mc:cc:name:
792  * With TYPE = U for a user ID
793  *             K for a key
794  * The RECNO is either the one of the dir record or the one of the uid record.
795  * OT is the the usual trust letter and only availabel on K lines.
796  * VAL is the calcualted validity
797  * MC is the marginal trust counter and only available on U lines
798  * CC is the same for the complete count
799  * NAME ist the username and only printed on U lines
800  */
801 static void
802 dump_tn_tree_with_colons( int level, TN tree )
803 {
804     TN kr, ur;
805
806     for( kr=tree; kr; kr = kr->next ) {
807         KBNODE kb = NULL;
808         u32 kid[2];
809
810         keyid_from_lid( kr->lid, kid );
811         get_keyblock_bylid( &kb, kr->lid );
812
813         printf( "%d:%08lX%08lX:K:%lu:%c:%c::::\n",
814                         level, (ulong)kid[0], (ulong)kid[1], kr->lid,
815                         trust_letter( kr->n.k.ownertrust ),
816                         trust_letter( kr->n.k.validity ) );
817         for( ur=kr->list; ur; ur = ur->next ) {
818             printf( "%d:%08lX%08lX:U:%lu::%c:%d:%d:",
819                         level, (ulong)kid[0], (ulong)kid[1], ur->lid,
820                         trust_letter( kr->n.u.validity ),
821                         ur->n.u.marginal_count,
822                         ur->n.u.fully_count );
823             print_uid_from_keyblock( stdout, kb, ur->lid );
824             putchar(':');
825             putchar('\n');
826             dump_tn_tree_with_colons( level+1, ur->list );
827         }
828         release_kbnode( kb );
829     }
830 }
831
832
833 \f
834 /***********************************************
835  *************  trustdb maintenance  ***********
836  ***********************************************/
837
838 /****************
839  * Create or update shadow dir record and return the LID of the record
840  */
841 static ulong
842 create_shadow_dir( PKT_signature *sig )
843 {
844     TRUSTREC sdir;
845     int rc;
846
847     /* first see whether we already have such a record */
848     rc = tdbio_search_sdir( sig->keyid, sig->pubkey_algo, &sdir );
849     if( rc && rc != -1 ) {
850         log_error("tdbio_search_sdir failed: %s\n", gpg_errstr(rc));
851         tdbio_invalid();
852     }
853     if( rc == -1 ) { /* not found: create */
854         memset( &sdir, 0, sizeof sdir );
855         sdir.recnum = tdbio_new_recnum();
856         sdir.rectype= RECTYPE_SDIR;
857         sdir.r.sdir.lid = sdir.recnum;
858         sdir.r.sdir.keyid[0] = sig->keyid[0];
859         sdir.r.sdir.keyid[1] = sig->keyid[1];
860         sdir.r.sdir.pubkey_algo = sig->pubkey_algo;
861         write_record( &sdir );
862     }
863     return sdir.recnum;
864 }
865
866
867 static ulong
868 find_or_create_lid( PKT_signature *sig )
869 {
870     ulong lid;
871
872     lid = lid_from_keyid_no_sdir( sig->keyid );
873     if( !lid )
874         lid = create_shadow_dir( sig );
875     return lid;
876 }
877
878
879
880 /****************
881  * Check the validity of a key and calculate the keyflags
882  * keynode points to
883  * a node with a [sub]key.  mainkid has the key ID of the primary key
884  * keyblock is the complete keyblock which is needed for signature
885  * checking.  LID and PK is only used in verbose mode.
886  */
887 static unsigned int
888 check_keybinding( KBNODE keyblock, KBNODE keynode, u32 *mainkid,
889                   ulong lid, PKT_public_key *pk )
890 {
891     KBNODE node;
892     int keybind_seen = 0;
893     int revoke_seen = 0;
894     unsigned int keyflags=0;
895     int is_main = (keynode->pkt->pkttype == PKT_PUBLIC_KEY);
896     int rc;
897
898     if( DBG_TRUST )
899         log_debug("check_keybinding: %08lX.%lu\n",
900                             (ulong)mainkid[1], lid );
901
902     if( is_main ) {
903         /* a primary key is always valid (user IDs are handled elsewhere)*/
904         keyflags = KEYF_CHECKED | KEYF_VALID;
905     }
906
907     for( node=keynode->next; node; node = node->next ) {
908         PKT_signature *sig;
909
910         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
911             break; /* ready */
912         if( node->pkt->pkttype != PKT_SIGNATURE )
913             continue; /* don't care about other packets */
914
915         sig = node->pkt->pkt.signature;
916
917         if( mainkid[0] != sig->keyid[0] || mainkid[1] != sig->keyid[1] )
918             continue; /* we only care about self-signatures */
919
920         if( sig->sig_class == 0x18 && !keybind_seen && !is_main ) {
921             /* check until we find a valid keybinding */
922             rc = check_key_signature( keyblock, node, NULL );
923             if( !rc ) {
924                 if( opt.verbose )
925                     log_info(_("key %08lX.%lu: Good subkey binding\n"),
926                                      (ulong)keyid_from_pk(pk,NULL), lid );
927                 keyflags |= KEYF_CHECKED | KEYF_VALID;
928             }
929             else {
930                 log_info(_(
931                   "key %08lX.%lu: Invalid subkey binding: %s\n"),
932                     (ulong)keyid_from_pk(pk,NULL), lid, gpg_errstr(rc) );
933                 keyflags |= KEYF_CHECKED;
934                 keyflags &= ~KEYF_VALID;
935             }
936             keybind_seen = 1;
937         }
938         else if( sig->sig_class == 0x20 && !revoke_seen ) {
939             /* this is a key revocation certificate: check it */
940             rc = check_key_signature( keyblock, node, NULL );
941             if( !rc ) {
942                 if( opt.verbose )
943                     log_info(_("key %08lX.%lu: Valid key revocation\n"),
944                                  (ulong)keyid_from_pk(pk, NULL), lid );
945                 keyflags |= KEYF_REVOKED;
946             }
947             else {
948                 log_info(_(
949                   "key %08lX.%lu: Invalid key revocation: %s\n"),
950                   (ulong)keyid_from_pk(pk,NULL), lid, gpg_errstr(rc) );
951             }
952             revoke_seen = 1;
953         }
954         else if( sig->sig_class == 0x28 && !revoke_seen && !is_main ) {
955             /* this is a subkey revocation certificate: check it */
956             rc = check_key_signature( keyblock, node, NULL );
957             if( !rc ) {
958                 if( opt.verbose )
959                     log_info(_(
960                         "key %08lX.%lu: Valid subkey revocation\n"),
961                          (ulong)keyid_from_pk(pk,NULL), lid );
962                 keyflags |= KEYF_REVOKED;
963             }
964             else {
965                 log_info(_(
966                   "key %08lX.%lu: Invalid subkey binding: %s\n"),
967                   (ulong)keyid_from_pk(pk,NULL), lid, gpg_errstr(rc) );
968             }
969             revoke_seen = 1;
970         }
971         /* Hmmm: should we handle direct key signatures here? */
972     }
973
974     return keyflags;
975 }
976
977
978 static ulong
979 make_key_records( KBNODE keyblock, ulong lid, u32 *keyid, int *mainrev )
980 {
981     TRUSTREC *krecs, **kend, *k, *k2;
982     KBNODE  node;
983     PKT_public_key *pk;
984     byte fpr[MAX_FINGERPRINT_LEN];
985     size_t fprlen;
986     ulong keyrecno;
987
988     *mainrev = 0;
989     krecs = NULL; kend = &krecs;
990     for( node=keyblock; node; node = node->next ) {
991         if( node->pkt->pkttype != PKT_PUBLIC_KEY
992             && node->pkt->pkttype != PKT_PUBLIC_SUBKEY )
993             continue;
994         pk = node->pkt->pkt.public_key;
995         fingerprint_from_pk( pk, fpr, &fprlen );
996
997         /* create the key record */
998         k = gcry_xcalloc( 1, sizeof *k );
999         k->rectype = RECTYPE_KEY;
1000         k->r.key.lid = lid;
1001         k->r.key.pubkey_algo = pk->pubkey_algo;
1002         k->r.key.fingerprint_len = fprlen;
1003         memcpy(k->r.key.fingerprint, fpr, fprlen );
1004         k->recnum = tdbio_new_recnum();
1005         *kend = k;
1006         kend = &k->next;
1007
1008         k->r.key.keyflags = check_keybinding( keyblock, node, keyid, lid, pk );
1009         if( (k->r.key.keyflags & KEYF_REVOKED)
1010             && node->pkt->pkttype == PKT_PUBLIC_KEY )
1011             *mainrev = 1;
1012     }
1013
1014     keyrecno = krecs? krecs->recnum : 0;
1015     /* write the keylist and release the memory */
1016     for( k = krecs; k ; k = k2 ) {
1017         if( k->next )
1018             k->r.key.next = k->next->recnum;
1019         write_record( k );
1020         k2 = k->next;
1021         gcry_free( k );
1022     }
1023     return keyrecno;
1024 }
1025
1026
1027 /****************
1028  * Check the validity of a user ID and calculate the uidflags
1029  * keynode points to  a node with a user ID.
1030  * mainkid has the key ID of the primary key, keyblock is the complete
1031  * keyblock which is needed for signature checking.
1032  * Returns: The uid flags and the self-signature which is considered to
1033  * be the most current.
1034  */
1035 static unsigned int
1036 check_uidsigs( KBNODE keyblock, KBNODE keynode, u32 *mainkid, ulong lid,
1037                                                   PKT_signature **bestsig )
1038 {
1039     KBNODE node;
1040     unsigned int uidflags = 0;
1041     PKT_signature *sig;
1042     PKT_signature *selfsig = NULL; /* the latest valid self signature */
1043     int rc;
1044
1045     if( DBG_TRUST ) {
1046         PKT_user_id *uid;
1047         log_debug("check_uidsigs: %08lX.%lu \"",
1048                             (ulong)mainkid[1], lid );
1049         assert(keynode->pkt->pkttype == PKT_USER_ID );
1050         uid = keynode->pkt->pkt.user_id;
1051         print_string( log_stream(), uid->name, uid->len, '\"' );
1052         fputs("\"\n", log_stream());
1053     }
1054
1055     /* first we check only the selfsignatures */
1056     for( node=keynode->next; node; node = node->next ) {
1057         if( node->pkt->pkttype == PKT_USER_ID
1058             || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
1059             break; /* ready */
1060         if( node->pkt->pkttype != PKT_SIGNATURE )
1061             continue; /* don't care about other packets */
1062         sig = node->pkt->pkt.signature;
1063         if( mainkid[0] != sig->keyid[0] || mainkid[1] != sig->keyid[1] )
1064             continue; /* we only care about self-signatures for now */
1065
1066         if( (sig->sig_class&~3) == 0x10 ) { /* regular self signature */
1067             rc = check_key_signature( keyblock, node, NULL );
1068             if( !rc ) {
1069                 if( opt.verbose )
1070                     log_info( "uid %08lX.%lu: %s\n",
1071                        (ulong)mainkid[1], lid, _("Good self-signature") );
1072                 uidflags |= UIDF_CHECKED | UIDF_VALID;
1073                 if( !selfsig )
1074                     selfsig = sig; /* use the first valid sig */
1075                 else if( sig->timestamp > selfsig->timestamp
1076                          && sig->sig_class >= selfsig->sig_class )
1077                     selfsig = sig; /* but this one is newer */
1078             }
1079             else {
1080                 log_info( "uid %08lX: %s: %s\n",
1081                            (ulong)mainkid[1], _("Invalid self-signature"),
1082                            gpg_errstr(rc) );
1083                 uidflags |= UIDF_CHECKED;
1084             }
1085         }
1086     }
1087
1088     /* and now check for revocations - we must do this after the
1089      * self signature check because a self-signature which is newer
1090      * than a revocation makes the revocation invalid.
1091      * RFC2440 is quiet about tis but I feel this is reasonable for
1092      * non-primary-key revocations. */
1093     for( node=keynode->next; node; node = node->next ) {
1094         if( node->pkt->pkttype == PKT_USER_ID
1095             || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
1096             break; /* ready */
1097         if( node->pkt->pkttype != PKT_SIGNATURE )
1098             continue; /* don't care about other packets */
1099         sig = node->pkt->pkt.signature;
1100         if( mainkid[0] != sig->keyid[0] || mainkid[1] != sig->keyid[1] )
1101             continue; /* we only care about self-signatures for now */
1102
1103         if( sig->sig_class == 0x30 ) { /* cert revocation */
1104             rc = check_key_signature( keyblock, node, NULL );
1105             if( !rc && selfsig && selfsig->timestamp > sig->timestamp ) {
1106                 log_info( "uid %08lX.%lu: %s\n",
1107                        (ulong)mainkid[1], lid,
1108                        _("Valid user ID revocation skipped "
1109                          "due to a newer self signature") );
1110             }
1111             else if( !rc ) {
1112                 if( opt.verbose )
1113                     log_info( "uid %08lX.%lu: %s\n",
1114                        (ulong)mainkid[1], lid, _("Valid user ID revocation") );
1115                 uidflags |= UIDF_CHECKED | UIDF_VALID | UIDF_REVOKED;
1116             }
1117             else {
1118                 log_info("uid %08lX: %s: %s\n",
1119                             (ulong)mainkid[1], _("Invalid user ID revocation"),
1120                                                     gpg_errstr(rc) );
1121             }
1122         }
1123     }
1124
1125     *bestsig = selfsig;
1126     return uidflags;
1127 }
1128
1129
1130 static unsigned int
1131 check_sig_record( KBNODE keyblock, KBNODE signode,
1132                   ulong siglid, int sigidx, u32 *keyid, ulong lid,
1133                   u32 *r_expiretime, int *mod_down, int *mod_up )
1134 {
1135     PKT_signature *sig = signode->pkt->pkt.signature;
1136     unsigned int sigflag = 0;
1137     TRUSTREC tmp;
1138     int revocation=0, expired=0, rc;
1139
1140     if( DBG_TRUST )
1141         log_debug("check_sig_record: %08lX.%lu %lu[%d]\n",
1142                             (ulong)keyid[1], lid, siglid, sigidx );
1143     *r_expiretime = 0;
1144     if( (sig->sig_class&~3) == 0x10 ) /* regular certification */
1145         ;
1146     else if( sig->sig_class == 0x30 ) /* cert revocation */
1147         revocation = 1;
1148     else
1149         return SIGF_CHECKED | SIGF_IGNORED;
1150
1151     read_record( siglid, &tmp, 0 );
1152     if( tmp.rectype == RECTYPE_DIR ) {
1153         /* the public key is in the trustdb: check sig */
1154         rc = check_key_signature2( keyblock, signode, NULL,
1155                                              r_expiretime, &expired );
1156         if( !rc ) { /* valid signature */
1157             if( opt.verbose )
1158                 log_info("sig %08lX.%lu/%lu[%d]/%08lX: %s\n",
1159                         (ulong)keyid[1], lid, siglid, sigidx,
1160                                                 (ulong)sig->keyid[1],
1161                         revocation? _("Valid certificate revocation")
1162                                   : _("Good certificate") );
1163             sigflag |= SIGF_CHECKED | SIGF_VALID;
1164             if( expired ) {
1165                 sigflag |= SIGF_EXPIRED;
1166                 /* We have to reset the expiretime, so that this signature
1167                  * does not get checked over and over due to the reached
1168                  * expiretime */
1169                 *r_expiretime = 0;
1170             }
1171             if( revocation ) {
1172                 sigflag |= SIGF_REVOKED;
1173                 *mod_down = 1;
1174             }
1175             else
1176                 *mod_up = 1;
1177         }
1178         else if( rc == GPGERR_NO_PUBKEY ) {
1179             /* This may happen if the key is still in the trustdb
1180              * but not available in the keystorage */
1181             sigflag |= SIGF_NOPUBKEY;
1182             *mod_down = 1;
1183             if( revocation )
1184                 sigflag |= SIGF_REVOKED;
1185         }
1186         else {
1187             log_info("sig %08lX.%lu/%lu[%d]/%08lX: %s: %s\n",
1188                         (ulong)keyid[1], lid, siglid, sigidx,
1189                                                 (ulong)sig->keyid[1],
1190                         revocation? _("Invalid certificate revocation")
1191                                    : _("Invalid certificate"),
1192                                             gpg_errstr(rc));
1193             sigflag |= SIGF_CHECKED;
1194             if( revocation ) {
1195                 sigflag |= SIGF_REVOKED;
1196                 *mod_down = 1;
1197             }
1198         }
1199     }
1200     else if( tmp.rectype == RECTYPE_SDIR ) {
1201         /* better check that it is the right one */
1202         if(    tmp.r.sdir.keyid[0] == sig->keyid[0]
1203             && tmp.r.sdir.keyid[1] == sig->keyid[1]
1204             && (!tmp.r.sdir.pubkey_algo
1205                  || tmp.r.sdir.pubkey_algo == sig->pubkey_algo ))
1206             sigflag |= SIGF_NOPUBKEY;
1207         else
1208             log_error(_("sig record %lu[%d] points to wrong record.\n"),
1209                          siglid, sigidx );
1210     }
1211     else {
1212         log_error(_("sig record %lu[%d] points to wrong record.\n"),
1213                     siglid, sigidx );
1214         tdbio_invalid();
1215     }
1216
1217     return sigflag;
1218 }
1219
1220 /****************
1221  * Make the sig records for the given uid record
1222  * We don't set flags here or even check the signatures; this will
1223  * happen latter.
1224  */
1225 static ulong
1226 make_sig_records( KBNODE keyblock, KBNODE uidnode,
1227                   ulong lid, u32 *mainkid, u32 *min_expire,
1228                                         int *mod_down, int *mod_up  )
1229 {
1230     TRUSTREC *srecs, **s_end, *s=NULL, *s2;
1231     KBNODE  node;
1232     PKT_signature *sig;
1233     ulong sigrecno, siglid;
1234     int i, sigidx = 0;
1235     u32 expiretime;
1236
1237     srecs = NULL; s_end = &srecs;
1238     for( node=uidnode->next; node; node = node->next ) {
1239         if( node->pkt->pkttype == PKT_USER_ID
1240             || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
1241             break; /* ready */
1242         if( node->pkt->pkttype != PKT_SIGNATURE )
1243             continue; /* don't care about other packets */
1244         sig = node->pkt->pkt.signature;
1245         if( mainkid[0] == sig->keyid[0] && mainkid[1] == sig->keyid[1] )
1246             continue; /* we don't care about self-signatures here */
1247
1248         siglid = find_or_create_lid( sig );
1249         /* smash dups */
1250         /* FIXME: Here we have a problem:
1251          *  We can't distinguish between a certification and a certification
1252          *  revocation without looking at class of the signature - we have
1253          *  to see how we can store the sigclass in the sigrecord..
1254          *  Argg- I hope I can get rid of this ugly trustdb ASAP.
1255          */
1256         for( s2 = s; s2 ; s2 = s2->next ) {
1257             for(i=0; i < sigidx; i++ ) {
1258                 if( s2->r.sig.sig[i].lid == siglid )
1259                     goto leaveduptest;
1260             }
1261         }
1262         for( s2 = srecs; s2 ; s2 = s2->next ) {
1263             for(i=0; i < SIGS_PER_RECORD; i++ ) {
1264                 if( s2->r.sig.sig[i].lid == siglid )
1265                     goto leaveduptest;
1266             }
1267         }
1268       leaveduptest:
1269         if( s2 ) {
1270             log_info( "sig %08lX.%lu: %s\n", (ulong)mainkid[1], lid,
1271                                     _("duplicated certificate - deleted") );
1272             continue;
1273         }
1274
1275         /* create the sig record */
1276         if( !sigidx ) {
1277             s = gcry_xcalloc( 1, sizeof *s );
1278             s->rectype = RECTYPE_SIG;
1279             s->r.sig.lid = lid;
1280         }
1281         s->r.sig.sig[sigidx].lid = siglid;
1282         s->r.sig.sig[sigidx].flag= check_sig_record( keyblock, node,
1283                                                      siglid, sigidx,
1284                                                      mainkid, lid, &expiretime,
1285                                                      mod_down, mod_up );
1286
1287         sigidx++;
1288         if( sigidx == SIGS_PER_RECORD ) {
1289             s->recnum = tdbio_new_recnum();
1290             *s_end = s;
1291             s_end = &s->next;
1292             sigidx = 0;
1293         }
1294         /* keep track of signers pk expire time */
1295         if( expiretime && (!*min_expire || *min_expire > expiretime ) )
1296             *min_expire = expiretime;
1297     }
1298     if( sigidx ) {
1299        s->recnum = tdbio_new_recnum();
1300        *s_end = s;
1301        s_end = &s->next;
1302     }
1303
1304     sigrecno = srecs? srecs->recnum : 0;
1305     /* write the keylist and release the memory */
1306     for( s = srecs; s ; s = s2 ) {
1307         if( s->next )
1308             s->r.sig.next = s->next->recnum;
1309         write_record( s );
1310         s2 = s->next;
1311         gcry_free( s );
1312     }
1313     return sigrecno;
1314 }
1315
1316
1317
1318 /****************
1319  * Make a preference record (or a list of them) according to the supplied
1320  * signature.
1321  * Returns: The record number of the first pref record.
1322  */
1323 static ulong
1324 make_pref_record( PKT_signature *sig, ulong lid )
1325 {
1326     static struct {
1327         sigsubpkttype_t subpkttype;
1328         int preftype;
1329     } ptable[] = {
1330         { SIGSUBPKT_PREF_SYM,   PREFTYPE_SYM    },
1331         { SIGSUBPKT_PREF_HASH,  PREFTYPE_HASH   },
1332         { SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR  },
1333         { 0, 0 }
1334     };
1335     TRUSTREC *precs, **p_end, *p=NULL, *p2;
1336     ulong precno;
1337     int k, idx=0;
1338     const byte *s;
1339     size_t n;
1340
1341   #if (ITEMS_PER_PREF_RECORD % 2) != 0
1342     #error ITEMS_PER_PREF_RECORD must have an even value
1343   #endif
1344
1345     precs = NULL; p_end = &precs;
1346     for(k=0; ptable[k].subpkttype; k++ ) {
1347         s = parse_sig_subpkt2( sig, ptable[k].subpkttype, &n );
1348         if( !s )
1349             continue;
1350         for( ; n; n--, s++ ) {
1351             if( !idx ) {
1352                 p = gcry_xcalloc( 1, sizeof *p );
1353                 p->rectype = RECTYPE_PREF;
1354                 p->r.pref.lid = lid;
1355             }
1356             p->r.pref.data[idx++] = ptable[k].preftype;
1357             p->r.pref.data[idx++] = *s;
1358             if( idx >= ITEMS_PER_PREF_RECORD ) {
1359                 p->recnum = tdbio_new_recnum();
1360                 *p_end = p;
1361                 p_end = &p->next;
1362                 idx = 0;
1363             }
1364         }
1365     }
1366     if( idx ) {
1367        p->recnum = tdbio_new_recnum();
1368        *p_end = p;
1369        p_end = &p->next;
1370     }
1371
1372     precno = precs? precs->recnum : 0;
1373     /* write the precs and release the memory */
1374     for( p = precs; p ; p = p2 ) {
1375         if( p->next )
1376             p->r.pref.next = p->next->recnum;
1377         write_record( p );
1378         p2 = p->next;
1379         gcry_free( p );
1380     }
1381     return precno;
1382 }
1383
1384
1385 static ulong
1386 make_uid_records( KBNODE keyblock, ulong lid, u32 *keyid, u32 *min_expire,
1387                                                  int *mod_down, int *mod_up )
1388 {
1389     TRUSTREC *urecs, **uend, *u, *u2;
1390     KBNODE  node;
1391     PKT_user_id *uid;
1392     byte uidhash[20];
1393     ulong uidrecno;
1394
1395     urecs = NULL; uend = &urecs;
1396     for( node=keyblock; node; node = node->next ) {
1397         PKT_signature *bestsig;
1398
1399         if( node->pkt->pkttype != PKT_USER_ID )
1400             continue;
1401         uid = node->pkt->pkt.user_id;
1402         if( uid->photo ) {
1403             gcry_md_hash_buffer( GCRY_MD_RMD160,  uidhash,
1404                                  uid->photo, uid->photolen );
1405         }
1406         else {
1407             gcry_md_hash_buffer( GCRY_MD_RMD160,  uidhash,
1408                                  uid->name, uid->len );
1409         }
1410
1411         /* create the uid record */
1412         u = gcry_xcalloc( 1, sizeof *u );
1413         u->rectype = RECTYPE_UID;
1414         u->r.uid.lid = lid;
1415         memcpy(u->r.uid.namehash, uidhash, 20 );
1416         u->recnum = tdbio_new_recnum();
1417         *uend = u;
1418         uend = &u->next;
1419
1420         u->r.uid.uidflags = check_uidsigs( keyblock, node, keyid,
1421                                                      lid, &bestsig );
1422         if( (u->r.uid.uidflags & UIDF_CHECKED)
1423             && (u->r.uid.uidflags & UIDF_VALID) ) {
1424             u->r.uid.prefrec = bestsig? make_pref_record( bestsig, lid ) : 0;
1425         }
1426
1427         /* the next test is really bad because we should modify
1428          * out modification timestamps only if we really have a change.
1429          * But because we are deleting the uid records first it is somewhat
1430          * difficult to track those changes.  fixme */
1431         if(   !( u->r.uid.uidflags & UIDF_VALID )
1432             || ( u->r.uid.uidflags & UIDF_REVOKED ) )
1433             *mod_down=1;
1434         else
1435             *mod_up=1;
1436
1437         /* create the list of signatures */
1438         u->r.uid.siglist = make_sig_records( keyblock, node,
1439                                              lid, keyid, min_expire,
1440                                              mod_down, mod_up );
1441     }
1442
1443     uidrecno = urecs? urecs->recnum : 0;
1444     /* write the uidlist and release the memory */
1445     for( u = urecs; u ; u = u2 ) {
1446         if( u->next )
1447             u->r.uid.next = u->next->recnum;
1448         write_record( u );
1449         u2 = u->next;
1450         gcry_free( u );
1451     }
1452     return uidrecno;
1453 }
1454
1455
1456
1457 /****************
1458  * Update all the info from the public keyblock.
1459  * The key must already exist in the keydb.
1460  */
1461 int
1462 update_trust_record( KBNODE keyblock, int recheck, int *modified )
1463 {
1464     TRUSTREC drec;
1465     int rc;
1466
1467     /* NOTE: We don't need recheck anymore, but this might chnage again in
1468      * the future */
1469     if( opt.dry_run )
1470         return 0;
1471     if( modified )
1472         *modified = 0;
1473     init_trustdb();
1474     rc = get_dir_record( find_kbnode( keyblock, PKT_PUBLIC_KEY )
1475                                             ->pkt->pkt.public_key, &drec );
1476     if( rc )
1477         return rc;
1478
1479     rc = do_update_trust_record( keyblock, &drec, 0, modified );
1480     return rc;
1481 }
1482
1483 /****************
1484  * Same as update_trust_record, but this functions expects the dir record.
1485  * On exit the dir record will reflect any changes made.
1486  * With sigs_only set only foreign key signatures are checked.
1487  */
1488 static int
1489 do_update_trust_record( KBNODE keyblock, TRUSTREC *drec,
1490                         int sigs_only, int *modified )
1491 {
1492     PKT_public_key *primary_pk;
1493     TRUSTREC krec, urec, prec, helprec;
1494     int i, rc = 0;
1495     u32 keyid[2]; /* keyid of primary key */
1496     int mod_up = 0;
1497     int mod_down = 0;
1498     ulong recno, r2;
1499     u32 expiretime;
1500
1501     primary_pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )->pkt->pkt.public_key;
1502     if( !primary_pk->local_id )
1503         primary_pk->local_id = drec->recnum;
1504
1505     keyid_from_pk( primary_pk, keyid );
1506     if( DBG_TRUST )
1507         log_debug("do_update_trust_record: %08lX.%lu\n",
1508                                         (ulong)keyid[1], drec->recnum );
1509
1510     rc = tdbio_begin_transaction();
1511     if( rc )
1512         return rc;
1513
1514     /* delete the old stuff FIXME: implementend sigs_only */
1515     for( recno=drec->r.dir.keylist; recno; recno = krec.r.key.next ) {
1516         read_record( recno, &krec, RECTYPE_KEY );
1517         delete_record( recno );
1518     }
1519     drec->r.dir.keylist = 0;
1520     for( recno=drec->r.dir.uidlist; recno; recno = urec.r.uid.next ) {
1521         read_record( recno, &urec, RECTYPE_UID );
1522         for(r2=urec.r.uid.prefrec ; r2; r2 = prec.r.pref.next ) {
1523             read_record( r2, &prec, RECTYPE_PREF );
1524             delete_record( r2 );
1525         }
1526         for(r2=urec.r.uid.siglist ; r2; r2 = helprec.r.sig.next ) {
1527             read_record( r2, &helprec, RECTYPE_SIG );
1528             delete_record( r2 );
1529         }
1530         delete_record( recno );
1531     }
1532     drec->r.dir.uidlist = 0;
1533
1534
1535     /* insert new stuff */
1536     drec->r.dir.dirflags &= ~DIRF_REVOKED;
1537     drec->r.dir.dirflags &= ~DIRF_NEWKEYS;
1538     drec->r.dir.keylist = make_key_records( keyblock, drec->recnum, keyid, &i );
1539     if( i ) /* primary key has been revoked */
1540         drec->r.dir.dirflags |= DIRF_REVOKED;
1541     expiretime = 0;
1542     drec->r.dir.uidlist = make_uid_records( keyblock, drec->recnum, keyid,
1543                                             &expiretime, &mod_down, &mod_up );
1544     if( rc )
1545         rc = tdbio_cancel_transaction();
1546     else {
1547         if( modified && tdbio_is_dirty() )
1548             *modified = 1;
1549         drec->r.dir.dirflags |= DIRF_CHECKED;
1550         drec->r.dir.valcheck = 0;
1551         drec->r.dir.checkat = expiretime;
1552         write_record( drec );
1553         tdbio_write_modify_stamp( mod_up, mod_down );
1554         rc = tdbio_end_transaction();
1555     }
1556     return rc;
1557 }
1558
1559
1560
1561 /****************
1562  * Insert a trust record into the TrustDB
1563  * This function assumes that the record does not yet exist.
1564  */
1565 int
1566 insert_trust_record( KBNODE keyblock )
1567 {
1568     TRUSTREC dirrec;
1569     TRUSTREC shadow;
1570     KBNODE node;
1571     int rc = 0;
1572     PKT_public_key *pk;
1573
1574
1575     if( opt.dry_run )
1576         return 0;
1577
1578     init_trustdb();
1579
1580     pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )->pkt->pkt.public_key;
1581     if( pk->local_id ) {
1582         log_debug("insert_trust_record with pk->local_id=%lu (2)\n",
1583                                                         pk->local_id );
1584         rc = update_trust_record( keyblock, 1, NULL );
1585         return rc;
1586     }
1587
1588     /* We have to look for a shadow dir record which must be reused
1589      * as the dir record. */
1590     rc = tdbio_search_sdir( pk->keyid, pk->pubkey_algo, &shadow );
1591     if( rc && rc != -1 ) {
1592         log_error(_("tdbio_search_dir failed: %s\n"), gpg_errstr(rc));
1593         tdbio_invalid();
1594     }
1595     memset( &dirrec, 0, sizeof dirrec );
1596     dirrec.rectype = RECTYPE_DIR;
1597     if( !rc ) /* we have a shadow dir record - convert to dir record */
1598         dirrec.recnum = shadow.recnum;
1599     else
1600         dirrec.recnum = tdbio_new_recnum();
1601     dirrec.r.dir.lid = dirrec.recnum;
1602     write_record( &dirrec );
1603
1604     /* put the LID into the keyblock */
1605     pk->local_id = dirrec.r.dir.lid;
1606     for( node=keyblock; node; node = node->next ) {
1607         if( node->pkt->pkttype == PKT_PUBLIC_KEY
1608             || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
1609             PKT_public_key *a_pk = node->pkt->pkt.public_key;
1610             a_pk->local_id = dirrec.r.dir.lid;
1611         }
1612         else if( node->pkt->pkttype == PKT_SIGNATURE ) {
1613             PKT_signature *a_sig = node->pkt->pkt.signature;
1614             a_sig->local_id = dirrec.r.dir.lid;
1615         }
1616     }
1617
1618
1619     /* mark tdb as modified upwards */
1620     tdbio_write_modify_stamp( 1, 0 );
1621
1622     /* and put all the other stuff into the keydb */
1623     rc = do_update_trust_record( keyblock, &dirrec, 0, NULL );
1624
1625     do_sync();
1626
1627     /* keep track of new keys */
1628     if( !fresh_imported_keys )
1629         fresh_imported_keys = new_lid_table();
1630     ins_lid_table_item( fresh_imported_keys, pk->local_id, 0 );
1631     if( ++fresh_imported_keys_count > FRESH_KEY_CHECK_THRESHOLD )
1632         mark_fresh_keys();
1633
1634     return rc;
1635 }
1636
1637
1638
1639
1640 /****************
1641  * Insert a trust record indentified by a PK into the TrustDB
1642  */
1643 int
1644 insert_trust_record_by_pk( PKT_public_key *pk )
1645 {
1646     KBNODE keyblock = NULL;
1647     byte fingerprint[MAX_FINGERPRINT_LEN];
1648     size_t fingerlen;
1649     int rc;
1650
1651     /* get the keyblock */
1652     fingerprint_from_pk( pk, fingerprint, &fingerlen );
1653     rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
1654     if( rc ) { /* that should never happen */
1655         log_debug( "insert_trust_record_by_pk: keyblock not found: %s\n",
1656                                                           gpg_errstr(rc) );
1657     }
1658     else {
1659         rc = insert_trust_record( keyblock );
1660         if( !rc ) /* copy the LID into the PK */
1661             pk->local_id = find_kbnode( keyblock, PKT_PUBLIC_KEY )
1662                                             ->pkt->pkt.public_key->local_id;
1663     }
1664
1665     release_kbnode( keyblock );
1666     return rc;
1667 }
1668
1669
1670 /****************
1671  * Check one trust record.  This function is called for every
1672  * directory record which is to be checked.  The supplied
1673  * dir record is modified according to the performed actions.
1674  * Currently we only do an update_trust_record.
1675  */
1676 static int
1677 check_trust_record( TRUSTREC *drec, int sigs_only )
1678 {
1679     KBNODE keyblock;
1680     int modified, rc;
1681
1682     rc = get_keyblock_bylid( &keyblock, drec->recnum );
1683     if( rc ) {
1684         log_debug( "check_trust_record %lu: keyblock not found: %s\n",
1685                                               drec->recnum, gpg_errstr(rc) );
1686         return rc;
1687     }
1688
1689     rc = do_update_trust_record( keyblock, drec, sigs_only, &modified );
1690     release_kbnode( keyblock );
1691
1692     return rc;
1693 }
1694
1695
1696 /****************
1697  * Walk over the keyrings and create trustdb records for all keys
1698  * which are not currently in the trustdb.
1699  * It is intended to be used after a fast-import operation.
1700  */
1701 void
1702 update_trustdb()
1703 {
1704     KBNODE keyblock = NULL;
1705     KBPOS kbpos;
1706     int rc;
1707
1708     if( opt.dry_run )
1709         return;
1710
1711     init_trustdb();
1712     rc = enum_keyblocks( 0, &kbpos, &keyblock );
1713     if( !rc ) {
1714         ulong count=0, err_count=0, new_count=0;
1715
1716         while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
1717             /*int modified;*/
1718             TRUSTREC drec;
1719             PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
1720                                         ->pkt->pkt.public_key;
1721
1722             rc = get_dir_record( pk, &drec );
1723             if( rc == -1 ) { /* not in trustdb: insert */
1724                 rc = insert_trust_record( keyblock );
1725                 if( rc && !pk->local_id ) {
1726                     log_error(_("lid ?: insert failed: %s\n"),
1727                                                      gpg_errstr(rc) );
1728                     err_count++;
1729                 }
1730                 else if( rc ) {
1731                     log_error(_("lid %lu: insert failed: %s\n"),
1732                                        pk->local_id, gpg_errstr(rc) );
1733                     err_count++;
1734                 }
1735                 else {
1736                     if( opt.verbose )
1737                         log_info(_("lid %lu: inserted\n"), pk->local_id );
1738                     new_count++;
1739                 }
1740             }
1741             else if( rc ) {
1742                 log_error(_("error reading dir record: %s\n"), gpg_errstr(rc));
1743                 err_count++;
1744             }
1745
1746             release_kbnode( keyblock ); keyblock = NULL;
1747             if( !(++count % 100) )
1748                 log_info(_("%lu keys so far processed\n"), count);
1749         }
1750         log_info(_("%lu keys processed\n"), count);
1751         if( err_count )
1752             log_info(_("\t%lu keys with errors\n"), err_count);
1753         if( new_count )
1754             log_info(_("\t%lu keys inserted\n"), new_count);
1755     }
1756     if( rc && rc != -1 )
1757         log_error(_("enumerate keyblocks failed: %s\n"), gpg_errstr(rc));
1758
1759     enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
1760     release_kbnode( keyblock );
1761 }
1762
1763
1764
1765 /****************
1766  * Do all required checks in the trustdb.  This function walks over all
1767  * records in the trustdb and does scheduled processing.
1768  */
1769 void
1770 check_trustdb( const char *username )
1771 {
1772     TRUSTREC rec;
1773     ulong recnum;
1774     ulong count=0, upd_count=0, err_count=0, skip_count=0, sigonly_count=0;
1775     ulong current_time = make_timestamp();
1776
1777     if( username )
1778         log_info("given user IDs ignored in check_trustdb\n");
1779
1780     init_trustdb();
1781
1782     for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
1783         int sigs_only;
1784
1785         if( rec.rectype != RECTYPE_DIR )
1786             continue; /* we only want the dir records */
1787
1788         if( count && !(count % 100) && !opt.quiet )
1789             log_info(_("%lu keys so far processed\n"), count);
1790         count++;
1791         sigs_only = 0;
1792
1793         if( !(rec.r.dir.dirflags & DIRF_CHECKED) )
1794             ;
1795         else if( !rec.r.dir.checkat || rec.r.dir.checkat > current_time ) {
1796             if( !(rec.r.dir.dirflags & DIRF_NEWKEYS) ) {
1797                 skip_count++;
1798                 continue;  /* not scheduled for checking */
1799             }
1800             sigs_only = 1; /* new public keys - check them */
1801             sigonly_count++;
1802         }
1803
1804         if( !rec.r.dir.keylist ) {
1805             log_info(_("lid %lu: dir record w/o key - skipped\n"), recnum);
1806             skip_count++;
1807             continue;
1808         }
1809
1810         check_trust_record( &rec, sigs_only );
1811     }
1812
1813     log_info(_("%lu keys processed\n"), count);
1814     if( sigonly_count )
1815         log_info(_("\t%lu due to new pubkeys\n"), sigonly_count);
1816     if( skip_count )
1817         log_info(_("\t%lu keys skipped\n"), skip_count);
1818     if( err_count )
1819         log_info(_("\t%lu keys with errors\n"), err_count);
1820     if( upd_count )
1821         log_info(_("\t%lu keys updated\n"), upd_count);
1822 }
1823
1824
1825 \f
1826 /***********************************************
1827  *********  Trust calculation  *****************
1828  ***********************************************/
1829
1830 /****************
1831  * Find all certification paths of a given LID.
1832  * Limit the search to MAX_DEPTH.  stack is a helper variable which
1833  * should have been allocated with size max_depth, stack[0] should
1834  * be setup to the key we are investigating, so the minimal depth
1835  * we should ever see in this function is 1.
1836  * Returns: a new tree
1837  * certchain_set must be a valid set or point to NULL; this function
1838  * may modifiy it.
1839  *
1840  * Hmmm: add a fastscan mode which stops at valid validity nodes.
1841  */
1842 static TN
1843 build_cert_tree( ulong lid, int depth, int max_depth, TN helproot )
1844 {
1845     TRUSTREC dirrec;
1846     TRUSTREC uidrec;
1847     ulong uidrno;
1848     TN keynode;
1849
1850     if( depth >= max_depth )
1851         return NULL;
1852
1853     keynode = new_tn();
1854     if( !helproot )
1855         helproot = keynode;
1856     keynode->lid = lid;
1857     if( !qry_lid_table_flag( ultikey_table, lid, NULL ) ) {
1858         /* this is an ultimately trusted key;
1859          * which means that we have found the end of the chain:
1860          * We do this here prior to reading the dir record
1861          * because we don't really need the info from that record */
1862         keynode->n.k.ownertrust = TRUST_ULTIMATE;
1863         keynode->n.k.buckstop   = 1;
1864         return keynode;
1865     }
1866     read_record( lid, &dirrec, 0 );
1867     if( dirrec.rectype != RECTYPE_DIR ) {
1868         if( dirrec.rectype != RECTYPE_SDIR )
1869             log_debug("lid %lu, has rectype %d"
1870                       " - skipped\n", lid, dirrec.rectype );
1871         gcry_free(keynode);
1872         return NULL;
1873     }
1874
1875     if( dirrec.r.dir.checkat && dirrec.r.dir.checkat <= make_timestamp() ) {
1876         check_trust_record( &dirrec, 0 );
1877     }
1878     else if( (dirrec.r.dir.dirflags & DIRF_NEWKEYS) ) {
1879         check_trust_record( &dirrec, 1 );
1880     }
1881
1882     keynode->n.k.ownertrust = dirrec.r.dir.ownertrust & TRUST_MASK;
1883
1884     /* loop over all user ids */
1885     for( uidrno = dirrec.r.dir.uidlist; uidrno; uidrno = uidrec.r.uid.next ) {
1886         TRUSTREC sigrec;
1887         ulong sigrno;
1888         TN uidnode = NULL;
1889
1890         read_record( uidrno, &uidrec, RECTYPE_UID );
1891
1892         if( !(uidrec.r.uid.uidflags & UIDF_CHECKED) )
1893             continue; /* user id has not been checked */
1894         if( !(uidrec.r.uid.uidflags & UIDF_VALID) )
1895             continue; /* user id is not valid */
1896         if( (uidrec.r.uid.uidflags & UIDF_REVOKED) )
1897             continue; /* user id has been revoked */
1898
1899         /* loop over all signature records */
1900         for(sigrno=uidrec.r.uid.siglist; sigrno; sigrno = sigrec.r.sig.next ) {
1901             int i;
1902             TN tn;
1903
1904             read_record( sigrno, &sigrec, RECTYPE_SIG );
1905
1906             for(i=0; i < SIGS_PER_RECORD; i++ ) {
1907                 if( !sigrec.r.sig.sig[i].lid )
1908                     continue; /* skip deleted sigs */
1909                 if( !(sigrec.r.sig.sig[i].flag & SIGF_CHECKED) )
1910                     continue; /* skip unchecked signatures */
1911                 if( !(sigrec.r.sig.sig[i].flag & SIGF_VALID) )
1912                     continue; /* skip invalid signatures */
1913                 if( (sigrec.r.sig.sig[i].flag & SIGF_EXPIRED) )
1914                     continue; /* skip expired signatures */
1915                 if( (sigrec.r.sig.sig[i].flag & SIGF_REVOKED) )
1916                     continue; /* skip revoked signatures */
1917                 /* check for cycles */
1918                 for( tn=keynode; tn && tn->lid != sigrec.r.sig.sig[i].lid;
1919                                                           tn = tn->back )
1920                     ;
1921                 if( tn )
1922                     continue; /* cycle found */
1923
1924                 tn = build_cert_tree( sigrec.r.sig.sig[i].lid,
1925                                       depth+1, max_depth, helproot );
1926                 if( !tn )
1927                     continue; /* cert chain too deep or error */
1928
1929                 if( !uidnode ) {
1930                     uidnode = new_tn();
1931                     uidnode->back = keynode;
1932                     uidnode->lid = uidrno;
1933                     uidnode->is_uid = 1;
1934                     uidnode->next = keynode->list;
1935                     keynode->list = uidnode;
1936                 }
1937
1938                 tn->back = uidnode;
1939                 tn->next = uidnode->list;
1940                 uidnode->list = tn;
1941                 if( tn->n.k.buckstop ) {
1942                     /* ultimately trusted key found:
1943                      * no need to check more signatures of this uid */
1944                     sigrec.r.sig.next = 0;
1945                     break;
1946                 }
1947             }
1948         } /* end loop over sig recs */
1949     } /* end loop over user ids */
1950
1951     if( !keynode->list ) {
1952         release_tn_tree( keynode );
1953         keynode = NULL;
1954     }
1955
1956     return keynode;
1957 }
1958
1959
1960 static void
1961 upd_one_ownertrust( ulong lid, unsigned new_trust, unsigned *retflgs )
1962 {
1963     TRUSTREC rec;
1964
1965     read_record( lid, &rec, RECTYPE_DIR );
1966     if( DBG_TRUST )
1967         log_debug("upd_one_ownertrust of %lu from %u to %u\n",
1968                            lid, (unsigned)rec.r.dir.ownertrust, new_trust );
1969     if( retflgs ) {
1970         if( (new_trust & TRUST_MASK) > (rec.r.dir.ownertrust & TRUST_MASK) )
1971             *retflgs |= 16; /* modified up */
1972         else
1973             *retflgs |= 32; /* modified down */
1974     }
1975
1976     /* we preserve the disabled state here */
1977     if( (rec.r.dir.ownertrust & TRUST_FLAG_DISABLED) )
1978         rec.r.dir.ownertrust = new_trust | TRUST_FLAG_DISABLED;
1979     else
1980         rec.r.dir.ownertrust = new_trust & ~TRUST_FLAG_DISABLED;
1981     write_record( &rec );
1982 }
1983
1984 /****************
1985  * Update the ownertrust in the complete tree.
1986  */
1987 static void
1988 propagate_ownertrust( TN kr, ulong lid, unsigned trust )
1989 {
1990     TN ur;
1991
1992     for( ; kr; kr = kr->next ) {
1993         if( kr->lid == lid )
1994             kr->n.k.ownertrust = trust;
1995         for( ur=kr->list; ur; ur = ur->next )
1996             propagate_ownertrust( ur->list, lid, trust );
1997     }
1998 }
1999
2000 /****************
2001  * Calculate the validity of all keys in the tree and especially
2002  * the one of the top key.  If add_fnc is not NULL, it is used to
2003  * ask for missing ownertrust values (but only if this will help
2004  * us to increase the validity.
2005  * add_fnc is expected to take the LID of the key under question
2006  * and return a ownertrust value or an error:  positive values
2007  * are assumed to be the new ownertrust value; a 0 does mean no change,
2008  * a -1 is a request to cancel this validation procedure, a -2 requests
2009  * a listing of the sub-tree using the tty functions.
2010  *
2011  *
2012  * Returns: 0 = okay
2013  */
2014 static int
2015 propagate_validity( TN root, TN node, int (*add_fnc)(ulong), unsigned *retflgs )
2016 {
2017     TN kr, ur;
2018     int max_validity = 0;
2019
2020     assert( !node->is_uid );
2021     if( node->n.k.ownertrust == TRUST_ULTIMATE ) {
2022         /* this is one of our keys */
2023         assert( !node->list ); /* it should be a leaf */
2024         node->n.k.validity = TRUST_ULTIMATE;
2025         if( retflgs )
2026             *retflgs |= 1;  /* found a path to an ultimately trusted key */
2027         return 0;
2028     }
2029
2030     /* loop over all user ids */
2031     for( ur=node->list; ur && max_validity <= TRUST_FULLY; ur = ur->next ) {
2032         assert( ur->is_uid );
2033         /* loop over all signators */
2034         for(kr=ur->list; kr && max_validity <= TRUST_FULLY; kr = kr->next ) {
2035             if( propagate_validity( root, kr, add_fnc, retflgs ) )
2036                 return -1; /* quit */
2037             if( kr->n.k.validity == TRUST_ULTIMATE ) {
2038                 ur->n.u.fully_count = opt.completes_needed;
2039             }
2040             else if( kr->n.k.validity == TRUST_FULLY ) {
2041                 if( add_fnc && !kr->n.k.ownertrust ) {
2042                     int rc;
2043
2044                     if( retflgs )
2045                         *retflgs |= 2; /* found key with undefined ownertrust*/
2046                     do {
2047                         rc = add_fnc( kr->lid );
2048                         switch( rc ) {
2049                           case TRUST_NEVER:
2050                           case TRUST_MARGINAL:
2051                           case TRUST_FULLY:
2052                             propagate_ownertrust( root, kr->lid, rc );
2053                             upd_one_ownertrust( kr->lid, rc, retflgs );
2054                             if( retflgs )
2055                                 *retflgs |= 4; /* changed */
2056                             break;
2057                           case -1:
2058                             return -1; /* cancel */
2059                           case -2:
2060                             dump_tn_tree( NULL, 0, kr );
2061                             tty_printf("\n");
2062                             break;
2063                           default:
2064                             break;
2065                         }
2066                     } while( rc == -2 );
2067                 }
2068                 if( kr->n.k.ownertrust == TRUST_FULLY )
2069                     ur->n.u.fully_count++;
2070                 else if( kr->n.k.ownertrust == TRUST_MARGINAL )
2071                     ur->n.u.marginal_count++;
2072             }
2073
2074             if( ur->n.u.fully_count >= opt.completes_needed
2075                 || ur->n.u.marginal_count >= opt.marginals_needed )
2076                 ur->n.u.validity = TRUST_FULLY;
2077             else if( ur->n.u.fully_count || ur->n.u.marginal_count )
2078                 ur->n.u.validity = TRUST_MARGINAL;
2079
2080             if( ur->n.u.validity >= max_validity )
2081                 max_validity = ur->n.u.validity;
2082         }
2083     }
2084
2085     node->n.k.validity = max_validity;
2086     return 0;
2087 }
2088
2089
2090
2091 /****************
2092  * Given the directory record of a key, check whether we can
2093  * find a path to an ultimately trusted key.  We do this by
2094  * checking all key signatures up to a some depth.
2095  */
2096 static int
2097 verify_key( int max_depth, TRUSTREC *drec, const char *namehash,
2098                             int (*add_fnc)(ulong), unsigned *retflgs )
2099 {
2100     TN tree;
2101     int keytrust;
2102     int pv_result;
2103
2104     tree = build_cert_tree( drec->r.dir.lid, 0, opt.max_cert_depth, NULL );
2105     if( !tree )
2106         return TRUST_UNDEFINED;
2107     pv_result = propagate_validity( tree, tree, add_fnc, retflgs );
2108     if( namehash && tree->n.k.validity != TRUST_ULTIMATE ) {
2109         /* find the matching user id.
2110          * We don't do this here if the key is ultimately trusted; in
2111          * this case there will be no lids for the user IDs and frankly
2112          * it does not make sense to compare by the name if we do
2113          * have the secret key.
2114          * fixme: the way we handle this is too inefficient */
2115         TN ur;
2116         TRUSTREC rec;
2117
2118         keytrust = 0;
2119         for( ur=tree->list; ur; ur = ur->next ) {
2120             read_record( ur->lid, &rec, RECTYPE_UID );
2121             if( !memcmp( namehash, rec.r.uid.namehash, 20 ) ) {
2122                 keytrust = ur->n.u.validity;
2123                 break;
2124             }
2125         }
2126     }
2127     else
2128         keytrust = tree->n.k.validity;
2129
2130     /* update the cached validity values */
2131     if( !pv_result
2132         && keytrust >= TRUST_UNDEFINED
2133         && tdbio_db_matches_options()
2134         && ( !drec->r.dir.valcheck || drec->r.dir.validity != keytrust ) ) {
2135         TN ur;
2136         TRUSTREC rec;
2137
2138         for( ur=tree->list; ur; ur = ur->next ) {
2139             read_record( ur->lid, &rec, RECTYPE_UID );
2140             if( rec.r.uid.validity != ur->n.u.validity ) {
2141                 rec.r.uid.validity = ur->n.u.validity;
2142                 write_record( &rec );
2143             }
2144         }
2145
2146         drec->r.dir.validity = tree->n.k.validity;
2147         drec->r.dir.valcheck = make_timestamp();
2148         write_record( drec );
2149         do_sync();
2150     }
2151
2152     release_tn_tree( tree );
2153     return keytrust;
2154 }
2155
2156
2157 /****************
2158  * we have the pubkey record and all needed informations are in the trustdb
2159  * but nothing more is known.
2160  */
2161 static int
2162 do_check( TRUSTREC *dr, unsigned *validity,
2163           const char *namehash, int (*add_fnc)(ulong), unsigned *retflgs )
2164 {
2165     if( !dr->r.dir.keylist ) {
2166         log_error(_("Ooops, no keys\n"));
2167         return GPGERR_TRUSTDB;
2168     }
2169     if( !dr->r.dir.uidlist ) {
2170         log_error(_("Ooops, no user IDs\n"));
2171         return GPGERR_TRUSTDB;
2172     }
2173
2174     if( retflgs )
2175         *retflgs &= ~(16|32);  /* reset the 2 special flags */
2176
2177     if( (dr->r.dir.ownertrust & TRUST_FLAG_DISABLED) )
2178         *validity = 0; /* no need to check further */
2179     else if( namehash ) {
2180         /* Fixme: use a cache */
2181         *validity = verify_key( opt.max_cert_depth, dr, namehash,
2182                                                         add_fnc, retflgs );
2183     }
2184     else if( !add_fnc
2185         && tdbio_db_matches_options()
2186             /* FIXME, TODO: This comparision is WRONG ! */
2187         && dr->r.dir.valcheck
2188             > tdbio_read_modify_stamp( (dr->r.dir.validity < TRUST_FULLY) )
2189         && dr->r.dir.validity )
2190         *validity = dr->r.dir.validity;
2191     else
2192         *validity = verify_key( opt.max_cert_depth, dr, NULL,
2193                                                         add_fnc, retflgs );
2194
2195     if( !(*validity & TRUST_MASK) )
2196         *validity = TRUST_UNDEFINED;
2197
2198     if( (dr->r.dir.ownertrust & TRUST_FLAG_DISABLED) )
2199         *validity |= TRUST_FLAG_DISABLED;
2200
2201     if( dr->r.dir.dirflags & DIRF_REVOKED )
2202         *validity |= TRUST_FLAG_REVOKED;
2203
2204     /* If we have changed some ownertrusts, set the trustdb timestamps
2205      * and do a sync */
2206     if( retflgs && (*retflgs & (16|32)) ) {
2207         tdbio_write_modify_stamp( (*retflgs & 16), (*retflgs & 32) );
2208         do_sync();
2209     }
2210
2211
2212     return 0;
2213 }
2214
2215
2216 \f
2217 /***********************************************
2218  *********  Change trustdb values **************
2219  ***********************************************/
2220
2221 int
2222 update_ownertrust( ulong lid, unsigned new_trust )
2223 {
2224     TRUSTREC rec;
2225
2226     init_trustdb();
2227     read_record( lid, &rec, RECTYPE_DIR );
2228     if( DBG_TRUST )
2229         log_debug("update_ownertrust of %lu from %u to %u\n",
2230                            lid, (unsigned)rec.r.dir.ownertrust, new_trust );
2231     rec.r.dir.ownertrust = new_trust;
2232     write_record( &rec );
2233     do_sync();
2234     return 0;
2235 }
2236
2237
2238 int
2239 clear_trust_checked_flag( PKT_public_key *pk )
2240 {
2241     TRUSTREC rec;
2242     int rc;
2243
2244     if( opt.dry_run )
2245         return 0;
2246
2247     init_trustdb();
2248     rc = get_dir_record( pk, &rec );
2249     if( rc )
2250         return rc;
2251
2252     /* check whether they are already reset */
2253     if( !(rec.r.dir.dirflags & DIRF_CHECKED) && !rec.r.dir.valcheck )
2254         return 0;
2255
2256     /* reset the flag */
2257     rec.r.dir.dirflags &= ~DIRF_CHECKED;
2258     rec.r.dir.valcheck = 0;
2259     write_record( &rec );
2260     do_sync();
2261     return 0;
2262 }
2263
2264
2265
2266
2267 \f
2268 /***********************************************
2269  *********  Query trustdb values  **************
2270  ***********************************************/
2271
2272
2273 /****************
2274  * This function simply looks for the key in the trustdb
2275  * and makes sure that pk->local_id is set to the correct value.
2276  * Return: 0 = found
2277  *         -1 = not found
2278  *        other = error
2279  */
2280 int
2281 query_trust_record( PKT_public_key *pk )
2282 {
2283     TRUSTREC rec;
2284     init_trustdb();
2285     return get_dir_record( pk, &rec );
2286 }
2287
2288
2289 /****************
2290  * Get the trustlevel for this PK.
2291  * Note: This does not ask any questions
2292  * Returns: 0 okay of an errorcode
2293  *
2294  * It operates this way:
2295  *  locate the pk in the trustdb
2296  *      found:
2297  *          Do we have a valid cache record for it?
2298  *              yes: return trustlevel from cache
2299  *              no:  make a cache record and all the other stuff
2300  *      not found:
2301  *          try to insert the pubkey into the trustdb and check again
2302  *
2303  * Problems: How do we get the complete keyblock to check that the
2304  *           cache record is actually valid?  Think we need a clever
2305  *           cache in getkey.c  to keep track of this stuff. Maybe it
2306  *           is not necessary to check this if we use a local pubring. Hmmmm.
2307  */
2308 int
2309 check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
2310              const byte *namehash, int (*add_fnc)(ulong), unsigned *retflgs )
2311 {
2312     TRUSTREC rec;
2313     unsigned trustlevel = TRUST_UNKNOWN;
2314     int rc=0;
2315     u32 cur_time;
2316     u32 keyid[2];
2317
2318
2319     init_trustdb();
2320     keyid_from_pk( pk, keyid );
2321
2322     /* get the pubkey record */
2323     if( pk->local_id ) {
2324         read_record( pk->local_id, &rec, RECTYPE_DIR );
2325     }
2326     else { /* no local_id: scan the trustdb */
2327         if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) {
2328             log_error(_("check_trust: search dir record failed: %s\n"),
2329                                                             gpg_errstr(rc));
2330             return rc;
2331         }
2332         else if( rc == -1 && opt.dry_run )
2333             return GPGERR_GENERAL;
2334         else if( rc == -1 ) { /* not found - insert */
2335             rc = insert_trust_record_by_pk( pk );
2336             if( rc ) {
2337                 log_error(_("key %08lX: insert trust record failed: %s\n"),
2338                                           (ulong)keyid[1], gpg_errstr(rc));
2339                 goto leave;
2340             }
2341             log_info(_("key %08lX.%lu: inserted into trustdb\n"),
2342                                           (ulong)keyid[1], pk->local_id );
2343             /* and re-read the dir record */
2344             read_record( pk->local_id, &rec, RECTYPE_DIR );
2345         }
2346     }
2347     cur_time = make_timestamp();
2348     if( pk->timestamp > cur_time ) {
2349         log_info(_("key %08lX.%lu: created in future "
2350                    "(time warp or clock problem)\n"),
2351                                           (ulong)keyid[1], pk->local_id );
2352         if( !opt.ignore_time_conflict )
2353             return GPGERR_TIME_CONFLICT;
2354     }
2355
2356     if( !(rec.r.dir.dirflags & DIRF_CHECKED) )
2357         check_trust_record( &rec, 0 );
2358     else if( rec.r.dir.checkat && rec.r.dir.checkat <= cur_time )
2359         check_trust_record( &rec, 0 );
2360     else if( (rec.r.dir.dirflags & DIRF_NEWKEYS) )
2361         check_trust_record( &rec, 1 );
2362
2363     if( pk->expiredate && pk->expiredate <= cur_time ) {
2364         log_info(_("key %08lX.%lu: expired at %s\n"),
2365                         (ulong)keyid[1], pk->local_id,
2366                              asctimestamp( pk->expiredate) );
2367         trustlevel = TRUST_EXPIRED;
2368     }
2369     else {
2370         rc = do_check( &rec, &trustlevel, namehash, add_fnc, retflgs );
2371         if( rc ) {
2372             log_error(_("key %08lX.%lu: trust check failed: %s\n"),
2373                             (ulong)keyid[1], pk->local_id, gpg_errstr(rc));
2374             return rc;
2375         }
2376     }
2377
2378     /* is a subkey has been requested, we have to check its keyflags */
2379     if( !rc ) {
2380         TRUSTREC krec;
2381         byte fpr[MAX_FINGERPRINT_LEN] = {0}; /* to avoid compiler warnings */
2382         size_t fprlen = 0;
2383         ulong recno;
2384         int kcount=0;
2385
2386         for( recno = rec.r.dir.keylist; recno; recno = krec.r.key.next ) {
2387             read_record( recno, &krec, RECTYPE_KEY );
2388             if( ++kcount == 1 )
2389                 continue; /* skip the primary key */
2390             if( kcount == 2 ) /* now we need the fingerprint */
2391                 fingerprint_from_pk( pk, fpr, &fprlen );
2392
2393             if( krec.r.key.fingerprint_len == fprlen
2394                 && !memcmp( krec.r.key.fingerprint, fpr, fprlen ) ) {
2395                 /* found the subkey */
2396                 if( (krec.r.key.keyflags & KEYF_REVOKED) )
2397                     trustlevel |= TRUST_FLAG_SUB_REVOKED;
2398                 /* should we check for keybinding here??? */
2399                 /* Hmmm: Maybe this whole checking stuff should not go
2400                  * into the trustdb, but be done direct from the keyblock.
2401                  * Chnage this all when we add an abstarction layer around
2402                  * the way certificates are handled by different standards */
2403                 break;
2404             }
2405         }
2406     }
2407
2408
2409   leave:
2410     if( DBG_TRUST )
2411         log_debug("check_trust() returns trustlevel %04x.\n", trustlevel);
2412     *r_trustlevel = trustlevel;
2413     return 0;
2414 }
2415
2416
2417 /****************
2418  * scan the whole trustdb and mark all signature records whose keys
2419  * are freshly imported.
2420  */
2421 static void
2422 mark_fresh_keys()
2423 {
2424     TRUSTREC dirrec, rec;
2425     ulong recnum, lid;
2426     int i;
2427
2428     memset( &dirrec, 0, sizeof dirrec );
2429
2430     for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
2431         if( rec.rectype != RECTYPE_SIG )
2432             continue;
2433         /* if we have already have the dir record, we can check it now */
2434         if( dirrec.recnum == rec.r.sig.lid
2435             && (dirrec.r.dir.dirflags & DIRF_NEWKEYS) )
2436             continue; /* flag is already set */
2437
2438         for(i=0; i < SIGS_PER_RECORD; i++ ) {
2439             if( !(lid=rec.r.sig.sig[i].lid) )
2440                 continue; /* skip deleted sigs */
2441             if( !(rec.r.sig.sig[i].flag & SIGF_CHECKED) )
2442                 continue; /* skip checked signatures */
2443             if( qry_lid_table_flag( fresh_imported_keys, lid, NULL ) )
2444                 continue; /* not in the list of new keys */
2445             read_record( rec.r.sig.lid, &dirrec, RECTYPE_DIR );
2446             if( !(dirrec.r.dir.dirflags & DIRF_NEWKEYS) ) {
2447                 dirrec.r.dir.dirflags |= DIRF_NEWKEYS;
2448                 write_record( &dirrec );
2449             }
2450             break;
2451         }
2452     }
2453
2454     do_sync();
2455
2456     clear_lid_table( fresh_imported_keys );
2457     fresh_imported_keys_count = 0;
2458 }
2459
2460
2461
2462 int
2463 query_trust_info( PKT_public_key *pk, const byte *namehash )
2464 {
2465     unsigned trustlevel;
2466     int c;
2467
2468     init_trustdb();
2469     if( check_trust( pk, &trustlevel, namehash, NULL, NULL ) )
2470         return '?';
2471     if( trustlevel & TRUST_FLAG_DISABLED )
2472         return 'd';
2473     if( trustlevel & TRUST_FLAG_REVOKED )
2474         return 'r';
2475     c = trust_letter( (trustlevel & TRUST_MASK) );
2476     if( !c )
2477         c = '?';
2478     return c;
2479 }
2480
2481
2482
2483 /****************
2484  * Return the assigned ownertrust value for the given LID
2485  */
2486 unsigned
2487 get_ownertrust( ulong lid )
2488 {
2489     TRUSTREC rec;
2490
2491     init_trustdb();
2492     read_record( lid, &rec, RECTYPE_DIR );
2493     return rec.r.dir.ownertrust;
2494 }
2495
2496 int
2497 get_ownertrust_info( ulong lid )
2498 {
2499     unsigned otrust;
2500     int c;
2501
2502     init_trustdb();
2503     otrust = get_ownertrust( lid );
2504     c = trust_letter( (otrust & TRUST_MASK) );
2505     if( !c )
2506         c = '?';
2507     return c;
2508 }
2509
2510
2511
2512 void
2513 list_trust_path( const char *username )
2514 {
2515     int rc;
2516     ulong lid;
2517     TRUSTREC rec;
2518     TN tree;
2519     PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
2520
2521     init_trustdb();
2522     if( (rc = get_pubkey_byname(NULL, pk, username, NULL )) )
2523         log_error(_("user '%s' not found: %s\n"), username, gpg_errstr(rc) );
2524     else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
2525         log_error(_("problem finding '%s' in trustdb: %s\n"),
2526                                             username, gpg_errstr(rc));
2527     else if( rc == -1 ) {
2528         log_info(_("user '%s' not in trustdb - inserting\n"), username);
2529         rc = insert_trust_record_by_pk( pk );
2530         if( rc )
2531             log_error(_("failed to put '%s' into trustdb: %s\n"),
2532                                                     username, gpg_errstr(rc));
2533         else {
2534             assert( pk->local_id );
2535         }
2536     }
2537     lid = pk->local_id;
2538
2539     tree = build_cert_tree( lid, 0, opt.max_cert_depth, NULL );
2540     if( tree )
2541         propagate_validity( tree, tree, NULL, NULL );
2542     if( opt.with_colons )
2543         dump_tn_tree_with_colons( 0, tree );
2544     else
2545         dump_tn_tree( stdout, 0, tree );
2546     /*printf("(alloced tns=%d  max=%d)\n", alloced_tns, max_alloced_tns );*/
2547     release_tn_tree( tree );
2548     /*printf("Ownertrust=%c Validity=%c\n", get_ownertrust_info( lid ),
2549                                           query_trust_info( pk, NULL ) ); */
2550
2551     free_public_key( pk );
2552
2553 }
2554
2555
2556
2557
2558 /****************
2559  * Enumerate all keys, which are needed to build all trust paths for
2560  * the given key.  This function does not return the key itself or
2561  * the ultimate key (the last point in cerificate chain).  Only
2562  * certificate chains which ends up at an ultimately trusted key
2563  * are listed.  If ownertrust or validity is not NULL, the corresponding
2564  * value for the returned LID is also returned in these variable(s).
2565  *
2566  *  1) create a void pointer and initialize it to NULL
2567  *  2) pass this void pointer by reference to this function.
2568  *     Set lid to the key you want to enumerate and pass it by reference.
2569  *  3) call this function as long as it does not return -1
2570  *     to indicate EOF. LID does contain the next key used to build the web
2571  *  4) Always call this function a last time with LID set to NULL,
2572  *     so that it can free its context.
2573  *
2574  * Returns: -1 on EOF or the level of the returned LID
2575  */
2576 int
2577 enum_cert_paths( void **context, ulong *lid,
2578                  unsigned *ownertrust, unsigned *validity )
2579 {
2580     return -1;
2581   #if 0
2582     struct enum_cert_paths_ctx *ctx;
2583     fixme: .....   tsl;
2584
2585     init_trustdb();
2586     if( !lid ) {  /* release the context */
2587         if( *context ) {
2588             FIXME: ........tsl2;
2589
2590             ctx = *context;
2591             for(tsl = ctx->tsl_head; tsl; tsl = tsl2 ) {
2592                 tsl2 = tsl->next;
2593                 gcry_free( tsl );
2594             }
2595             *context = NULL;
2596         }
2597         return -1;
2598     }
2599
2600     if( !*context ) {
2601         FIXME .... *tmppath;
2602         TRUSTREC rec;
2603
2604         if( !*lid )
2605             return -1;
2606
2607         ctx = gcry_xcalloc( 1, sizeof *ctx );
2608         *context = ctx;
2609         /* collect the paths */
2610       #if 0
2611         read_record( *lid, &rec, RECTYPE_DIR );
2612         tmppath = gcry_xcalloc( 1, (opt.max_cert_depth+1)* sizeof *tmppath );
2613         tsl = NULL;
2614         collect_paths( 0, opt.max_cert_depth, 1, &rec, tmppath, &tsl );
2615         gcry_free( tmppath );
2616         sort_tsl_list( &tsl );
2617       #endif
2618         /* setup the context */
2619         ctx->tsl_head = tsl;
2620         ctx->tsl = ctx->tsl_head;
2621         ctx->idx = 0;
2622     }
2623     else
2624         ctx = *context;
2625
2626     while( ctx->tsl && ctx->idx >= ctx->tsl->pathlen )  {
2627         ctx->tsl = ctx->tsl->next;
2628         ctx->idx = 0;
2629     }
2630     tsl = ctx->tsl;
2631     if( !tsl )
2632         return -1; /* eof */
2633
2634     if( ownertrust )
2635         *ownertrust = tsl->path[ctx->idx].otrust;
2636     if( validity )
2637         *validity = tsl->path[ctx->idx].trust;
2638     *lid = tsl->path[ctx->idx].lid;
2639     ctx->idx++;
2640     return ctx->idx-1;
2641   #endif
2642 }
2643
2644
2645 /****************
2646  * Print the current path
2647  */
2648 void
2649 enum_cert_paths_print( void **context, FILE *fp,
2650                                        int refresh, ulong selected_lid )
2651 {
2652     return;
2653   #if 0
2654     struct enum_cert_paths_ctx *ctx;
2655     FIXME......... tsl;
2656
2657     if( !*context )
2658         return;
2659     init_trustdb();
2660     ctx = *context;
2661     if( !ctx->tsl )
2662         return;
2663     tsl = ctx->tsl;
2664
2665     if( !fp )
2666         fp = stderr;
2667
2668     if( refresh ) { /* update the ownertrust and if possible the validity */
2669         int i;
2670         int match = tdbio_db_matches_options();
2671
2672         for( i = 0; i < tsl->pathlen; i++ )  {
2673             TRUSTREC rec;
2674
2675             read_record( tsl->path[i].lid, &rec, RECTYPE_DIR );
2676             tsl->path[i].otrust = rec.r.dir.ownertrust;
2677             /* update validity only if we have it in the cache
2678              * calculation is too time consuming */
2679             if( match && rec.r.dir.valcheck && rec.r.dir.validity ) {
2680                 tsl->path[i].trust = rec.r.dir.validity;
2681                 if( rec.r.dir.dirflags & DIRF_REVOKED )
2682                     tsl->path[i].trust = TRUST_FLAG_REVOKED;
2683             }
2684         }
2685     }
2686
2687     print_path( tsl->pathlen, tsl->path, fp, selected_lid );
2688   #endif
2689 }
2690
2691
2692 /*
2693  * Return an allocated buffer with the preference values for
2694  * the key with LID and the userid which is identified by the
2695  * HAMEHASH or the first one if namehash is NULL.  ret_n receives
2696  * the length of the allocated buffer.  Structure of the buffer is
2697  * a repeated sequences of 2 bytes; where the first byte describes the
2698  * type of the preference and the second one the value.  The constants
2699  * PREFTYPE_xxxx should be used to reference a type.
2700  */
2701 byte *
2702 get_pref_data( ulong lid, const byte *namehash, size_t *ret_n )
2703 {
2704     TRUSTREC rec;
2705     ulong recno;
2706
2707     init_trustdb();
2708     read_record( lid, &rec, RECTYPE_DIR );
2709     for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
2710         read_record( recno, &rec, RECTYPE_UID );
2711         if( rec.r.uid.prefrec
2712             && ( !namehash || !memcmp(namehash, rec.r.uid.namehash, 20) ))  {
2713             byte *buf;
2714             /* found the correct one or the first one */
2715             read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
2716             if( rec.r.pref.next )
2717                 log_info(_("WARNING: can't yet handle long pref records\n"));
2718             buf = gcry_xmalloc( ITEMS_PER_PREF_RECORD );
2719             memcpy( buf, rec.r.pref.data, ITEMS_PER_PREF_RECORD );
2720             *ret_n = ITEMS_PER_PREF_RECORD;
2721             return buf;
2722         }
2723     }
2724     return NULL;
2725 }
2726
2727
2728
2729 /****************
2730  * Check whether the algorithm is in one of the pref records
2731  */
2732 int
2733 is_algo_in_prefs( ulong lid, int preftype, int algo )
2734 {
2735     TRUSTREC rec;
2736     ulong recno;
2737     int i;
2738     byte *pref;
2739
2740     init_trustdb();
2741     read_record( lid, &rec, RECTYPE_DIR );
2742     for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
2743         read_record( recno, &rec, RECTYPE_UID );
2744         if( rec.r.uid.prefrec ) {
2745             read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
2746             if( rec.r.pref.next )
2747                 log_info(_("WARNING: can't yet handle long pref records\n"));
2748             pref = rec.r.pref.data;
2749             for(i=0; i+1 < ITEMS_PER_PREF_RECORD; i+=2 ) {
2750                 if( pref[i] == preftype && pref[i+1] == algo )
2751                     return 1;
2752             }
2753         }
2754     }
2755     return 0;
2756 }
2757