See ChangeLog: Mon Mar 8 20:47:17 CET 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
45 #if MAX_FINGERPRINT_LEN > 20
46   #error Must change structure of trustdb
47 #endif
48
49 struct keyid_list {
50     struct keyid_list *next;
51     u32 keyid[2];
52 };
53
54 struct local_id_item {
55     struct local_id_item *next;
56     ulong lid;
57     unsigned flag;
58 };
59
60 struct local_id_table {
61     struct local_id_table *next; /* only used to keep a list of unused tables */
62     struct local_id_item *items[16];
63 };
64
65
66 typedef struct local_id_table *LOCAL_ID_TABLE;
67
68
69 struct enum_cert_paths_ctx {
70    int init;
71    int idx;
72 };
73
74
75 struct recno_list_struct {
76     struct recno_list_struct *next;
77     ulong recno;
78     int type;
79 };
80 typedef struct recno_list_struct *RECNO_LIST;
81
82
83
84 typedef struct trust_node *TN;
85 struct trust_node {
86     TN    back;  /* parent */
87     TN    list;  /* list of other node (should all be of the same type)*/
88     TN    next;  /* used to build the list */
89     int   is_uid; /* set if this is an uid node */
90     ulong lid;   /* key or uid recordnumber */
91     union {
92         struct {
93             int ownertrust;
94             int validity;
95             /* helper */
96             int buckstop;
97         } k;
98         struct {
99             int marginal_count;
100             int fully_count;
101             int validity;
102         } u;
103     } n;
104 };
105
106
107 static TN used_tns;
108 static int alloced_tns;
109 static int max_alloced_tns;
110
111
112 static int walk_sigrecs( SIGREC_CONTEXT *c );
113
114 static LOCAL_ID_TABLE new_lid_table(void);
115 static void release_lid_table( LOCAL_ID_TABLE tbl );
116 static int ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag );
117 static int qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag );
118
119
120 static int propagate_validity( TN node );
121
122 static void print_user_id( const char *text, u32 *keyid );
123 static int list_sigs( ulong pubkey_id );
124 static int do_check( TRUSTREC *drec, unsigned *trustlevel, const char *nhash);
125 static int get_dir_record( PKT_public_key *pk, TRUSTREC *rec );
126
127 static void upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig );
128 static void upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
129                  TRUSTREC *drec, RECNO_LIST *recno_list, int recheck,
130                  TRUSTREC *urec, const byte *uidhash, int revoked );
131
132 static struct keyid_list *trusted_key_list;
133
134 /* a table used to keep track of ultimately trusted keys
135  * which are the ones from our secrings and the trusted keys */
136 static LOCAL_ID_TABLE ultikey_table;
137
138 /* list of unused lid items and tables */
139 static LOCAL_ID_TABLE unused_lid_tables;
140 static struct local_id_item *unused_lid_items;
141
142 static struct {
143     int init;
144     int level;
145     char *dbname;
146 } trustdb_args;
147 #define INIT_TRUSTDB() do { if( !trustdb_args.init ) \
148                                 do_init_trustdb();   \
149                           } while(0)
150 static void do_init_trustdb(void);
151
152 #define HEXTOBIN(a) ( (a) >= '0' && (a) <= '9' ? ((a)-'0') : \
153                       (a) >= 'A' && (a) <= 'F' ? ((a)-'A'+10) : ((a)-'a'+10))
154
155
156 \f
157 /**********************************************
158  ***********  record read write  **************
159  **********************************************/
160
161 static void
162 die_invalid_db(void)
163 {
164     log_error(_(
165         "The trustdb is corrupted; please run \"gpgm --fix-trustdb\".\n") );
166     g10_exit(2);
167 }
168
169 /****************
170  * Read a record but die if it does not exist
171  */
172 static void
173 read_record( ulong recno, TRUSTREC *rec, int rectype )
174 {
175     int rc = tdbio_read_record( recno, rec, rectype );
176     if( !rc )
177         return;
178     log_error(_("trust record %lu, req type %d: read failed: %s\n"),
179                                     recno, rectype,  g10_errstr(rc) );
180     die_invalid_db();
181 }
182
183
184 /****************
185  * Wirte a record but die on error
186  */
187 static void
188 write_record( TRUSTREC *rec )
189 {
190     int rc = tdbio_write_record( rec );
191     if( !rc )
192         return;
193     log_error(_("trust record %lu, type %d: write failed: %s\n"),
194                             rec->recnum, rec->rectype, g10_errstr(rc) );
195     die_invalid_db();
196 }
197
198 /****************
199  * Delete a record but die on error
200  */
201 static void
202 delete_record( ulong recno )
203 {
204     int rc = tdbio_delete_record( recno );
205     if( !rc )
206         return;
207     log_error(_("trust record %lu: delete failed: %s\n"),
208                                               recno, g10_errstr(rc) );
209     die_invalid_db();
210 }
211
212 /****************
213  * sync the db
214  */
215 static void
216 do_sync(void)
217 {
218     int rc = tdbio_sync();
219     if( !rc )
220         return;
221     log_error(_("trustdb: sync failed: %s\n"), g10_errstr(rc) );
222     g10_exit(2);
223 }
224
225
226 \f
227 /**********************************************
228  ************* list helpers *******************
229  **********************************************/
230
231 /****************
232  * Insert a new item into a recno list
233  */
234 static void
235 ins_recno_list( RECNO_LIST *head, ulong recno, int type )
236 {
237     RECNO_LIST item = m_alloc( sizeof *item );
238
239     item->recno = recno;
240     item->type = type;
241     item->next = *head;
242     *head = item;
243 }
244
245 static RECNO_LIST
246 qry_recno_list( RECNO_LIST list, ulong recno, int type  )
247 {
248     for( ; list; list = list->next ) {
249         if( list->recno == recno && (!type || list->type == type) )
250             return list;
251     }
252     return NULL;
253 }
254
255
256 static void
257 rel_recno_list( RECNO_LIST *head )
258 {
259     RECNO_LIST r, r2;
260
261     for(r = *head; r; r = r2 ) {
262         r2 = r->next;
263         m_free(r);
264     }
265     *head = NULL;
266 }
267
268 static LOCAL_ID_TABLE
269 new_lid_table(void)
270 {
271     LOCAL_ID_TABLE a;
272
273     a = unused_lid_tables;
274     if( a ) {
275         unused_lid_tables = a->next;
276         memset( a, 0, sizeof *a );
277     }
278     else
279         a = m_alloc_clear( sizeof *a );
280     return a;
281 }
282
283 static void
284 release_lid_table( LOCAL_ID_TABLE tbl )
285 {
286     struct local_id_item *a, *a2;
287     int i;
288
289     for(i=0; i < 16; i++ ) {
290         for(a=tbl->items[i]; a; a = a2 ) {
291             a2 = a->next;
292             a->next = unused_lid_items;
293             unused_lid_items = a;
294         }
295     }
296     tbl->next = unused_lid_tables;
297     unused_lid_tables = tbl;
298 }
299
300 /****************
301  * Add a new item to the table or return 1 if we already have this item
302  */
303 static int
304 ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag )
305 {
306     struct local_id_item *a;
307
308     for( a = tbl->items[lid & 0x0f]; a; a = a->next )
309         if( a->lid == lid )
310             return 1;
311     a = unused_lid_items;
312     if( a )
313         unused_lid_items = a->next;
314     else
315         a = m_alloc( sizeof *a );
316     a->lid = lid;
317     a->flag = flag;
318     a->next = tbl->items[lid & 0x0f];
319     tbl->items[lid & 0x0f] = a;
320     return 0;
321 }
322
323 static int
324 qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag )
325 {
326     struct local_id_item *a;
327
328     for( a = tbl->items[lid & 0x0f]; a; a = a->next )
329         if( a->lid == lid ) {
330             if( flag )
331                 *flag = a->flag;
332             return 0;
333         }
334     return -1;
335 }
336
337
338
339 /****************
340  * Return the keyid from the primary key identified by LID.
341  */
342 int
343 keyid_from_lid( ulong lid, u32 *keyid )
344 {
345     TRUSTREC rec;
346     int rc;
347
348     INIT_TRUSTDB();
349     rc = tdbio_read_record( lid, &rec, 0 );
350     if( rc ) {
351         log_error(_("error reading dir record for LID %lu: %s\n"),
352                                                     lid, g10_errstr(rc));
353         return G10ERR_TRUSTDB;
354     }
355     if( rec.rectype == RECTYPE_SDIR )
356         return 0;
357     if( rec.rectype != RECTYPE_DIR ) {
358         log_error(_("lid %lu: expected dir record, got type %d\n"),
359                                                     lid, rec.rectype );
360         return G10ERR_TRUSTDB;
361     }
362     if( !rec.r.dir.keylist ) {
363         log_error(_("no primary key for LID %lu\n"), lid );
364         return G10ERR_TRUSTDB;
365     }
366     rc = tdbio_read_record( rec.r.dir.keylist, &rec, RECTYPE_KEY );
367     if( rc ) {
368         log_error(_("error reading primary key for LID %lu: %s\n"),
369                                                     lid, g10_errstr(rc));
370         return G10ERR_TRUSTDB;
371     }
372     keyid_from_fingerprint( rec.r.key.fingerprint, rec.r.key.fingerprint_len,
373                             keyid );
374
375     return 0;
376 }
377
378
379 ulong
380 lid_from_keyblock( KBNODE keyblock )
381 {
382     KBNODE node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
383     PKT_public_key *pk;
384     if( !node )
385         BUG();
386     pk = node->pkt->pkt.public_key;
387     if( !pk->local_id ) {
388         TRUSTREC rec;
389         INIT_TRUSTDB();
390
391         get_dir_record( pk, &rec );
392     }
393     return pk->local_id;
394 }
395
396
397 \f
398 /****************
399  * Walk through the signatures of a public key.
400  * The caller must provide a context structure, with all fields set
401  * to zero, but the local_id field set to the requested key;
402  * This function does not change this field.  On return the context
403  * is filled with the local-id of the signature and the signature flag.
404  * No fields should be changed (clearing all fields and setting
405  * pubkeyid is okay to continue with an other pubkey)
406  * Returns: 0 - okay, -1 for eof (no more sigs) or any other errorcode
407  */
408 static int
409 walk_sigrecs( SIGREC_CONTEXT *c )
410 {
411     TRUSTREC *r;
412     ulong rnum;
413
414     if( c->ctl.eof )
415         return -1;
416     r = &c->ctl.rec;
417     if( !c->ctl.init_done ) {
418         c->ctl.init_done = 1;
419         read_record( c->lid, r, 0 );
420         if( r->rectype != RECTYPE_DIR ) {
421             c->ctl.eof = 1;
422             return -1;  /* return eof */
423         }
424         c->ctl.nextuid = r->r.dir.uidlist;
425         /* force a read */
426         c->ctl.index = SIGS_PER_RECORD;
427         r->r.sig.next = 0;
428     }
429
430     /* need a loop to skip over deleted sigs */
431     do {
432         if( c->ctl.index >= SIGS_PER_RECORD ) { /* read the record */
433             rnum = r->r.sig.next;
434             if( !rnum && c->ctl.nextuid ) { /* read next uid record */
435                 read_record( c->ctl.nextuid, r, RECTYPE_UID );
436                 c->ctl.nextuid = r->r.uid.next;
437                 rnum = r->r.uid.siglist;
438             }
439             if( !rnum ) {
440                 c->ctl.eof = 1;
441                 return -1;  /* return eof */
442             }
443             read_record( rnum, r, RECTYPE_SIG );
444             if( r->r.sig.lid != c->lid ) {
445                 log_error(_("chained sigrec %lu has a wrong owner\n"), rnum );
446                 c->ctl.eof = 1;
447                 die_invalid_db();
448             }
449             c->ctl.index = 0;
450         }
451     } while( !r->r.sig.sig[c->ctl.index++].lid );
452
453     c->sig_lid = r->r.sig.sig[c->ctl.index-1].lid;
454     c->sig_flag = r->r.sig.sig[c->ctl.index-1].flag;
455     return 0;
456 }
457
458
459
460 \f
461 /***********************************************
462  *************  Trust  stuff  ******************
463  ***********************************************/
464
465 int
466 trust_letter( unsigned value )
467 {
468     switch( value ) {
469       case TRUST_UNKNOWN:   return '-';
470       case TRUST_EXPIRED:   return 'e';
471       case TRUST_UNDEFINED: return 'q';
472       case TRUST_NEVER:     return 'n';
473       case TRUST_MARGINAL:  return 'm';
474       case TRUST_FULLY:     return 'f';
475       case TRUST_ULTIMATE:  return 'u';
476       default:              return  0 ;
477     }
478 }
479
480
481 void
482 register_trusted_key( const char *string )
483 {
484     u32 keyid[2];
485     struct keyid_list *r;
486
487     if( classify_user_id( string, keyid, NULL, NULL, NULL ) != 11 ) {
488         log_error(_("'%s' is not a valid long keyID\n"), string );
489         return;
490     }
491
492     for( r = trusted_key_list; r; r = r->next )
493         if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] )
494             return;
495     r = m_alloc( sizeof *r );
496     r->keyid[0] = keyid[0];
497     r->keyid[1] = keyid[1];
498     r->next = trusted_key_list;
499     trusted_key_list = r;
500 }
501
502 /****************
503  * Verify that all our public keys are in the trustdb.
504  */
505 static int
506 verify_own_keys(void)
507 {
508     int rc;
509     void *enum_context = NULL;
510     PKT_secret_key *sk = m_alloc_clear( sizeof *sk );
511     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
512     u32 keyid[2];
513     struct keyid_list *kl;
514
515     /* put the trusted keys into the trusted key table */
516     for( kl = trusted_key_list; kl; kl = kl->next ) {
517         keyid[0] = kl->keyid[0];
518         keyid[1] = kl->keyid[1];
519         /* get the public key */
520         memset( pk, 0, sizeof *pk );
521         rc = get_pubkey( pk, keyid );
522         if( rc ) {
523             log_info(_("key %08lX: no public key for trusted key - skipped\n"),
524                                                             (ulong)keyid[1] );
525         }
526         else {
527             /* make sure that the pubkey is in the trustdb */
528             rc = query_trust_record( pk );
529             if( rc == -1 ) { /* put it into the trustdb */
530                 rc = insert_trust_record( pk );
531                 if( rc ) {
532                     log_error(_("key %08lX: can't put it into the trustdb\n"),
533                                                         (ulong)keyid[1] );
534                 }
535             }
536             else if( rc ) {
537                 log_error(_("key %08lX: query record failed\n"),
538                                                         (ulong)keyid[1] );
539             }
540             else {
541                 if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
542                     log_error(_("key %08lX: already in trusted key table\n"),
543                                                           (ulong)keyid[1]);
544                 else if( opt.verbose > 1 )
545                     log_info(_("key %08lX: accepted as trusted key.\n"),
546                                                           (ulong)keyid[1]);
547             }
548         }
549         release_public_key_parts( pk );
550     }
551
552     while( !(rc=enum_secret_keys( &enum_context, sk, 0 ) ) ) {
553         int have_pk = 0;
554
555         keyid_from_sk( sk, keyid );
556
557         if( DBG_TRUST )
558             log_debug("key %08lX: checking secret key\n", (ulong)keyid[1] );
559
560         if( is_secret_key_protected( sk ) < 1 )
561             log_info(_("NOTE: secret key %08lX is NOT protected.\n"),
562                                                             (ulong)keyid[1] );
563
564         for( kl = trusted_key_list; kl; kl = kl->next ) {
565             if( kl->keyid[0] == keyid[0] && kl->keyid[1] == keyid[1] )
566                 goto skip; /* already in trusted key table */
567         }
568
569         /* see whether we can access the public key of this secret key */
570         memset( pk, 0, sizeof *pk );
571         rc = get_pubkey( pk, keyid );
572         if( rc ) {
573             log_info(_("key %08lX: secret key without public key - skipped\n"),
574                                                             (ulong)keyid[1] );
575             goto skip;
576         }
577         have_pk=1;
578
579         if( cmp_public_secret_key( pk, sk ) ) {
580             log_info(_("key %08lX: secret and public key don't match\n"),
581                                                             (ulong)keyid[1] );
582             goto skip;
583         }
584
585         /* make sure that the pubkey is in the trustdb */
586         rc = query_trust_record( pk );
587         if( rc == -1 ) { /* put it into the trustdb */
588             rc = insert_trust_record( pk );
589             if( rc ) {
590                 log_error(_("key %08lX: can't put it into the trustdb\n"),
591                                                             (ulong)keyid[1] );
592                 goto skip;
593             }
594         }
595         else if( rc ) {
596             log_error(_("key %08lX: query record failed\n"), (ulong)keyid[1] );
597             goto skip;
598
599         }
600
601         if( DBG_TRUST )
602             log_debug("key %08lX.%lu: stored into ultikey_table\n",
603                                     (ulong)keyid[1], pk->local_id );
604         if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
605             log_error(_("key %08lX: already in trusted key table\n"),
606                                                         (ulong)keyid[1]);
607         else if( opt.verbose > 1 )
608             log_info(_("key %08lX: accepted as trusted key.\n"),
609                                                         (ulong)keyid[1]);
610       skip:
611         release_secret_key_parts( sk );
612         if( have_pk )
613             release_public_key_parts( pk );
614     }
615     if( rc != -1 )
616         log_error(_("enumerate secret keys failed: %s\n"), g10_errstr(rc) );
617     else
618         rc = 0;
619
620     /* release the trusted keyid table */
621     {   struct keyid_list *kl2;
622         for( kl = trusted_key_list; kl; kl = kl2 ) {
623             kl2 = kl->next;
624             m_free( kl );
625         }
626         trusted_key_list = NULL;
627     }
628
629     enum_secret_keys( &enum_context, NULL, 0 ); /* free context */
630     free_secret_key( sk );
631     free_public_key( pk );
632     return rc;
633 }
634
635
636 static void
637 print_user_id( const char *text, u32 *keyid )
638 {
639     char *p;
640     size_t n;
641
642     p = get_user_id( keyid, &n );
643     if( *text ) {
644         fputs( text, stdout);
645         putchar(' ');
646     }
647     putchar('\"');
648     print_string( stdout, p, n, 0 );
649     putchar('\"');
650     putchar('\n');
651     m_free(p);
652 }
653
654
655 static int
656 print_sigflags( FILE *fp, unsigned flags )
657 {
658     if( flags & SIGF_CHECKED ) {
659         fprintf(fp,"%c%c%c",
660            (flags & SIGF_VALID)   ? 'V':'-',
661            (flags & SIGF_EXPIRED) ? 'E':'-',
662            (flags & SIGF_REVOKED) ? 'R':'-');
663     }
664     else if( flags & SIGF_NOPUBKEY)
665         fputs("?--", fp);
666     else
667         fputs("---", fp);
668     return 3;
669 }
670
671 /* (a non-recursive algorithm would be easier) */
672 static int
673 do_list_sigs( ulong root, ulong pk_lid, int depth,
674               LOCAL_ID_TABLE lids, unsigned *lineno )
675 {
676     SIGREC_CONTEXT sx;
677     int rc;
678     u32 keyid[2];
679
680     memset( &sx, 0, sizeof sx );
681     sx.lid = pk_lid;
682     for(;;) {
683         rc = walk_sigrecs( &sx ); /* should we replace it and use */
684         if( rc )
685             break;
686         rc = keyid_from_lid( sx.sig_lid, keyid );
687         if( rc ) {
688             printf("%6u: %*s????????.%lu:", *lineno, depth*4, "", sx.sig_lid );
689             print_sigflags( stdout, sx.sig_flag );
690             putchar('\n');
691             ++*lineno;
692         }
693         else {
694             printf("%6u: %*s%08lX.%lu:", *lineno, depth*4, "",
695                               (ulong)keyid[1], sx.sig_lid );
696             print_sigflags( stdout, sx.sig_flag );
697             putchar(' ');
698             /* check whether we already checked this pk_lid */
699             if( !qry_lid_table_flag( ultikey_table, sx.sig_lid, NULL ) ) {
700                 print_user_id("[ultimately trusted]", keyid);
701                 ++*lineno;
702             }
703             else if( sx.sig_lid == pk_lid ) {
704                 printf("[self-signature]\n");
705                 ++*lineno;
706             }
707             else if( sx.sig_lid == root ) {
708                 printf("[closed]\n");
709                 ++*lineno;
710             }
711             else if( ins_lid_table_item( lids, sx.sig_lid, *lineno ) ) {
712                 unsigned refline;
713                 qry_lid_table_flag( lids, sx.sig_lid, &refline );
714                 printf("[see line %u]\n", refline);
715                 ++*lineno;
716             }
717             else if( depth+1 >= MAX_LIST_SIGS_DEPTH  ) {
718                 print_user_id( "[too deeply nested]", keyid );
719                 ++*lineno;
720             }
721             else {
722                 print_user_id( "", keyid );
723                 ++*lineno;
724                 rc = do_list_sigs( root, sx.sig_lid, depth+1, lids, lineno );
725                 if( rc )
726                     break;
727             }
728         }
729     }
730     return rc==-1? 0 : rc;
731 }
732
733 /****************
734  * List all signatures of a public key
735  */
736 static int
737 list_sigs( ulong pubkey_id )
738 {
739     int rc;
740     u32 keyid[2];
741     LOCAL_ID_TABLE lids;
742     unsigned lineno = 1;
743
744     rc = keyid_from_lid( pubkey_id, keyid );
745     if( rc )
746         return rc;
747     printf("Signatures of %08lX.%lu ", (ulong)keyid[1], pubkey_id );
748     print_user_id("", keyid);
749     printf("----------------------\n");
750
751     lids = new_lid_table();
752     rc = do_list_sigs( pubkey_id, pubkey_id, 0, lids, &lineno );
753     putchar('\n');
754     release_lid_table(lids);
755     return rc;
756 }
757
758 /****************
759  * List all records of a public key
760  */
761 static int
762 list_records( ulong lid )
763 {
764     int rc;
765     TRUSTREC dr, ur, rec;
766     ulong recno;
767
768     rc = tdbio_read_record( lid, &dr, RECTYPE_DIR );
769     if( rc ) {
770         log_error(_("lid %lu: read dir record failed: %s\n"),
771                                                 lid, g10_errstr(rc));
772         return rc;
773     }
774     tdbio_dump_record( &dr, stdout );
775
776     for( recno=dr.r.dir.keylist; recno; recno = rec.r.key.next ) {
777         rc = tdbio_read_record( recno, &rec, 0 );
778         if( rc ) {
779             log_error(_("lid %lu: read key record failed: %s\n"),
780                                                 lid, g10_errstr(rc));
781             return rc;
782         }
783         tdbio_dump_record( &rec, stdout );
784     }
785
786     for( recno=dr.r.dir.uidlist; recno; recno = ur.r.uid.next ) {
787         rc = tdbio_read_record( recno, &ur, RECTYPE_UID );
788         if( rc ) {
789             log_error(_("lid %lu: read uid record failed: %s\n"),
790                                                 lid, g10_errstr(rc));
791             return rc;
792         }
793         tdbio_dump_record( &ur, stdout );
794         /* preference records */
795         for(recno=ur.r.uid.prefrec; recno; recno = rec.r.pref.next ) {
796             rc = tdbio_read_record( recno, &rec, RECTYPE_PREF );
797             if( rc ) {
798                 log_error(_("lid %lu: read pref record failed: %s\n"),
799                                                     lid, g10_errstr(rc));
800                 return rc;
801             }
802             tdbio_dump_record( &rec, stdout );
803         }
804         /* sig records */
805         for(recno=ur.r.uid.siglist; recno; recno = rec.r.sig.next ) {
806             rc = tdbio_read_record( recno, &rec, RECTYPE_SIG );
807             if( rc ) {
808                 log_error(_("lid %lu: read sig record failed: %s\n"),
809                                                     lid, g10_errstr(rc));
810                 return rc;
811             }
812             tdbio_dump_record( &rec, stdout );
813         }
814     }
815
816     /* add cache record dump here */
817
818
819
820     return rc;
821 }
822
823
824
825 static TN
826 new_tn(void)
827 {
828     TN t;
829
830     if( used_tns ) {
831         t = used_tns;
832         used_tns = t->next;
833         memset( t, 0, sizeof *t );
834     }
835     else
836         t = m_alloc_clear( sizeof *t );
837     if( ++alloced_tns > max_alloced_tns )
838         max_alloced_tns = alloced_tns;
839     return t;
840 }
841
842
843 static void
844 release_tn( TN t )
845 {
846     if( t ) {
847         t->next = used_tns;
848         used_tns = t;
849         alloced_tns--;
850     }
851 }
852
853
854 static void
855 release_tn_tree( TN kr )
856 {
857     TN  kr2;
858
859     for( ; kr; kr = kr2 ) {
860         release_tn_tree( kr->list );
861         kr2 = kr->next;
862         release_tn( kr );
863     }
864 }
865
866
867 /****************
868  * Find all certification paths of a given LID.
869  * Limit the search to MAX_DEPTH.  stack is a helper variable which
870  * should have been allocated with size max_depth, stack[0] should
871  * be setup to the key we are investigating, so the minimal depth
872  * we should ever see in this function is 1.
873  * Returns: a new tree
874  * certchain_set must be a valid set or point to NULL; this function
875  * may modifiy it.
876  */
877 static TN
878 build_cert_tree( ulong lid, int depth, int max_depth, TN helproot )
879 {
880     TRUSTREC dirrec;
881     TRUSTREC uidrec;
882     ulong uidrno;
883     TN keynode;
884
885     if( depth >= max_depth )
886         return NULL;
887
888     keynode = new_tn();
889     if( !helproot )
890         helproot = keynode;
891     keynode->lid = lid;
892     if( !qry_lid_table_flag( ultikey_table, lid, NULL ) ) {
893         /* this is an ultimately trusted key;
894          * which means that we have found the end of the chain:
895          * We do this here prior to reading the dir record
896          * because we don't really need the info from that record */
897         keynode->n.k.ownertrust = TRUST_ULTIMATE;
898         keynode->n.k.buckstop   = 1;
899         return keynode;
900     }
901     read_record( lid, &dirrec, 0 );
902     if( dirrec.rectype != RECTYPE_DIR ) {
903         if( dirrec.rectype != RECTYPE_SDIR )
904             log_debug("lid %lu, has rectype %d"
905                       " - skipped\n", lid, dirrec.rectype );
906         m_free(keynode);
907         return NULL;
908     }
909     keynode->n.k.ownertrust = dirrec.r.dir.ownertrust;
910
911     /* loop over all user ids */
912     for( uidrno = dirrec.r.dir.uidlist; uidrno; uidrno = uidrec.r.uid.next ) {
913         TRUSTREC sigrec;
914         ulong sigrno;
915         TN uidnode = NULL;
916
917         read_record( uidrno, &uidrec, RECTYPE_UID );
918
919         if( !(uidrec.r.uid.uidflags & UIDF_CHECKED) )
920             continue; /* user id has not been checked */
921         if( !(uidrec.r.uid.uidflags & UIDF_VALID) )
922             continue; /* user id is not valid */
923         if( (uidrec.r.uid.uidflags & UIDF_REVOKED) )
924             continue; /* user id has been revoked */
925
926         /* loop over all signature records */
927         for(sigrno=uidrec.r.uid.siglist; sigrno; sigrno = sigrec.r.sig.next ) {
928             int i;
929             TN tn;
930
931             read_record( sigrno, &sigrec, RECTYPE_SIG );
932
933             for(i=0; i < SIGS_PER_RECORD; i++ ) {
934                 if( !sigrec.r.sig.sig[i].lid )
935                     continue; /* skip deleted sigs */
936                 if( !(sigrec.r.sig.sig[i].flag & SIGF_CHECKED) )
937                     continue; /* skip unchecked signatures */
938                 if( !(sigrec.r.sig.sig[i].flag & SIGF_VALID) )
939                     continue; /* skip invalid signatures */
940                 if( (sigrec.r.sig.sig[i].flag & SIGF_EXPIRED) )
941                     continue; /* skip expired signatures */
942                 if( (sigrec.r.sig.sig[i].flag & SIGF_REVOKED) )
943                     continue; /* skip revoked signatures */
944                 /* check for cycles */
945                 for( tn=keynode; tn && tn->lid != sigrec.r.sig.sig[i].lid;
946                                                           tn = tn->back )
947                     ;
948                 if( tn )
949                     continue; /* cycle found */
950
951                 tn = build_cert_tree( sigrec.r.sig.sig[i].lid,
952                                       depth+1, max_depth, helproot );
953                 if( !tn )
954                     continue; /* cert chain too deep or error */
955
956                 if( !uidnode ) {
957                     uidnode = new_tn();
958                     uidnode->back = keynode;
959                     uidnode->lid = uidrno;
960                     uidnode->is_uid = 1;
961                     uidnode->next = keynode->list;
962                     keynode->list = uidnode;
963                 }
964
965                 tn->back = uidnode;
966                 tn->next = uidnode->list;
967                 uidnode->list = tn;
968               #if 0 /* optimazation - fixme: reenable this later */
969                 if( tn->n.k.buckstop ) {
970                     /* ultimately trusted key found:
971                      * no need to check more signatures of this uid */
972                     sigrec.r.sig.next = 0;
973                     break;
974                 }
975               #endif
976             }
977         } /* end loop over sig recs */
978     } /* end loop over user ids */
979
980     if( !keynode->list ) {
981         release_tn_tree( keynode );
982         keynode = NULL;
983     }
984
985     return keynode;
986 }
987
988
989
990
991 /****************
992  * Given the directory record of a key, check whether we can
993  * find a path to an ultimately trusted key.  We do this by
994  * checking all key signatures up to a some depth.
995  */
996 static int
997 verify_key( int max_depth, TRUSTREC *drec, const char *namehash )
998 {
999     TN tree;
1000     int trust;
1001
1002     tree = build_cert_tree( drec->r.dir.lid, 0, opt.max_cert_depth, NULL );
1003     if( !tree )
1004         return TRUST_UNDEFINED;
1005     trust = propagate_validity( tree );
1006     if( namehash ) {
1007         /* find the matching user id.
1008          * FIXME: the way we handle this is too inefficient */
1009         TN ur;
1010         TRUSTREC rec;
1011
1012         trust = 0;
1013         for( ur=tree->list; ur; ur = ur->next ) {
1014             read_record( ur->lid, &rec, RECTYPE_UID );
1015             if( !memcmp( namehash, rec.r.uid.namehash, 20 ) ) {
1016                 trust = ur->n.u.validity;
1017                 break;
1018             }
1019         }
1020     }
1021
1022     release_tn_tree( tree );
1023     return trust;
1024 }
1025
1026
1027
1028
1029 /****************
1030  * we have the pubkey record and all needed informations are in the trustdb
1031  * but nothing more is known.
1032  */
1033 static int
1034 do_check( TRUSTREC *dr, unsigned *validity, const char *namehash )
1035 {
1036     if( !dr->r.dir.keylist ) {
1037         log_error(_("Ooops, no keys\n"));
1038         return G10ERR_TRUSTDB;
1039     }
1040     if( !dr->r.dir.uidlist ) {
1041         log_error(_("Ooops, no user ids\n"));
1042         return G10ERR_TRUSTDB;
1043     }
1044
1045     if( namehash ) {
1046         /* Fixme: use the cache */
1047         *validity = verify_key( opt.max_cert_depth, dr, namehash );
1048     }
1049     else if( tdbio_db_matches_options()
1050         && (dr->r.dir.dirflags & DIRF_VALVALID)
1051         && dr->r.dir.validity )
1052         *validity = dr->r.dir.validity;
1053     else {
1054         *validity = verify_key( opt.max_cert_depth, dr, NULL );
1055         if( (*validity & TRUST_MASK) >= TRUST_UNDEFINED
1056             && tdbio_db_matches_options() ) {
1057             /* update the cached validity value */
1058             /* FIXME: Move this to another place so that we can
1059              * update the validity of the uids too */
1060             dr->r.dir.validity = (*validity & TRUST_MASK);
1061             dr->r.dir.dirflags |= DIRF_VALVALID;
1062             write_record( dr );
1063         }
1064     }
1065
1066     if( dr->r.dir.dirflags & DIRF_REVOKED )
1067         *validity |= TRUST_FLAG_REVOKED;
1068
1069     return 0;
1070 }
1071
1072 \f
1073 /****************
1074  * Perform some checks over the trustdb
1075  *  level 0: only open the db
1076  *        1: used for initial program startup
1077  */
1078 int
1079 init_trustdb( int level, const char *dbname )
1080 {
1081     /* just store the args */
1082     if( trustdb_args.init )
1083         return 0;
1084     trustdb_args.level = level;
1085     trustdb_args.dbname = dbname? m_strdup(dbname): NULL;
1086     return 0;
1087 }
1088
1089 static void
1090 do_init_trustdb()
1091 {
1092     int rc=0;
1093     int level = trustdb_args.level;
1094     const char* dbname = trustdb_args.dbname;
1095
1096     trustdb_args.init = 1;
1097
1098     if( !ultikey_table )
1099         ultikey_table = new_lid_table();
1100
1101     if( !level || level==1 ) {
1102         rc = tdbio_set_dbname( dbname, !!level );
1103         if( !rc ) {
1104             if( !level )
1105                 return;
1106
1107             /* verify that our own keys are in the trustDB
1108              * or move them to the trustdb. */
1109             rc = verify_own_keys();
1110
1111             /* should we check whether there is no other ultimately trusted
1112              * key in the database? */
1113         }
1114     }
1115     else
1116         BUG();
1117     if( rc )
1118         log_fatal("can't init trustdb: %s\n", g10_errstr(rc) );
1119 }
1120
1121
1122 void
1123 list_trustdb( const char *username )
1124 {
1125     TRUSTREC rec;
1126
1127     INIT_TRUSTDB();
1128
1129     if( username && *username == '#' ) {
1130         int rc;
1131         ulong lid = atoi(username+1);
1132
1133         if( (rc = list_records( lid)) )
1134             log_error(_("user '%s' read problem: %s\n"),
1135                                             username, g10_errstr(rc));
1136         else if( (rc = list_sigs( lid )) )
1137             log_error(_("user '%s' list problem: %s\n"),
1138                                             username, g10_errstr(rc));
1139     }
1140     else if( username ) {
1141         PKT_public_key *pk = m_alloc_clear( sizeof *pk );
1142         int rc;
1143
1144         if( (rc = get_pubkey_byname( NULL, pk, username, NULL )) )
1145             log_error(_("user '%s' not found: %s\n"), username, g10_errstr(rc) );
1146         else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
1147             log_error(_("problem finding '%s' in trustdb: %s\n"),
1148                                                 username, g10_errstr(rc));
1149         else if( rc == -1 )
1150             log_error(_("user '%s' not in trustdb\n"), username);
1151         else if( (rc = list_records( pk->local_id)) )
1152             log_error(_("user '%s' read problem: %s\n"),
1153                                                 username, g10_errstr(rc));
1154         else if( (rc = list_sigs( pk->local_id )) )
1155             log_error(_("user '%s' list problem: %s\n"),
1156                                                 username, g10_errstr(rc));
1157         free_public_key( pk );
1158     }
1159     else {
1160         ulong recnum;
1161         int i;
1162
1163         printf("TrustDB: %s\n", tdbio_get_dbname() );
1164         for(i=9+strlen(tdbio_get_dbname()); i > 0; i-- )
1165             putchar('-');
1166         putchar('\n');
1167         for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ )
1168             tdbio_dump_record( &rec, stdout );
1169     }
1170 }
1171
1172 /****************
1173  * Print a list of all defined owner trust value.
1174  */
1175 void
1176 export_ownertrust()
1177 {
1178     TRUSTREC rec;
1179     TRUSTREC rec2;
1180     ulong recnum;
1181     int i;
1182     byte *p;
1183     int rc;
1184
1185     INIT_TRUSTDB();
1186     printf(_("# List of assigned trustvalues, created %s\n"
1187              "# (Use \"gpgm --import-ownertrust\" to restore them)\n"),
1188            asctimestamp( make_timestamp() ) );
1189     for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
1190         if( rec.rectype == RECTYPE_DIR ) {
1191             if( !rec.r.dir.keylist ) {
1192                 log_error(_("directory record w/o primary key\n"));
1193                 continue;
1194             }
1195             if( !rec.r.dir.ownertrust )
1196                 continue;
1197             rc = tdbio_read_record( rec.r.dir.keylist, &rec2, RECTYPE_KEY);
1198             if( rc ) {
1199                 log_error(_("error reading key record: %s\n"), g10_errstr(rc));
1200                 continue;
1201             }
1202             p = rec2.r.key.fingerprint;
1203             for(i=0; i < rec2.r.key.fingerprint_len; i++, p++ )
1204                 printf("%02X", *p );
1205             printf(":%u:\n", (unsigned)rec.r.dir.ownertrust );
1206         }
1207     }
1208 }
1209
1210
1211 void
1212 import_ownertrust( const char *fname )
1213 {
1214     FILE *fp;
1215     int is_stdin=0;
1216     char line[256];
1217     char *p;
1218     size_t n, fprlen;
1219     unsigned otrust;
1220
1221     INIT_TRUSTDB();
1222     if( !fname || (*fname == '-' && !fname[1]) ) {
1223         fp = stdin;
1224         fname = "[stdin]";
1225         is_stdin = 1;
1226     }
1227     else if( !(fp = fopen( fname, "r" )) ) {
1228         log_error_f(fname, _("can't open file: %s\n"), strerror(errno) );
1229         return;
1230     }
1231
1232     while( fgets( line, DIM(line)-1, fp ) ) {
1233         TRUSTREC rec;
1234         int rc;
1235
1236         if( !*line || *line == '#' )
1237             continue;
1238         n = strlen(line);
1239         if( line[n-1] != '\n' ) {
1240             log_error_f(fname, _("line too long\n") );
1241             /* ... or last line does not have a LF */
1242             break; /* can't continue */
1243         }
1244         for(p = line; *p && *p != ':' ; p++ )
1245             if( !isxdigit(*p) )
1246                 break;
1247         if( *p != ':' ) {
1248             log_error_f(fname, _("error: missing colon\n") );
1249             continue;
1250         }
1251         fprlen = p - line;
1252         if( fprlen != 32 && fprlen != 40 ) {
1253             log_error_f(fname, _("error: invalid fingerprint\n") );
1254             continue;
1255         }
1256         if( sscanf(p, ":%u:", &otrust ) != 1 ) {
1257             log_error_f(fname, _("error: no ownertrust value\n") );
1258             continue;
1259         }
1260         if( !otrust )
1261             continue; /* no otrust defined - no need to update or insert */
1262         /* convert the ascii fingerprint to binary */
1263         for(p=line, fprlen=0; *p != ':'; p += 2 )
1264             line[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]);
1265         line[fprlen] = 0;
1266
1267       repeat:
1268         rc = tdbio_search_dir_byfpr( line, fprlen, 0, &rec );
1269         if( !rc ) { /* found: update */
1270             if( rec.r.dir.ownertrust )
1271                 log_info("LID %lu: changing trust from %u to %u\n",
1272                           rec.r.dir.lid, rec.r.dir.ownertrust, otrust );
1273             else
1274                 log_info("LID %lu: setting trust to %u\n",
1275                                    rec.r.dir.lid, otrust );
1276             rec.r.dir.ownertrust = otrust;
1277             write_record( &rec );
1278         }
1279         else if( rc == -1 ) { /* not found; get the key from the ring */
1280             PKT_public_key *pk = m_alloc_clear( sizeof *pk );
1281
1282             log_info_f(fname, _("key not in trustdb, searching ring.\n"));
1283             rc = get_pubkey_byfprint( pk, line, fprlen );
1284             if( rc )
1285                 log_info_f(fname, _("key not in ring: %s\n"), g10_errstr(rc));
1286             else {
1287                 rc = query_trust_record( pk );  /* only as assertion */
1288                 if( rc != -1 )
1289                     log_error_f(fname, _("Oops: key is now in trustdb???\n"));
1290                 else {
1291                     rc = insert_trust_record( pk );
1292                     if( !rc )
1293                         goto repeat; /* update the ownertrust */
1294                     log_error_f(fname, _("insert trust record failed: %s\n"),
1295                                                            g10_errstr(rc) );
1296                 }
1297             }
1298         }
1299         else /* error */
1300             log_error_f(fname, _("error finding dir record: %s\n"),
1301                                                     g10_errstr(rc));
1302     }
1303     if( ferror(fp) )
1304         log_error_f(fname, _("read error: %s\n"), strerror(errno) );
1305     if( !is_stdin )
1306         fclose(fp);
1307     do_sync();
1308 }
1309
1310
1311
1312 #if 0
1313 static void
1314 print_path( int pathlen, TN ME .........., FILE *fp, ulong highlight )
1315 {
1316     int rc, c, i;
1317     u32 keyid[2];
1318     char *p;
1319     size_t n;
1320
1321     for( i = 0; i < pathlen; i++ )  {
1322         if( highlight )
1323             fputs(highlight == path[i].lid? "* ":"  ", fp );
1324         rc = keyid_from_lid( path[i].lid, keyid );
1325         if( rc )
1326             fprintf(fp, "????????.%lu:", path[i].lid );
1327         else
1328             fprintf(fp,"%08lX.%lu:", (ulong)keyid[1], path[i].lid );
1329         c = trust_letter(path[i].otrust);
1330         if( c )
1331             putc( c, fp );
1332         else
1333             fprintf( fp, "%02x", path[i].otrust );
1334         putc('/', fp);
1335         c = trust_letter(path[i].trust);
1336         if( c )
1337             putc( c, fp );
1338         else
1339             fprintf( fp, "%02x", path[i].trust );
1340         putc(' ', fp);
1341         p = get_user_id( keyid, &n );
1342         putc(' ', fp);
1343         putc('\"', fp);
1344         print_string( fp, p, n > 40? 40:n, 0 );
1345         putc('\"', fp);
1346         m_free(p);
1347         putc('\n', fp );
1348     }
1349 }
1350 #endif
1351
1352
1353
1354 static int
1355 propagate_validity( TN node )
1356 {
1357     TN kr, ur;
1358     int max_validity = 0;
1359
1360     assert( !node->is_uid );
1361     if( node->n.k.ownertrust == TRUST_ULTIMATE ) {
1362         /* this is one of our keys */
1363         assert( !node->list ); /* This should be a leaf */
1364         return TRUST_ULTIMATE;
1365     }
1366
1367     /* loop over all user ids */
1368     for( ur=node->list; ur; ur = ur->next ) {
1369         assert( ur->is_uid );
1370         /* loop over all signators */
1371         for(kr=ur->list; kr; kr = kr->next ) {
1372             int val = propagate_validity( kr );
1373
1374             if( val == TRUST_ULTIMATE ) {
1375                 ur->n.u.fully_count = opt.completes_needed;
1376             }
1377             else if( val == TRUST_FULLY ) {
1378                 if( kr->n.k.ownertrust == TRUST_FULLY )
1379                     ur->n.u.fully_count++;
1380                 else if( kr->n.k.ownertrust == TRUST_MARGINAL )
1381                     ur->n.u.marginal_count++;
1382             }
1383         }
1384         /* fixme: We can move this test into the loop to stop as soon as
1385          * we have a level of FULLY and return from this function
1386          * We dont do this now to get better debug output */
1387         if( ur->n.u.fully_count >= opt.completes_needed
1388             || ur->n.u.marginal_count >= opt.marginals_needed )
1389             ur->n.u.validity = TRUST_FULLY;
1390         else if( ur->n.u.fully_count || ur->n.u.marginal_count )
1391             ur->n.u.validity = TRUST_MARGINAL;
1392
1393         if( ur->n.u.validity >= max_validity )
1394             max_validity = ur->n.u.validity;
1395     }
1396
1397     node->n.k.validity = max_validity;
1398     return max_validity;
1399 }
1400
1401
1402 static void
1403 print_default_uid( ulong lid )
1404 {
1405     u32 keyid[2];
1406
1407     if( !keyid_from_lid( lid, keyid ) )
1408         print_user_id( "", keyid );
1409 }
1410
1411
1412 static void
1413 dump_tn_tree( int indent, TN tree )
1414 {
1415     TN kr, ur;
1416
1417     for( kr=tree; kr; kr = kr->next ) {
1418         printf("%*s", indent*4, "" );
1419         printf("K%lu(ot=%d,val=%d)  ", kr->lid,
1420                                          kr->n.k.ownertrust,
1421                                          kr->n.k.validity  );
1422         print_default_uid( kr->lid );
1423         for( ur=kr->list; ur; ur = ur->next ) {
1424             printf("%*s  ", indent*4, "" );
1425             printf("U%lu(mc=%d,fc=%d,val=%d)\n", ur->lid,
1426                                                  ur->n.u.marginal_count,
1427                                                  ur->n.u.fully_count,
1428                                                  ur->n.u.validity
1429                                             );
1430             dump_tn_tree( indent+1, ur->list );
1431         }
1432     }
1433 }
1434
1435
1436 void
1437 list_trust_path( const char *username )
1438 {
1439     int rc;
1440     ulong lid;
1441     TRUSTREC rec;
1442     TN tree;
1443     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
1444
1445     INIT_TRUSTDB();
1446     if( (rc = get_pubkey_byname(NULL, pk, username, NULL )) )
1447         log_error(_("user '%s' not found: %s\n"), username, g10_errstr(rc) );
1448     else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
1449         log_error(_("problem finding '%s' in trustdb: %s\n"),
1450                                             username, g10_errstr(rc));
1451     else if( rc == -1 ) {
1452         log_info(_("user '%s' not in trustdb - inserting\n"), username);
1453         rc = insert_trust_record( pk );
1454         if( rc )
1455             log_error(_("failed to put '%s' into trustdb: %s\n"),
1456                                                     username, g10_errstr(rc));
1457         else {
1458             assert( pk->local_id );
1459         }
1460     }
1461     lid = pk->local_id;
1462     free_public_key( pk );
1463
1464     tree = build_cert_tree( lid, 0, opt.max_cert_depth, NULL );
1465     if( tree )
1466         propagate_validity( tree );
1467     dump_tn_tree( 0, tree );
1468     printf("(alloced tns=%d  max=%d)\n", alloced_tns, max_alloced_tns );
1469     release_tn_tree( tree );
1470 }
1471
1472
1473 /****************
1474  * Check the complete trustdb or only the entries for the given username.
1475  * We check the complete database. If a username is given or the special
1476  * username "*" is used, a complete recheck is done.  With no user ID
1477  * only the records which are not yet checkd are now checked.
1478  */
1479 void
1480 check_trustdb( const char *username )
1481 {
1482     TRUSTREC rec;
1483     KBNODE keyblock = NULL;
1484     KBPOS kbpos;
1485     int rc;
1486     int recheck = username && *username == '*' && !username[1];
1487
1488     INIT_TRUSTDB();
1489     if( username && !recheck ) {
1490         rc = find_keyblock_byname( &kbpos, username );
1491         if( !rc )
1492             rc = read_keyblock( &kbpos, &keyblock );
1493         if( rc ) {
1494             log_error(_("%s: keyblock read problem: %s\n"),
1495                                     username, g10_errstr(rc));
1496         }
1497         else {
1498             int modified;
1499
1500             rc = update_trust_record( keyblock, 1, &modified );
1501             if( rc == -1 ) { /* not yet in trustdb: insert */
1502                 rc = insert_trust_record(
1503                             find_kbnode( keyblock, PKT_PUBLIC_KEY
1504                                        ) ->pkt->pkt.public_key );
1505
1506             }
1507             if( rc )
1508                 log_error(_("%s: update failed: %s\n"),
1509                                            username, g10_errstr(rc) );
1510             else if( modified )
1511                 log_info(_("%s: updated\n"), username );
1512             else
1513                 log_info(_("%s: okay\n"), username );
1514
1515         }
1516         release_kbnode( keyblock ); keyblock = NULL;
1517     }
1518     else {
1519         ulong recnum;
1520         ulong count=0, upd_count=0, err_count=0, skip_count=0;
1521
1522         for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
1523             if( rec.rectype == RECTYPE_DIR ) {
1524                 TRUSTREC tmp;
1525                 int modified;
1526
1527                 if( !rec.r.dir.keylist ) {
1528                     log_info(_("lid %lu: dir record w/o key - skipped\n"),
1529                                                                   recnum);
1530                     count++;
1531                     skip_count++;
1532                     continue;
1533                 }
1534
1535                 read_record( rec.r.dir.keylist, &tmp, RECTYPE_KEY );
1536
1537                 rc = get_keyblock_byfprint( &keyblock,
1538                                             tmp.r.key.fingerprint,
1539                                             tmp.r.key.fingerprint_len );
1540                 if( rc ) {
1541                     log_error(_("lid %lu: keyblock not found: %s\n"),
1542                                                  recnum, g10_errstr(rc) );
1543                     count++;
1544                     skip_count++;
1545                     continue;
1546                 }
1547
1548                 rc = update_trust_record( keyblock, recheck, &modified );
1549                 if( rc ) {
1550                     log_error(_("lid %lu: update failed: %s\n"),
1551                                                  recnum, g10_errstr(rc) );
1552                     err_count++;
1553                 }
1554                 else if( modified ) {
1555                     if( opt.verbose )
1556                         log_info(_("lid %lu: updated\n"), recnum );
1557                     upd_count++;
1558                 }
1559                 else if( opt.verbose > 1 )
1560                     log_info(_("lid %lu: okay\n"), recnum );
1561
1562                 release_kbnode( keyblock ); keyblock = NULL;
1563                 if( !(++count % 100) )
1564                     log_info(_("%lu keys so far processed\n"), count);
1565             }
1566         }
1567         log_info(_("%lu keys processed\n"), count);
1568         if( skip_count )
1569             log_info(_("\t%lu keys skipped\n"), skip_count);
1570         if( err_count )
1571             log_info(_("\t%lu keys with errors\n"), err_count);
1572         if( upd_count )
1573             log_info(_("\t%lu keys updated\n"), upd_count);
1574     }
1575 }
1576
1577
1578 /****************
1579  * Put new entries  from the pubrings into the trustdb.
1580  * This function honors the sig flags to speed up the check.
1581  */
1582 void
1583 update_trustdb( )
1584 {
1585     KBNODE keyblock = NULL;
1586     KBPOS kbpos;
1587     int rc;
1588
1589     if( opt.dry_run )
1590         return;
1591
1592     INIT_TRUSTDB();
1593     rc = enum_keyblocks( 0, &kbpos, &keyblock );
1594     if( !rc ) {
1595         ulong count=0, upd_count=0, err_count=0, new_count=0;
1596
1597         while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
1598             int modified;
1599
1600             rc = update_trust_record( keyblock, 1, &modified );
1601             if( rc == -1 ) { /* not yet in trustdb: insert */
1602                 PKT_public_key *pk =
1603                             find_kbnode( keyblock, PKT_PUBLIC_KEY
1604                                        ) ->pkt->pkt.public_key;
1605                 rc = insert_trust_record( pk );
1606                 if( rc && !pk->local_id ) {
1607                     log_error(_("lid ?: insert failed: %s\n"),
1608                                                      g10_errstr(rc) );
1609                     err_count++;
1610                 }
1611                 else if( rc ) {
1612                     log_error(_("lid %lu: insert failed: %s\n"),
1613                                        pk->local_id, g10_errstr(rc) );
1614                     err_count++;
1615                 }
1616                 else {
1617                     if( opt.verbose )
1618                         log_info(_("lid %lu: inserted\n"), pk->local_id );
1619                     new_count++;
1620                 }
1621             }
1622             else if( rc ) {
1623                 log_error(_("lid %lu: update failed: %s\n"),
1624                          lid_from_keyblock(keyblock), g10_errstr(rc) );
1625                 err_count++;
1626             }
1627             else if( modified ) {
1628                 if( opt.verbose )
1629                     log_info(_("lid %lu: updated\n"), lid_from_keyblock(keyblock));
1630                 upd_count++;
1631             }
1632             else if( opt.verbose > 1 )
1633                 log_info(_("lid %lu: okay\n"), lid_from_keyblock(keyblock) );
1634
1635             release_kbnode( keyblock ); keyblock = NULL;
1636             if( !(++count % 100) )
1637                 log_info(_("%lu keys so far processed\n"), count);
1638         }
1639         log_info(_("%lu keys processed\n"), count);
1640         if( err_count )
1641             log_info(_("\t%lu keys with errors\n"), err_count);
1642         if( upd_count )
1643             log_info(_("\t%lu keys updated\n"), upd_count);
1644         if( new_count )
1645             log_info(_("\t%lu keys inserted\n"), new_count);
1646     }
1647     if( rc && rc != -1 )
1648         log_error(_("enumerate keyblocks failed: %s\n"), g10_errstr(rc));
1649
1650     enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
1651     release_kbnode( keyblock );
1652 }
1653
1654
1655 \f
1656 /****************
1657  * Get the trustlevel for this PK.
1658  * Note: This does not ask any questions
1659  * Returns: 0 okay of an errorcode
1660  *
1661  * It operates this way:
1662  *  locate the pk in the trustdb
1663  *      found:
1664  *          Do we have a valid cache record for it?
1665  *              yes: return trustlevel from cache
1666  *              no:  make a cache record and all the other stuff
1667  *      not found:
1668  *          try to insert the pubkey into the trustdb and check again
1669  *
1670  * Problems: How do we get the complete keyblock to check that the
1671  *           cache record is actually valid?  Think we need a clever
1672  *           cache in getkey.c  to keep track of this stuff. Maybe it
1673  *           is not necessary to check this if we use a local pubring. Hmmmm.
1674  */
1675 int
1676 check_trust( PKT_public_key *pk, unsigned *r_trustlevel, const byte *namehash )
1677 {
1678     TRUSTREC rec;
1679     unsigned trustlevel = TRUST_UNKNOWN;
1680     int rc=0;
1681     u32 cur_time;
1682     u32 keyid[2];
1683
1684
1685     INIT_TRUSTDB();
1686     keyid_from_pk( pk, keyid );
1687
1688     /* get the pubkey record */
1689     if( pk->local_id ) {
1690         read_record( pk->local_id, &rec, RECTYPE_DIR );
1691     }
1692     else { /* no local_id: scan the trustdb */
1693         if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) {
1694             log_error(_("check_trust: search dir record failed: %s\n"),
1695                                                             g10_errstr(rc));
1696             return rc;
1697         }
1698         else if( rc == -1 ) { /* not found - insert */
1699             rc = insert_trust_record( pk );
1700             if( rc ) {
1701                 log_error(_("key %08lX: insert trust record failed: %s\n"),
1702                                           (ulong)keyid[1], g10_errstr(rc));
1703                 goto leave;
1704             }
1705             log_info(_("key %08lX.%lu: inserted into trustdb\n"),
1706                                           (ulong)keyid[1], pk->local_id );
1707             /* and re-read the dir record */
1708             read_record( pk->local_id, &rec, RECTYPE_DIR );
1709         }
1710     }
1711     cur_time = make_timestamp();
1712     if( pk->timestamp > cur_time ) {
1713         log_info(_("key %08lX.%lu: created in future "
1714                    "(time warp or clock problem)\n"),
1715                                           (ulong)keyid[1], pk->local_id );
1716         return G10ERR_TIME_CONFLICT;
1717     }
1718
1719     if( pk->expiredate && pk->expiredate <= cur_time ) {
1720         log_info(_("key %08lX.%lu: expired at %s\n"),
1721                         (ulong)keyid[1], pk->local_id,
1722                              asctimestamp( pk->expiredate) );
1723          trustlevel = TRUST_EXPIRED;
1724     }
1725     else {
1726         rc = do_check( &rec, &trustlevel, namehash );
1727         if( rc ) {
1728             log_error(_("key %08lX.%lu: trust check failed: %s\n"),
1729                             (ulong)keyid[1], pk->local_id, g10_errstr(rc));
1730             return rc;
1731         }
1732     }
1733
1734
1735   leave:
1736     if( DBG_TRUST )
1737         log_debug("check_trust() returns trustlevel %04x.\n", trustlevel);
1738     *r_trustlevel = trustlevel;
1739     return 0;
1740 }
1741
1742
1743
1744
1745 int
1746 query_trust_info( PKT_public_key *pk, const byte *namehash )
1747 {
1748     unsigned trustlevel;
1749     int c;
1750
1751     INIT_TRUSTDB();
1752     if( check_trust( pk, &trustlevel, namehash ) )
1753         return '?';
1754     if( trustlevel & TRUST_FLAG_REVOKED )
1755         return 'r';
1756     c = trust_letter( (trustlevel & TRUST_MASK) );
1757     if( !c )
1758         c = '?';
1759     return c;
1760 }
1761
1762
1763
1764 /****************
1765  * Enumerate all keys, which are needed to build all trust paths for
1766  * the given key.  This function does not return the key itself or
1767  * the ultimate key (the last point in cerificate chain).  Only
1768  * certificate chains which ends up at an ultimately trusted key
1769  * are listed.  If ownertrust or validity is not NULL, the corresponding
1770  * value for the returned LID is also returned in these variable(s).
1771  *
1772  *  1) create a void pointer and initialize it to NULL
1773  *  2) pass this void pointer by reference to this function.
1774  *     Set lid to the key you want to enumerate and pass it by reference.
1775  *  3) call this function as long as it does not return -1
1776  *     to indicate EOF. LID does contain the next key used to build the web
1777  *  4) Always call this function a last time with LID set to NULL,
1778  *     so that it can free its context.
1779  *
1780  * Returns: -1 on EOF or the level of the returned LID
1781  */
1782 int
1783 enum_cert_paths( void **context, ulong *lid,
1784                  unsigned *ownertrust, unsigned *validity )
1785 {
1786     return -1;
1787   #if 0
1788     struct enum_cert_paths_ctx *ctx;
1789     fixme: .....   tsl;
1790
1791     INIT_TRUSTDB();
1792     if( !lid ) {  /* release the context */
1793         if( *context ) {
1794             FIXME: ........tsl2;
1795
1796             ctx = *context;
1797             for(tsl = ctx->tsl_head; tsl; tsl = tsl2 ) {
1798                 tsl2 = tsl->next;
1799                 m_free( tsl );
1800             }
1801             *context = NULL;
1802         }
1803         return -1;
1804     }
1805
1806     if( !*context ) {
1807         FIXME .... *tmppath;
1808         TRUSTREC rec;
1809
1810         if( !*lid )
1811             return -1;
1812
1813         ctx = m_alloc_clear( sizeof *ctx );
1814         *context = ctx;
1815         /* collect the paths */
1816       #if 0
1817         read_record( *lid, &rec, RECTYPE_DIR );
1818         tmppath = m_alloc_clear( (opt.max_cert_depth+1)* sizeof *tmppath );
1819         tsl = NULL;
1820         collect_paths( 0, opt.max_cert_depth, 1, &rec, tmppath, &tsl );
1821         m_free( tmppath );
1822         sort_tsl_list( &tsl );
1823       #endif
1824         /* setup the context */
1825         ctx->tsl_head = tsl;
1826         ctx->tsl = ctx->tsl_head;
1827         ctx->idx = 0;
1828     }
1829     else
1830         ctx = *context;
1831
1832     while( ctx->tsl && ctx->idx >= ctx->tsl->pathlen )  {
1833         ctx->tsl = ctx->tsl->next;
1834         ctx->idx = 0;
1835     }
1836     tsl = ctx->tsl;
1837     if( !tsl )
1838         return -1; /* eof */
1839
1840     if( ownertrust )
1841         *ownertrust = tsl->path[ctx->idx].otrust;
1842     if( validity )
1843         *validity = tsl->path[ctx->idx].trust;
1844     *lid = tsl->path[ctx->idx].lid;
1845     ctx->idx++;
1846     return ctx->idx-1;
1847   #endif
1848 }
1849
1850
1851 /****************
1852  * Print the current path
1853  */
1854 void
1855 enum_cert_paths_print( void **context, FILE *fp,
1856                                        int refresh, ulong selected_lid )
1857 {
1858     return;
1859   #if 0
1860     struct enum_cert_paths_ctx *ctx;
1861     FIXME......... tsl;
1862
1863     if( !*context )
1864         return;
1865     INIT_TRUSTDB();
1866     ctx = *context;
1867     if( !ctx->tsl )
1868         return;
1869     tsl = ctx->tsl;
1870
1871     if( !fp )
1872         fp = stderr;
1873
1874     if( refresh ) { /* update the ownertrust and if possible the validity */
1875         int i;
1876         int match = tdbio_db_matches_options();
1877
1878         for( i = 0; i < tsl->pathlen; i++ )  {
1879             TRUSTREC rec;
1880
1881             read_record( tsl->path[i].lid, &rec, RECTYPE_DIR );
1882             tsl->path[i].otrust = rec.r.dir.ownertrust;
1883             /* update validity only if we have it in the cache
1884              * calculation is too time consuming */
1885             if( match && (rec.r.dir.dirflags & DIRF_VALVALID)
1886                       && rec.r.dir.validity ) {
1887                 tsl->path[i].trust = rec.r.dir.validity;
1888                 if( rec.r.dir.dirflags & DIRF_REVOKED )
1889                     tsl->path[i].trust = TRUST_FLAG_REVOKED;
1890             }
1891         }
1892     }
1893
1894     print_path( tsl->pathlen, tsl->path, fp, selected_lid );
1895   #endif
1896 }
1897
1898
1899 /****************
1900  * Return the assigned ownertrust value for the given LID
1901  */
1902 unsigned
1903 get_ownertrust( ulong lid )
1904 {
1905     TRUSTREC rec;
1906
1907     INIT_TRUSTDB();
1908     read_record( lid, &rec, RECTYPE_DIR );
1909     return rec.r.dir.ownertrust;
1910 }
1911
1912 int
1913 get_ownertrust_info( ulong lid )
1914 {
1915     unsigned otrust;
1916     int c;
1917
1918     INIT_TRUSTDB();
1919     otrust = get_ownertrust( lid );
1920     c = trust_letter( (otrust & TRUST_MASK) );
1921     if( !c )
1922         c = '?';
1923     return c;
1924 }
1925
1926 /*
1927  * Return an allocated buffer with the preference values for
1928  * the key with LID and the userid which is identified by the
1929  * HAMEHASH or the firstone if namehash is NULL.  ret_n receives
1930  * the length of the allocated buffer.  Structure of the buffer is
1931  * a repeated sequences of 2 bytes; where the first byte describes the
1932  * type of the preference and the second one the value.  The constants
1933  * PREFTYPE_xxxx should be used to reference a type.
1934  */
1935 byte *
1936 get_pref_data( ulong lid, const byte *namehash, size_t *ret_n )
1937 {
1938     TRUSTREC rec;
1939     ulong recno;
1940
1941     INIT_TRUSTDB();
1942     read_record( lid, &rec, RECTYPE_DIR );
1943     for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
1944         read_record( recno, &rec, RECTYPE_UID );
1945         if( rec.r.uid.prefrec
1946             && ( !namehash || !memcmp(namehash, rec.r.uid.namehash, 20) ))  {
1947             byte *buf;
1948             /* found the correct one or the first one */
1949             read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
1950             if( rec.r.pref.next )
1951                 log_info(_("WARNING: can't yet handle long pref records\n"));
1952             buf = m_alloc( ITEMS_PER_PREF_RECORD );
1953             memcpy( buf, rec.r.pref.data, ITEMS_PER_PREF_RECORD );
1954             *ret_n = ITEMS_PER_PREF_RECORD;
1955             return buf;
1956         }
1957     }
1958     return NULL;
1959 }
1960
1961
1962
1963 /****************
1964  * Check whether the algorithm is in one of the pref records
1965  */
1966 int
1967 is_algo_in_prefs( ulong lid, int preftype, int algo )
1968 {
1969     TRUSTREC rec;
1970     ulong recno;
1971     int i;
1972     byte *pref;
1973
1974     INIT_TRUSTDB();
1975     read_record( lid, &rec, RECTYPE_DIR );
1976     for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
1977         read_record( recno, &rec, RECTYPE_UID );
1978         if( rec.r.uid.prefrec ) {
1979             read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
1980             if( rec.r.pref.next )
1981                 log_info(_("WARNING: can't yet handle long pref records\n"));
1982             pref = rec.r.pref.data;
1983             for(i=0; i+1 < ITEMS_PER_PREF_RECORD; i+=2 ) {
1984                 if( pref[i] == preftype && pref[i+1] == algo )
1985                     return 1;
1986             }
1987         }
1988     }
1989     return 0;
1990 }
1991
1992
1993 static int
1994 get_dir_record( PKT_public_key *pk, TRUSTREC *rec )
1995 {
1996     int rc=0;
1997
1998     if( pk->local_id ) {
1999         read_record( pk->local_id, rec, RECTYPE_DIR );
2000     }
2001     else { /* no local_id: scan the trustdb */
2002         if( (rc=tdbio_search_dir_bypk( pk, rec )) && rc != -1 )
2003             log_error(_("get_dir_record: search_record failed: %s\n"),
2004                                                             g10_errstr(rc));
2005     }
2006     return rc;
2007 }
2008
2009
2010
2011 /****************
2012  * This function simply looks for the key in the trustdb
2013  * and makes sure that pk->local_id is set to the correct value.
2014  * Return: 0 = found
2015  *         -1 = not found
2016  *        other = error
2017  */
2018 int
2019 query_trust_record( PKT_public_key *pk )
2020 {
2021     TRUSTREC rec;
2022     INIT_TRUSTDB();
2023     return get_dir_record( pk, &rec );
2024 }
2025
2026
2027 int
2028 clear_trust_checked_flag( PKT_public_key *pk )
2029 {
2030     TRUSTREC rec;
2031     int rc;
2032
2033     if( opt.dry_run )
2034         return 0;
2035
2036     INIT_TRUSTDB();
2037     rc = get_dir_record( pk, &rec );
2038     if( rc )
2039         return rc;
2040
2041     /* check whether they are already reset */
2042     if(   !(rec.r.dir.dirflags & DIRF_CHECKED)
2043        && !(rec.r.dir.dirflags & DIRF_VALVALID) )
2044         return 0;
2045
2046     /* reset the flag */
2047     rec.r.dir.dirflags &= ~DIRF_CHECKED;
2048     rec.r.dir.dirflags &= ~DIRF_VALVALID;
2049     write_record( &rec );
2050     do_sync();
2051     return 0;
2052 }
2053
2054
2055
2056
2057 static void
2058 check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
2059                 TRUSTREC *sigrec, int sigidx, ulong hint_owner )
2060 {
2061     KBNODE node;
2062     int rc, state;
2063     byte uhash[20];
2064     int is_selfsig;
2065     PKT_signature *sigpkt = NULL;
2066     TRUSTREC tmp;
2067     u32 sigkid[2];
2068     int revoked = 0;
2069
2070     if( sigrec->r.sig.sig[sigidx].flag & SIGF_CHECKED )
2071         log_info(_("NOTE: sig rec %lu[%d] in hintlist "
2072                    "of %lu but marked as checked\n"),
2073                     sigrec->recnum, sigidx, hint_owner );
2074     if( !(sigrec->r.sig.sig[sigidx].flag & SIGF_NOPUBKEY) )
2075         log_info(_("NOTE: sig rec %lu[%d] in hintlist "
2076                    "of %lu but not marked\n"),
2077                     sigrec->recnum, sigidx, hint_owner );
2078
2079     read_record( sigrec->r.sig.sig[sigidx].lid, &tmp, 0 );
2080     if( tmp.rectype != RECTYPE_DIR ) {
2081         /* we need the dir record */
2082         log_error(_("sig rec %lu[%d] in hintlist "
2083                     "of %lu does not point to a dir record\n"),
2084                     sigrec->recnum, sigidx, hint_owner );
2085         return;
2086     }
2087     if( !tmp.r.dir.keylist ) {
2088         log_error(_("lid %lu: no primary key\n"), tmp.r.dir.lid );
2089         return;
2090     }
2091     read_record(tmp.r.dir.keylist, &tmp, RECTYPE_KEY );
2092     keyid_from_fingerprint( tmp.r.key.fingerprint,
2093                             tmp.r.key.fingerprint_len, sigkid );
2094
2095
2096     /* find the correct signature packet */
2097     state = 0;
2098     for( node=keyblock; node; node = node->next ) {
2099         if( node->pkt->pkttype == PKT_USER_ID ) {
2100             PKT_user_id *uidpkt = node->pkt->pkt.user_id;
2101
2102             if( state )
2103                 break;
2104             rmd160_hash_buffer( uhash, uidpkt->name, uidpkt->len );
2105             if( !memcmp( uhash, uidrec_hash, 20 ) )
2106                 state = 1;
2107         }
2108         else if( state && node->pkt->pkttype == PKT_SIGNATURE ) {
2109             sigpkt = node->pkt->pkt.signature;
2110             if( sigpkt->keyid[0] == sigkid[0]
2111                 && sigpkt->keyid[1] == sigkid[1]
2112                 && ( (sigpkt->sig_class&~3) == 0x10
2113                      || ( revoked = (sigpkt->sig_class == 0x30)) ) ) {
2114                 state = 2;
2115                 break; /* found */
2116             }
2117         }
2118     }
2119
2120     if( !node ) {
2121         log_info(_("lid %lu: user id not found in keyblock\n"), lid );
2122         return ;
2123     }
2124     if( state != 2 ) {
2125         log_info(_("lid %lu: user id without signature\n"), lid );
2126         return ;
2127     }
2128
2129     /* and check the sig */
2130     rc = check_key_signature( keyblock, node, &is_selfsig );
2131     if( is_selfsig ) {
2132         log_error(_("lid %lu: self-signature in hintlist\n"), lid );
2133         return;
2134     }
2135
2136     /* FiXME: handling fo SIGF_REVOKED is not correct! */
2137
2138     if( !rc ) { /* valid signature */
2139         if( opt.verbose )
2140             log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2141                     (ulong)keyid[1], lid, uhash[18], uhash[19],
2142                     (ulong)sigpkt->keyid[1],
2143                     revoked? _("Valid certificate revocation")
2144                            : _("Good certificate") );
2145         sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED | SIGF_VALID;
2146         if( revoked )
2147             sigrec->r.sig.sig[sigidx].flag |= SIGF_REVOKED;
2148     }
2149     else if( rc == G10ERR_NO_PUBKEY ) {
2150         log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2151               (ulong)keyid[1], lid, uhash[18], uhash[19],
2152                (ulong)sigpkt->keyid[1],
2153                  _("very strange: no public key\n") );
2154         sigrec->r.sig.sig[sigidx].flag = SIGF_NOPUBKEY;
2155     }
2156     else {
2157         log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2158                     (ulong)keyid[1], lid, uhash[18], uhash[19],
2159                     (ulong)sigpkt->keyid[1], g10_errstr(rc) );
2160         sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED;
2161     }
2162     sigrec->dirty = 1;
2163 }
2164
2165
2166 /****************
2167  * Process a hintlist.
2168  * Fixme: this list is not anymore anchored to another
2169  *        record, so it should be put elsewehere in case of an error
2170  */
2171 static void
2172 process_hintlist( ulong hintlist, ulong hint_owner )
2173 {
2174     ulong hlst_rn;
2175     int rc;
2176
2177     for( hlst_rn = hintlist; hlst_rn; ) {
2178         TRUSTREC hlstrec;
2179         int hlst_idx;
2180
2181         read_record( hlst_rn, &hlstrec, RECTYPE_HLST );
2182
2183         for( hlst_idx=0; hlst_idx < ITEMS_PER_HLST_RECORD; hlst_idx++ ) {
2184             TRUSTREC dirrec;
2185             TRUSTREC uidrec;
2186             TRUSTREC tmprec;
2187             KBNODE keyblock = NULL;
2188             u32 keyid[2];
2189             ulong lid;
2190             ulong r1, r2;
2191
2192             lid = hlstrec.r.hlst.rnum[hlst_idx];
2193             if( !lid )
2194                 continue;
2195
2196             read_record( lid, &dirrec, 0 );
2197             /* make sure it points to a dir record:
2198              * this should be true because it only makes sense to
2199              * call this function if the dir record is available */
2200             if( dirrec.rectype != RECTYPE_DIR )  {
2201                 log_error(_("hintlist %lu[%d] of %lu "
2202                             "does not point to a dir record\n"),
2203                             hlst_rn, hlst_idx, hint_owner );
2204                 continue;
2205             }
2206             if( !dirrec.r.dir.keylist ) {
2207                 log_error(_("lid %lu does not have a key\n"), lid );
2208                 continue;
2209             }
2210
2211             /* get the keyblock */
2212             read_record( dirrec.r.dir.keylist, &tmprec, RECTYPE_KEY );
2213             rc = get_keyblock_byfprint( &keyblock,
2214                                         tmprec.r.key.fingerprint,
2215                                         tmprec.r.key.fingerprint_len );
2216             if( rc ) {
2217                 log_error(_("lid %lu: can't get keyblock: %s\n"),
2218                                                     lid, g10_errstr(rc) );
2219                 continue;
2220             }
2221             keyid_from_fingerprint( tmprec.r.key.fingerprint,
2222                                     tmprec.r.key.fingerprint_len, keyid );
2223
2224             /* Walk over all user ids and their signatures and check all
2225              * the signature which are created by hint_owner */
2226             for( r1 = dirrec.r.dir.uidlist; r1; r1 = uidrec.r.uid.next ) {
2227                 TRUSTREC sigrec;
2228
2229                 read_record( r1, &uidrec, RECTYPE_UID );
2230                 for( r2 = uidrec.r.uid.siglist; r2; r2 = sigrec.r.sig.next ) {
2231                     int i;
2232
2233                     read_record( r2, &sigrec, RECTYPE_SIG );
2234                     sigrec.dirty = 0;
2235                     for(i=0; i < SIGS_PER_RECORD; i++ ) {
2236                         if( !sigrec.r.sig.sig[i].lid )
2237                             continue; /* skip deleted sigs */
2238                         if( sigrec.r.sig.sig[i].lid != hint_owner )
2239                             continue; /* not for us */
2240                         /* some diagnostic messages */
2241                         /* and do the signature check */
2242                         check_hint_sig( lid, keyblock, keyid,
2243                                         uidrec.r.uid.namehash,
2244                                         &sigrec, i, hint_owner );
2245                     }
2246                     if( sigrec.dirty )
2247                         write_record( &sigrec );
2248                 }
2249             }
2250             release_kbnode( keyblock );
2251         } /* loop over hlst entries */
2252
2253         /* delete this hlst record */
2254         hlst_rn = hlstrec.r.hlst.next;
2255         delete_record( hlstrec.recnum );
2256     } /* loop over hintlist */
2257 }
2258
2259
2260 /****************
2261  * Create or update shadow dir record and return the LID of the record
2262  */
2263 static ulong
2264 create_shadow_dir( PKT_signature *sig, ulong lid  )
2265 {
2266     TRUSTREC sdir, hlst, tmphlst;
2267     ulong recno, newlid;
2268     int tmpidx=0; /* avoids gcc warnign - this is controlled by tmphlst */
2269     int rc;
2270
2271     /* first see whether we already have such a record */
2272     rc = tdbio_search_sdir( sig->keyid, sig->pubkey_algo, &sdir );
2273     if( rc && rc != -1 ) {
2274         log_error(_("tdbio_search_dir failed: %s\n"), g10_errstr(rc));
2275         die_invalid_db();
2276     }
2277     if( rc == -1 ) { /* not found: create */
2278         memset( &sdir, 0, sizeof sdir );
2279         sdir.recnum = tdbio_new_recnum();
2280         sdir.rectype= RECTYPE_SDIR;
2281         sdir.r.sdir.lid = sdir.recnum;
2282         sdir.r.sdir.keyid[0] = sig->keyid[0];
2283         sdir.r.sdir.keyid[1] = sig->keyid[1];
2284         sdir.r.sdir.pubkey_algo = sig->pubkey_algo;
2285         sdir.r.sdir.hintlist = 0;
2286         write_record( &sdir );
2287     }
2288     newlid = sdir.recnum;
2289     /* Put the record number into the hintlist.
2290      * (It is easier to use the lid and not the record number of the
2291      *  key to save some space (assuming that a signator has
2292      *  signed more than one user id - and it is easier to implement.)
2293      */
2294     tmphlst.recnum = 0;
2295     for( recno=sdir.r.sdir.hintlist; recno; recno = hlst.r.hlst.next) {
2296         int i;
2297         read_record( recno, &hlst, RECTYPE_HLST );
2298         for( i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
2299             if( !hlst.r.hlst.rnum[i] ) {
2300                 if( !tmphlst.recnum ) {
2301                     tmphlst = hlst;
2302                     tmpidx = i;
2303                 }
2304             }
2305             else if( hlst.r.hlst.rnum[i] == lid )
2306                 return newlid; /* the signature is already in the hintlist */
2307         }
2308     }
2309     /* not yet in the hint list, write it */
2310     if( tmphlst.recnum ) { /* we have an empty slot */
2311         tmphlst.r.hlst.rnum[tmpidx] = lid;
2312         write_record( &tmphlst );
2313     }
2314     else { /* must append a new hlst record */
2315         memset( &hlst, 0, sizeof hlst );
2316         hlst.recnum = tdbio_new_recnum();
2317         hlst.rectype = RECTYPE_HLST;
2318         hlst.r.hlst.next = sdir.r.sdir.hintlist;
2319         hlst.r.hlst.rnum[0] = lid;
2320         write_record( &hlst );
2321         sdir.r.sdir.hintlist = hlst.recnum;
2322         write_record( &sdir );
2323     }
2324
2325     return newlid;
2326 }
2327
2328
2329 /****************
2330  * This function checks the given public key and inserts or updates
2331  * the keyrecord from the trustdb.  Revocation certificates
2332  * are handled here and the keybinding of subkeys is checked.
2333  * Hmmm: Should we check here, that the key has at least one valid
2334  * user ID or do we allow keys w/o user ID?
2335  *
2336  * keyblock points to the first node in the keyblock,
2337  * keynode is the node with the public key to check
2338  * (either primary or secondary), keyid is the keyid of
2339  * the primary key, drec is the directory record and recno_list
2340  * is a list used to keep track of visited records.
2341  * Existing keyflags are recalculated if recheck is true.
2342  */
2343 static void
2344 upd_key_record( KBNODE keyblock, KBNODE keynode, u32 *keyid,
2345                 TRUSTREC *drec, RECNO_LIST *recno_list, int recheck )
2346 {
2347     TRUSTREC krec;
2348     KBNODE  node;
2349     PKT_public_key *pk = keynode->pkt->pkt.public_key;
2350     ulong lid = drec->recnum;
2351     byte fpr[MAX_FINGERPRINT_LEN];
2352     size_t fprlen;
2353     ulong recno, newrecno;
2354     int keybind_seen = 0;
2355     int revoke_seen = 0;
2356     int rc;
2357
2358     fingerprint_from_pk( pk, fpr, &fprlen );
2359     /* do we already have this key? */
2360     for( recno=drec->r.dir.keylist; recno; recno = krec.r.key.next ) {
2361         read_record( recno, &krec, RECTYPE_KEY );
2362         if( krec.r.key.fingerprint_len == fprlen
2363             && !memcmp( krec.r.key.fingerprint, fpr, fprlen ) )
2364             break;
2365     }
2366     if( recno ) { /* yes */
2367         ins_recno_list( recno_list, recno, RECTYPE_KEY );
2368     }
2369     else { /* no: insert this new key */
2370         recheck = 1;
2371         memset( &krec, 0, sizeof(krec) );
2372         krec.rectype = RECTYPE_KEY;
2373         krec.r.key.lid = lid;
2374         krec.r.key.pubkey_algo = pk->pubkey_algo;
2375         krec.r.key.fingerprint_len = fprlen;
2376         memcpy(krec.r.key.fingerprint, fpr, fprlen );
2377         krec.recnum = newrecno = tdbio_new_recnum();
2378         write_record( &krec );
2379         ins_recno_list( recno_list, newrecno, RECTYPE_KEY );
2380         /* and put this new record at the end of the keylist */
2381         if( !(recno=drec->r.dir.keylist) ) {
2382             /* this is the first key */
2383             drec->r.dir.keylist = newrecno;
2384             drec->dirty = 1;
2385         }
2386         else { /* we already have a key, append the new one */
2387             TRUSTREC save = krec;
2388             for( ; recno; recno = krec.r.key.next )
2389                 read_record( recno, &krec, RECTYPE_KEY );
2390             krec.r.key.next = newrecno;
2391             write_record( &krec );
2392             krec = save;
2393         }
2394     }
2395
2396     if( !recheck && (krec.r.key.keyflags & KEYF_CHECKED) )
2397         return;
2398
2399     /* check keybindings and revocations */
2400     krec.r.key.keyflags = 0;
2401     if( keynode->pkt->pkttype == PKT_PUBLIC_KEY ) {
2402         /* we assume that a primary key is always valid
2403          * and check later whether we have a revocation */
2404         krec.r.key.keyflags |= KEYF_CHECKED | KEYF_VALID;
2405     }
2406
2407     for( node=keynode->next; node; node = node->next ) {
2408         PKT_signature *sig;
2409
2410         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2411             break; /* ready */
2412         else if( node->pkt->pkttype != PKT_SIGNATURE )
2413             continue;
2414
2415         sig = node->pkt->pkt.signature;
2416
2417         if( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
2418             continue; /* not a self signature */
2419         if( sig->sig_class == 0x18 && !keybind_seen ) { /* a keybinding */
2420             if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
2421                 continue; /* oops, not for a main key */
2422             /* we check until we find a valid keybinding */
2423             rc = check_key_signature( keyblock, node, NULL );
2424             if( !rc ) {
2425                 if( opt.verbose )
2426                     log_info(_(
2427                         "key %08lX.%lu: Good subkey binding\n"),
2428                          (ulong)keyid_from_pk(pk,NULL), lid );
2429                 krec.r.key.keyflags |= KEYF_CHECKED | KEYF_VALID;
2430             }
2431             else {
2432                 log_info(_(
2433                   "key %08lX.%lu: Invalid subkey binding: %s\n"),
2434                     (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
2435                 krec.r.key.keyflags |= KEYF_CHECKED;
2436                 krec.r.key.keyflags &= ~KEYF_VALID;
2437             }
2438             keybind_seen = 1;
2439         }
2440         else if( sig->sig_class == 0x20 && !revoke_seen ) {
2441             if( keynode->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2442                 continue; /* a subkey is not expected here */
2443             /* This is a key revocation certificate: check it */
2444             rc = check_key_signature( keyblock, node, NULL );
2445             if( !rc ) {
2446                 if( opt.verbose )
2447                     log_info(_(
2448                         "key %08lX.%lu: Valid key revocation\n"),
2449                          (ulong)keyid_from_pk(pk,NULL), lid );
2450                 krec.r.key.keyflags |= KEYF_REVOKED;
2451             }
2452             else {
2453                 log_info(_(
2454                   "key %08lX.%lu: Invalid key revocation: %s\n"),
2455                   (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
2456             }
2457             revoke_seen = 1;
2458         }
2459         else if( sig->sig_class == 0x28 && !revoke_seen ) {
2460             if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
2461                 continue; /* a mainkey is not expected here */
2462             /* This is a subkey revocation certificate: check it */
2463             /* fixme: we should also check the revocation
2464              * is newer than the key (OpenPGP) */
2465             rc = check_key_signature( keyblock, node, NULL );
2466             if( !rc ) {
2467                 if( opt.verbose )
2468                     log_info(_(
2469                         "key %08lX.%lu: Valid subkey revocation\n"),
2470                          (ulong)keyid_from_pk(pk,NULL), lid );
2471                 krec.r.key.keyflags |= KEYF_REVOKED;
2472             }
2473             else {
2474                 log_info(_(
2475                   "key %08lX.%lu: Invalid subkey binding: %s\n"),
2476                   (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
2477             }
2478             revoke_seen = 1;
2479         }
2480     }
2481
2482     write_record( &krec );
2483 }
2484
2485
2486 /****************
2487  * This function checks the given user ID and inserts or updates
2488  * the uid record of the trustdb.  Revocation certificates
2489  * are handled here.
2490  *
2491  * keyblock points to the first node in the keyblock,
2492  * uidnode is the node with the user id to check
2493  * keyid is the keyid of
2494  * the primary key, drec is the directory record and recno_list
2495  * is a list used to keep track of visited records.
2496  * Existing uidflags are recalculated if recheck is true.
2497  */
2498 static void
2499 upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
2500                 TRUSTREC *drec, RECNO_LIST *recno_list, int recheck )
2501 {
2502     ulong lid = drec->recnum;
2503     PKT_user_id *uid = uidnode->pkt->pkt.user_id;
2504     TRUSTREC urec;
2505     PKT_signature *selfsig = NULL;
2506     byte uidhash[20];
2507     KBNODE node;
2508     ulong recno, newrecno;
2509     int rc;
2510
2511     if( DBG_TRUST )
2512         log_debug("upd_uid_record for %08lX/%02X%02X\n",
2513                                (ulong)keyid[1], uidhash[18], uidhash[19]);
2514
2515     /* see whether we already have an uid record */
2516     rmd160_hash_buffer( uidhash, uid->name, uid->len );
2517     for( recno=drec->r.dir.uidlist; recno; recno = urec.r.uid.next ) {
2518         read_record( recno, &urec, RECTYPE_UID );
2519         if( !memcmp( uidhash, urec.r.uid.namehash, 20 ) )
2520             break;
2521     }
2522     if( recno ) { /* we already have this record */
2523         ins_recno_list( recno_list, recno, RECTYPE_UID );
2524     }
2525     else { /* new user id */
2526         recheck = 1;
2527         memset( &urec, 0 , sizeof(urec) );
2528         urec.rectype = RECTYPE_UID;
2529         urec.r.uid.lid = drec->recnum;
2530         memcpy(urec.r.uid.namehash, uidhash, 20 );
2531         urec.recnum = newrecno = tdbio_new_recnum();
2532         write_record( &urec );
2533         ins_recno_list( recno_list, newrecno, RECTYPE_UID );
2534         /* and put this new record at the end of the uidlist */
2535         if( !(recno=drec->r.dir.uidlist) ) { /* this is the first uid */
2536             drec->r.dir.uidlist = newrecno;
2537             drec->dirty = 1;
2538         }
2539         else { /* we already have an uid, append it to the list */
2540             TRUSTREC save = urec;
2541             for( ; recno; recno = urec.r.key.next )
2542                 read_record( recno, &urec, RECTYPE_UID );
2543             urec.r.uid.next = newrecno;
2544             write_record( &urec );
2545             urec = save;
2546         }
2547     }
2548
2549     if( recheck || !(urec.r.uid.uidflags & UIDF_CHECKED) ) {
2550         /* check self signatures */
2551         urec.r.uid.uidflags = 0;
2552         for( node=uidnode->next; node; node = node->next ) {
2553             PKT_signature *sig;
2554
2555             if( node->pkt->pkttype == PKT_USER_ID )
2556                 break; /* ready */
2557             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2558                 break; /* ready */
2559             if( node->pkt->pkttype != PKT_SIGNATURE )
2560                 continue;
2561
2562             sig = node->pkt->pkt.signature;
2563
2564             if( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
2565                 continue; /* not a self signature */
2566
2567             if( (sig->sig_class&~3) == 0x10 ) { /* regular self signature */
2568                 rc = check_key_signature( keyblock, node, NULL );
2569                 if( !rc ) {
2570                     if( opt.verbose )
2571                         log_info( "uid %08lX.%lu/%02X%02X: %s\n",
2572                            (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2573                                   _("Good self-signature") );
2574                     urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID;
2575                     if( !selfsig )
2576                         selfsig = sig; /* use the first valid sig */
2577                     else if( sig->timestamp > selfsig->timestamp
2578                              && sig->sig_class >= selfsig->sig_class )
2579                         selfsig = sig; /* but this one is newer */
2580                 }
2581                 else {
2582                     log_info( "uid %08lX/%02X%02X: %s: %s\n",
2583                                (ulong)keyid[1], uidhash[18], uidhash[19],
2584                               _("Invalid self-signature"),
2585                                g10_errstr(rc) );
2586                     urec.r.uid.uidflags |= UIDF_CHECKED;
2587                 }
2588             }
2589             else if( sig->sig_class == 0x30 ) { /* cert revocation */
2590                 rc = check_key_signature( keyblock, node, NULL );
2591                 if( !rc && selfsig && selfsig->timestamp > sig->timestamp ) {
2592                     log_info( "uid %08lX.%lu/%02X%02X: %s\n",
2593                            (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2594                            _("Valid user ID revocation skipped "
2595                              "due to a newer self signature\n") );
2596                 }
2597                 else if( !rc ) {
2598                     if( opt.verbose )
2599                         log_info( "uid %08lX.%lu/%02X%02X: %s\n",
2600                            (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2601                                  _("Valid user ID revocation\n") );
2602                     urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID;
2603                     urec.r.uid.uidflags |= UIDF_REVOKED;
2604                 }
2605                 else {
2606                     log_info("uid %08lX/%02X%02X: %s: %s\n",
2607                                 (ulong)keyid[1], uidhash[18], uidhash[19],
2608                                _("Invalid user ID revocation"),
2609                                                         g10_errstr(rc) );
2610                 }
2611             }
2612         }
2613         write_record( &urec );
2614     } /* end check self-signatures */
2615
2616
2617     if( (urec.r.uid.uidflags & (UIDF_CHECKED|UIDF_VALID))
2618         != (UIDF_CHECKED|UIDF_VALID) )
2619         return; /* user ID is not valid, so no need to check more things */
2620
2621     /* check the preferences */
2622     if( selfsig )
2623         upd_pref_record( &urec, keyid, selfsig );
2624
2625     /* check non-self signatures */
2626     for( node=uidnode->next; node; node = node->next ) {
2627         PKT_signature *sig;
2628
2629         if( node->pkt->pkttype == PKT_USER_ID )
2630             break; /* ready */
2631         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2632             break; /* ready */
2633         if( node->pkt->pkttype != PKT_SIGNATURE )
2634             continue;
2635
2636         sig = node->pkt->pkt.signature;
2637
2638         if( keyid[0] == sig->keyid[0] || keyid[1] == sig->keyid[1] )
2639             continue; /* skip self signature */
2640
2641         if( (sig->sig_class&~3) == 0x10 ) { /* regular certification */
2642             upd_cert_record( keyblock, node, keyid, drec, recno_list,
2643                              recheck, &urec, uidhash, 0 );
2644         }
2645         else if( sig->sig_class == 0x30 ) { /* cert revocation */
2646             upd_cert_record( keyblock, node, keyid, drec, recno_list,
2647                              recheck, &urec, uidhash, 1 );
2648         }
2649     } /* end check certificates */
2650
2651     write_record( &urec );
2652 }
2653
2654
2655
2656 /****************
2657  *
2658  *
2659  */
2660 static void
2661 upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig )
2662 {
2663     static struct {
2664         sigsubpkttype_t subpkttype;
2665         int preftype;
2666     } ptable[] = {
2667         { SIGSUBPKT_PREF_SYM,   PREFTYPE_SYM    },
2668         { SIGSUBPKT_PREF_HASH,  PREFTYPE_HASH   },
2669         { SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR  },
2670         { 0, 0 }
2671     };
2672     TRUSTREC prec;
2673     ulong lid = urec->r.uid.lid ;
2674     const byte *uidhash = urec->r.uid.namehash;
2675     const byte *s;
2676     size_t n;
2677     int k, i;
2678     ulong recno;
2679     byte prefs_sig[200];
2680     int n_prefs_sig = 0;
2681     byte prefs_rec[200];
2682     int n_prefs_rec = 0;
2683
2684     if( DBG_TRUST )
2685         log_debug("upd_pref_record for %08lX.%lu/%02X%02X\n",
2686                           (ulong)keyid[1], lid, uidhash[18], uidhash[19] );
2687
2688
2689     /* check for changed preferences */
2690     for(k=0; ptable[k].subpkttype; k++ ) {
2691         s = parse_sig_subpkt2( sig, ptable[k].subpkttype, &n );
2692         if( s ) {
2693             for( ; n; n--, s++ ) {
2694                 if( n_prefs_sig >= DIM(prefs_sig)-1 ) {
2695                     log_info("uid %08lX.%lu/%02X%02X: %s\n",
2696                               (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2697                               _("Too many preferences") );
2698                     break;
2699                 }
2700                 prefs_sig[n_prefs_sig++] = ptable[k].preftype;
2701                 prefs_sig[n_prefs_sig++] = *s;
2702             }
2703         }
2704     }
2705     for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
2706         read_record( recno, &prec, RECTYPE_PREF );
2707         for(i = 0; i < ITEMS_PER_PREF_RECORD; i +=2 )  {
2708             if( n_prefs_rec >= DIM(prefs_rec)-1 ) {
2709                 log_info("uid %08lX.%lu/%02X%02X: %s\n",
2710                           (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2711                           _("Too many preference items") );
2712                 break;
2713             }
2714             if( prec.r.pref.data[i] ) {
2715                 prefs_rec[n_prefs_rec++] = prec.r.pref.data[i];
2716                 prefs_rec[n_prefs_rec++] = prec.r.pref.data[i+1];
2717             }
2718         }
2719     }
2720     if( n_prefs_sig == n_prefs_rec
2721         && !memcmp( prefs_sig, prefs_rec, n_prefs_sig ) )
2722         return;  /* not changed */
2723
2724     /* Preferences have changed:  Delete all pref records
2725      * This is much simpler than checking whether we have to
2726      * do update the record at all - the record cache may care about it
2727      */
2728     for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
2729         read_record( recno, &prec, RECTYPE_PREF );
2730         delete_record( recno );
2731     }
2732
2733     if( n_prefs_sig > ITEMS_PER_PREF_RECORD )
2734          log_info(_("WARNING: can't yet handle long pref records\n"));
2735
2736     memset( &prec, 0, sizeof prec );
2737     prec.recnum = tdbio_new_recnum();
2738     prec.rectype = RECTYPE_PREF;
2739     prec.r.pref.lid = lid;
2740     if( n_prefs_sig <= ITEMS_PER_PREF_RECORD )
2741         memcpy( prec.r.pref.data, prefs_sig, n_prefs_sig );
2742     else { /* need more than one pref record */
2743         TRUSTREC tmp;
2744         ulong nextrn;
2745         byte *pp = prefs_sig;
2746
2747         n = n_prefs_sig;
2748         memcpy( prec.r.pref.data, pp, ITEMS_PER_PREF_RECORD );
2749         n -= ITEMS_PER_PREF_RECORD;
2750         pp += ITEMS_PER_PREF_RECORD;
2751         nextrn = prec.r.pref.next = tdbio_new_recnum();
2752         do {
2753             memset( &tmp, 0, sizeof tmp );
2754             tmp.recnum = nextrn;
2755             tmp.rectype = RECTYPE_PREF;
2756             tmp.r.pref.lid = lid;
2757             if( n <= ITEMS_PER_PREF_RECORD ) {
2758                 memcpy( tmp.r.pref.data, pp, n );
2759                 n = 0;
2760             }
2761             else {
2762                 memcpy( tmp.r.pref.data, pp, ITEMS_PER_PREF_RECORD );
2763                 n -= ITEMS_PER_PREF_RECORD;
2764                 pp += ITEMS_PER_PREF_RECORD;
2765                 nextrn = tmp.r.pref.next = tdbio_new_recnum();
2766             }
2767             write_record( &tmp );
2768         } while( n );
2769     }
2770     write_record( &prec );
2771     urec->r.uid.prefrec = prec.recnum;
2772     urec->dirty = 1;
2773 }
2774
2775
2776
2777 static void
2778 upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
2779                  TRUSTREC *drec, RECNO_LIST *recno_list, int recheck,
2780                  TRUSTREC *urec, const byte *uidhash, int revoked )
2781 {
2782     /* We simply insert the signature into the sig records but
2783      * avoid duplicate ones.  We do not check them here because
2784      * there is a big chance, that we import required public keys
2785      * later.  The problem with this is that we must somewhere store
2786      * the information about this signature (we need a record id).
2787      * We do this by using the record type shadow dir, which will
2788      * be converted to a dir record as soon as the missing public key
2789      * gets inserted into the trustdb.
2790      */
2791     ulong lid = drec->recnum;
2792     PKT_signature *sig = signode->pkt->pkt.signature;
2793     TRUSTREC rec;
2794     ulong recno;
2795     TRUSTREC delrec;
2796     int delrecidx=0;
2797     int newflag = 0;
2798     ulong newlid = 0;
2799     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
2800     ulong pk_lid = 0;
2801     int found_sig = 0;
2802     int found_delrec = 0;
2803     int rc;
2804
2805
2806     if( DBG_TRUST )
2807         log_debug("upd_cert_record for %08lX.?/%02X%02X/%08lX\n",
2808                               (ulong)keyid[1], uidhash[18],
2809                                uidhash[19], (ulong)sig->keyid[1] );
2810
2811     delrec.recnum = 0;
2812
2813     /* get the LID of the pubkey of the signature under verification */
2814     rc = get_pubkey( pk, sig->keyid );
2815     if( !rc ) {
2816         if( pk->local_id )
2817             pk_lid = pk->local_id;
2818         else {
2819             rc = tdbio_search_dir_bypk( pk, &rec );
2820             if( !rc )
2821                 pk_lid = rec.recnum;
2822             else if( rc == -1 ) { /* see whether there is a sdir instead */
2823                 u32 akid[2];
2824
2825                 keyid_from_pk( pk, akid );
2826                 rc = tdbio_search_sdir( akid, pk->pubkey_algo, &rec );
2827                 if( !rc )
2828                     pk_lid = rec.recnum;
2829             }
2830         }
2831     }
2832     free_public_key( pk ); pk = NULL;
2833
2834     /* Loop over all signatures just in case one is not correctly
2835      * marked.  If we see the correct signature, set a flag.
2836      * delete duplicate signatures (should not happen but...) */
2837     for( recno = urec->r.uid.siglist; recno; recno = rec.r.sig.next ) {
2838         int i;
2839
2840         read_record( recno, &rec, RECTYPE_SIG );
2841         for(i=0; i < SIGS_PER_RECORD; i++ ) {
2842             TRUSTREC tmp;
2843             if( !rec.r.sig.sig[i].lid ) {
2844                 if( !found_delrec && !delrec.recnum ) {
2845                     delrec = rec;
2846                     delrecidx = i;
2847                     found_delrec=1;
2848                 }
2849                 continue; /* skip deleted sigs */
2850             }
2851             if( rec.r.sig.sig[i].lid == pk_lid ) {
2852               #if 0 /* must take uid into account */
2853                 if( found_sig ) {
2854                     log_info( "sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2855                               (ulong)keyid[1], lid, uidhash[18],
2856                                uidhash[19], (ulong)sig->keyid[1],
2857                              _("duplicated certificate - deleted") );
2858                     rec.r.sig.sig[i].lid = 0;
2859                     rec.dirty = 1;
2860                     continue;
2861                 }
2862               #endif
2863                 found_sig = 1;
2864             }
2865             if( !recheck && !revoked && (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
2866                 continue; /* we already checked this signature */
2867             if( !recheck && (rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
2868                 continue; /* we do not have the public key */
2869
2870             read_record( rec.r.sig.sig[i].lid, &tmp, 0 );
2871             if( tmp.rectype == RECTYPE_DIR ) {
2872                 /* In this case we should now be able to check the signature */
2873                 rc = check_key_signature( keyblock, signode, NULL );
2874                 if( !rc ) { /* valid signature */
2875                     if( opt.verbose )
2876                         log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2877                                 (ulong)keyid[1], lid, uidhash[18],
2878                                 uidhash[19], (ulong)sig->keyid[1],
2879                                 revoked? _("Valid certificate revocation")
2880                                        : _("Good certificate") );
2881                     rec.r.sig.sig[i].flag = SIGF_CHECKED | SIGF_VALID;
2882                     if( revoked )
2883                         rec.r.sig.sig[i].flag |= SIGF_REVOKED;
2884                 }
2885                 else if( rc == G10ERR_NO_PUBKEY ) {
2886                     /* fixme: For some reason this really happens? */
2887                     if( (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
2888                         log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2889                                   (ulong)keyid[1], lid, uidhash[18],
2890                                  uidhash[19], (ulong)sig->keyid[1],
2891                                  _("Hmmm, public key lost?") );
2892                     rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
2893                     if( revoked )
2894                         rec.r.sig.sig[i].flag |= SIGF_REVOKED;
2895                 }
2896                 else {
2897                     log_info("sig %08lX.%lu/%02X%02X/%08lX: %s: %s\n",
2898                                 (ulong)keyid[1], lid, uidhash[18],
2899                                 uidhash[19], (ulong)sig->keyid[1],
2900                                 revoked? _("Invalid certificate revocation")
2901                                        : _("Invalid certificate"),
2902                                                     g10_errstr(rc));
2903                     rec.r.sig.sig[i].flag = SIGF_CHECKED;
2904                     if( revoked )
2905                         rec.r.sig.sig[i].flag |= SIGF_REVOKED;
2906                 }
2907                 rec.dirty = 1;
2908             }
2909             else if( tmp.rectype == RECTYPE_SDIR ) {
2910                 /* must check that it is the right one */
2911                 if( tmp.r.sdir.keyid[0] == sig->keyid[0]
2912                     && tmp.r.sdir.keyid[1] == sig->keyid[1]
2913                     && (!tmp.r.sdir.pubkey_algo
2914                          || tmp.r.sdir.pubkey_algo == sig->pubkey_algo )) {
2915                     if( !(rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
2916                         log_info(_("uid %08lX.%lu/%02X%02X: "
2917                                 "has shadow dir %lu but is not yet marked.\n"),
2918                                 (ulong)keyid[1], lid,
2919                                 uidhash[18], uidhash[19], tmp.recnum );
2920                     rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
2921                     if( revoked )
2922                         rec.r.sig.sig[i].flag |= SIGF_REVOKED;
2923                     rec.dirty = 1;
2924                     /* fixme: should we verify that the record is
2925                      * in the hintlist? - This case here should anyway
2926                      * never occur */
2927                 }
2928             }
2929             else {
2930                 log_error(_("sig record %lu[%d] points to wrong record.\n"),
2931                             rec.r.sig.sig[i].lid, i );
2932                 die_invalid_db();
2933             }
2934         }
2935         if( found_delrec && delrec.recnum ) {
2936             delrec = rec;
2937             found_delrec = 0; /* we only want the first one */
2938         }
2939         if( rec.dirty ) {
2940             write_record( &rec );
2941             rec.dirty = 0;
2942         }
2943     }
2944
2945     if( found_sig )  /* fixme: uid stuff */
2946         return;
2947
2948     /* at this point, we have verified, that the signature is not in
2949      * our list of signatures.  Add a new record with that signature
2950      * and if the public key is there, check the signature. */
2951
2952     if( !pk_lid ) /* we have already seen that there is no pubkey */
2953         rc = G10ERR_NO_PUBKEY;
2954     else
2955         rc = check_key_signature( keyblock, signode, NULL );
2956
2957     if( !rc ) { /* valid signature */
2958         if( opt.verbose )
2959             log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2960                           (ulong)keyid[1], lid, uidhash[18],
2961                            uidhash[19], (ulong)sig->keyid[1],
2962                                 revoked? _("Valid certificate revocation")
2963                                        : _("Good certificate") );
2964         newlid = pk_lid;  /* this is the pk of the signature */
2965         newflag = SIGF_CHECKED | SIGF_VALID;
2966         if( revoked )
2967             newflag |= SIGF_REVOKED;
2968     }
2969     else if( rc == G10ERR_NO_PUBKEY ) {
2970         if( opt.verbose > 1 || DBG_TRUST )
2971             log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2972                      (ulong)keyid[1], lid, uidhash[18],
2973                       uidhash[19], (ulong)sig->keyid[1], g10_errstr(rc) );
2974         newlid = create_shadow_dir( sig, lid );
2975         newflag = SIGF_NOPUBKEY;
2976         if( revoked )
2977             newflag |= SIGF_REVOKED;
2978     }
2979     else {
2980         log_info( "sig %08lX.%lu/%02X%02X/%08lX: %s: %s\n",
2981                     (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2982                               (ulong)sig->keyid[1],
2983                 revoked? _("Invalid certificate revocation")
2984                        : _("Invalid certificate"),
2985                                             g10_errstr(rc));
2986         newlid = create_shadow_dir( sig, lid );
2987         newflag = SIGF_CHECKED;
2988         if( revoked )
2989             newflag |= SIGF_REVOKED;
2990     }
2991
2992     if( delrec.recnum ) { /* we can reuse a deleted/unused slot */
2993         delrec.r.sig.sig[delrecidx].lid = newlid;
2994         delrec.r.sig.sig[delrecidx].flag= newflag;
2995         write_record( &delrec );
2996     }
2997     else { /* must insert a new sig record */
2998         TRUSTREC tmp;
2999
3000         memset( &tmp, 0, sizeof tmp );
3001         tmp.recnum = tdbio_new_recnum();
3002         tmp.rectype = RECTYPE_SIG;
3003         tmp.r.sig.lid = lid;
3004         tmp.r.sig.next = urec->r.uid.siglist;
3005         tmp.r.sig.sig[0].lid = newlid;
3006         tmp.r.sig.sig[0].flag= newflag;
3007         write_record( &tmp );
3008         urec->r.uid.siglist = tmp.recnum;
3009         urec->dirty = 1;
3010     }
3011 }
3012
3013
3014 /****************
3015  * Update all the info from the public keyblock.
3016  * The key must already exist in the keydb.
3017  * This function is responsible for checking the signatures in cases
3018  * where the public key is already available.  If we do not have the public
3019  * key, the check is done by some special code in insert_trust_record().
3020  */
3021 int
3022 update_trust_record( KBNODE keyblock, int recheck, int *modified )
3023 {
3024     PKT_public_key *primary_pk;
3025     KBNODE node;
3026     TRUSTREC drec;
3027     TRUSTREC krec;
3028     TRUSTREC urec;
3029     TRUSTREC prec;
3030     TRUSTREC helprec;
3031     int rc = 0;
3032     u32 keyid[2]; /* keyid of primary key */
3033     ulong recno, lastrecno;
3034     RECNO_LIST recno_list = NULL; /* list of verified records */
3035     /* fixme: replace recno_list by a lookup on node->recno */
3036
3037     if( opt.dry_run )
3038         return 0;
3039
3040     INIT_TRUSTDB();
3041     if( modified )
3042         *modified = 0;
3043
3044     node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
3045     primary_pk = node->pkt->pkt.public_key;
3046     rc = get_dir_record( primary_pk, &drec );
3047     if( rc )
3048         return rc;
3049     if( !primary_pk->local_id )
3050         primary_pk->local_id = drec.recnum;
3051
3052     keyid_from_pk( primary_pk, keyid );
3053
3054     /* fixme: check that the keyblock has a valid structure */
3055
3056     rc = tdbio_begin_transaction();
3057     if( rc )
3058         return rc;
3059
3060     /* update the keys */
3061     for( node=keyblock; node; node = node->next ) {
3062         if( node->pkt->pkttype == PKT_PUBLIC_KEY
3063             || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3064             upd_key_record( keyblock, node, keyid,
3065                             &drec, &recno_list, recheck );
3066     }
3067     /* update the user IDs */
3068     for( node=keyblock; node; node = node->next ) {
3069         if( node->pkt->pkttype == PKT_USER_ID )
3070             upd_uid_record( keyblock, node, keyid,
3071                             &drec, &recno_list, recheck );
3072     }
3073
3074     /* delete keyrecords from the trustdb which are not anymore used */
3075     /* should we really do this, or is it better to keep them and */
3076     /* mark as unused? */
3077     /* And set the revocation flag into the dir record */
3078     drec.r.dir.dirflags &= ~DIRF_REVOKED;
3079     lastrecno = 0;
3080     for( recno=drec.r.dir.keylist; recno; recno = krec.r.key.next ) {
3081         read_record( recno, &krec, RECTYPE_KEY );
3082         if( recno == drec.r.dir.keylist ) { /* this is the primary key */
3083             if( (krec.r.key.keyflags & KEYF_REVOKED) ) {
3084                 drec.r.dir.dirflags |= DIRF_REVOKED;
3085                 drec.dirty = 1;
3086             }
3087         }
3088
3089         if( !qry_recno_list( recno_list, recno, RECTYPE_KEY ) ) {
3090             /* delete this one */
3091             if( !lastrecno ) {
3092                 drec.r.dir.keylist = krec.r.key.next;
3093                 drec.dirty = 1;
3094             }
3095             else {
3096                 read_record( lastrecno, &helprec, RECTYPE_KEY );
3097                 helprec.r.key.next = krec.r.key.next;
3098                 write_record( &helprec );
3099             }
3100             delete_record( recno );
3101         }
3102         else
3103             lastrecno = recno;
3104     }
3105     /* delete uid records and sig and their pref records from the
3106      * trustdb which are not anymore used */
3107     lastrecno = 0;
3108     for( recno=drec.r.dir.uidlist; recno; recno = urec.r.uid.next ) {
3109         read_record( recno, &urec, RECTYPE_UID );
3110         if( !qry_recno_list( recno_list, recno, RECTYPE_UID ) ) {
3111             ulong r2;
3112             /* delete this one */
3113             if( !lastrecno ) {
3114                 drec.r.dir.uidlist = urec.r.uid.next;
3115                 drec.dirty = 1;
3116             }
3117             else {
3118                 read_record( lastrecno, &helprec, RECTYPE_UID );
3119                 helprec.r.uid.next = urec.r.uid.next;
3120                 write_record( &helprec );
3121             }
3122             for(r2=urec.r.uid.prefrec ; r2; r2 = prec.r.pref.next ) {
3123                 read_record( r2, &prec, RECTYPE_PREF );
3124                 delete_record( r2 );
3125             }
3126             for(r2=urec.r.uid.siglist ; r2; r2 = helprec.r.sig.next ) {
3127                 read_record( r2, &helprec, RECTYPE_SIG );
3128                 delete_record( r2 );
3129             }
3130             delete_record( recno );
3131         }
3132         else
3133             lastrecno = recno;
3134     }
3135
3136
3137
3138     if( rc )
3139         rc = tdbio_cancel_transaction();
3140     else {
3141         if( modified && tdbio_is_dirty() )
3142             *modified = 1;
3143         drec.r.dir.dirflags |= DIRF_CHECKED;
3144         drec.r.dir.dirflags &= ~DIRF_VALVALID;
3145         write_record( &drec );
3146         rc = tdbio_end_transaction();
3147     }
3148     rel_recno_list( &recno_list );
3149     return rc;
3150 }
3151
3152
3153 /****************
3154  * Insert a trust record into the TrustDB
3155  * This function assumes that the record does not yet exist.
3156  */
3157 int
3158 insert_trust_record( PKT_public_key *pk )
3159 {
3160     TRUSTREC dirrec;
3161     TRUSTREC shadow;
3162     KBNODE keyblock = NULL;
3163     KBNODE node;
3164     byte fingerprint[MAX_FINGERPRINT_LEN];
3165     size_t fingerlen;
3166     int rc = 0;
3167     ulong hintlist = 0;
3168
3169
3170     if( opt.dry_run )
3171         return 0;
3172
3173     INIT_TRUSTDB();
3174
3175     fingerprint_from_pk( pk, fingerprint, &fingerlen );
3176
3177     /* fixme: assert that we do not have this record.
3178      * we can do this by searching for the primary keyid
3179      *
3180      * fixme: If there is no such key we should look whether one
3181      * of the subkeys has been used to sign another key and in this case
3182      * we got the key anyway.  Because a secondary key can't be used
3183      * without a primary key (it is needed to bind the secondary one
3184      * to the primary one which has the user ids etc.)
3185      */
3186
3187     /* get the keyblock which has the key */
3188     rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
3189     if( rc ) { /* that should never happen */
3190         log_error( _("insert_trust_record: keyblock not found: %s\n"),
3191                                                           g10_errstr(rc) );
3192         goto leave;
3193     }
3194
3195     if( pk->local_id ) {
3196         log_debug("insert_trust_reord with pk->local_id=%lu\n", pk->local_id );
3197         rc = update_trust_record( keyblock, 1, NULL );
3198         release_kbnode( keyblock );
3199         return rc;
3200     }
3201
3202     /* check that we used the primary key (we are little bit paranoid) */
3203     {   PKT_public_key *a_pk;
3204         u32 akid[2], bkid[2];
3205
3206         node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
3207         a_pk = node->pkt->pkt.public_key;
3208
3209         /* we can't use cmp_public_keys here because some parts (expiredate)
3210          * might not be set in pk <--- but why (fixme) */
3211         keyid_from_pk( a_pk, akid );
3212         keyid_from_pk( pk, bkid );
3213
3214         if( akid[0] != bkid[0] || akid[1] != bkid[1] ) {
3215             log_error(_("did not use primary key for insert_trust_record()\n"));
3216             rc = G10ERR_GENERAL;
3217             goto leave;
3218         }
3219     }
3220
3221     /* We have to look for a shadow dir record which must be reused
3222      * as the dir record. And: check all signatures which are listed
3223      * in the hintlist of the shadow dir record.
3224      */
3225     rc = tdbio_search_sdir( pk->keyid, pk->pubkey_algo, &shadow );
3226     if( rc && rc != -1 ) {
3227         log_error(_("tdbio_search_dir failed: %s\n"), g10_errstr(rc));
3228         die_invalid_db();
3229     }
3230     memset( &dirrec, 0, sizeof dirrec );
3231     dirrec.rectype = RECTYPE_DIR;
3232     if( !rc ) {
3233         /* hey, great: this key has already signed other keys
3234          * convert this to a real directory entry */
3235         hintlist = shadow.r.sdir.hintlist;
3236         dirrec.recnum = shadow.recnum;
3237     }
3238     else {
3239         dirrec.recnum = tdbio_new_recnum();
3240     }
3241     dirrec.r.dir.lid = dirrec.recnum;
3242     write_record( &dirrec );
3243
3244     /* store the LID */
3245     pk->local_id = dirrec.r.dir.lid;
3246     for( node=keyblock; node; node = node->next ) {
3247         if( node->pkt->pkttype == PKT_PUBLIC_KEY
3248             || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
3249             PKT_public_key *a_pk = node->pkt->pkt.public_key;
3250             a_pk->local_id = dirrec.r.dir.lid;
3251         }
3252         else if( node->pkt->pkttype == PKT_SIGNATURE ) {
3253             PKT_signature *a_sig = node->pkt->pkt.signature;
3254             a_sig->local_id = dirrec.r.dir.lid;
3255         }
3256     }
3257
3258     /* and put all the other stuff into the keydb */
3259     rc = update_trust_record( keyblock, 1, NULL );
3260     if( !rc )
3261         process_hintlist( hintlist, dirrec.r.dir.lid );
3262
3263   leave:
3264     if( rc && hintlist )
3265         ; /* fixme: the hintlist is not anymore anchored */
3266     release_kbnode( keyblock );
3267     do_sync();
3268     return rc;
3269 }
3270
3271
3272 int
3273 update_ownertrust( ulong lid, unsigned new_trust )
3274 {
3275     TRUSTREC rec;
3276
3277     INIT_TRUSTDB();
3278     read_record( lid, &rec, RECTYPE_DIR );
3279     rec.r.dir.ownertrust = new_trust;
3280     write_record( &rec );
3281     do_sync();
3282     return 0;
3283 }
3284
3285