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