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