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