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