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