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