See ChangeLog: Thu Dec 17 18:31:15 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, ulong selected_lid )
1754 {
1755     struct enum_cert_paths_ctx *ctx;
1756     TRUST_SEG_LIST tsl;
1757
1758     if( !*context )
1759         return;
1760     ctx = *context;
1761     if( !ctx->tsl )
1762         return;
1763
1764     if( !fp )
1765         fp = stderr;
1766
1767     print_path( ctx->tsl->pathlen, ctx->tsl->path, fp, selected_lid );
1768 }
1769
1770
1771 /****************
1772  * Return the assigned ownertrust value for the given LID
1773  */
1774 unsigned
1775 get_ownertrust( ulong lid )
1776 {
1777     TRUSTREC rec;
1778
1779     read_record( lid, &rec, RECTYPE_DIR );
1780     return rec.r.dir.ownertrust;
1781 }
1782
1783 int
1784 get_ownertrust_info( ulong lid )
1785 {
1786     unsigned otrust;
1787     int c;
1788
1789     otrust = get_ownertrust( lid );
1790     c = trust_letter( (otrust & TRUST_MASK) );
1791     if( !c )
1792         c = '?';
1793     return c;
1794 }
1795
1796 /*
1797  * Return an allocated buffer with the preference values for
1798  * the key with LID and the userid which is identified by the
1799  * HAMEHASH or the firstone if namehash is NULL.  ret_n receives
1800  * the length of the allcoated buffer.  Structure of the buffer is
1801  * a repeated sequences of 2 bytes; where the first byte describes the
1802  * type of the preference and the second one the value.  The constants
1803  * PREFTYPE_xxxx should be used to reference a type.
1804  */
1805 byte *
1806 get_pref_data( ulong lid, const byte *namehash, size_t *ret_n )
1807 {
1808     TRUSTREC rec;
1809     ulong recno;
1810
1811     read_record( lid, &rec, RECTYPE_DIR );
1812     for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
1813         read_record( recno, &rec, RECTYPE_UID );
1814         if( rec.r.uid.prefrec
1815             && ( !namehash || !memcmp(namehash, rec.r.uid.namehash, 20) ))  {
1816             byte *buf;
1817             /* found the correct one or the first one */
1818             read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
1819             if( rec.r.pref.next )
1820                 log_info(_("WARNING: can't yet handle long pref records\n"));
1821             buf = m_alloc( ITEMS_PER_PREF_RECORD );
1822             memcpy( buf, rec.r.pref.data, ITEMS_PER_PREF_RECORD );
1823             *ret_n = ITEMS_PER_PREF_RECORD;
1824             return buf;
1825         }
1826     }
1827     return NULL;
1828 }
1829
1830
1831
1832 /****************
1833  * Check whether the algorithm is in one of the pref records
1834  */
1835 int
1836 is_algo_in_prefs( ulong lid, int preftype, int algo )
1837 {
1838     TRUSTREC rec;
1839     ulong recno;
1840     int i;
1841     byte *pref;
1842
1843     read_record( lid, &rec, RECTYPE_DIR );
1844     for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
1845         read_record( recno, &rec, RECTYPE_UID );
1846         if( rec.r.uid.prefrec ) {
1847             read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
1848             if( rec.r.pref.next )
1849                 log_info(_("WARNING: can't yet handle long pref records\n"));
1850             pref = rec.r.pref.data;
1851             for(i=0; i+1 < ITEMS_PER_PREF_RECORD; i+=2 ) {
1852                 if( pref[i] == preftype && pref[i+1] == algo )
1853                     return 1;
1854             }
1855         }
1856     }
1857     return 0;
1858 }
1859
1860
1861 static int
1862 get_dir_record( PKT_public_key *pk, TRUSTREC *rec )
1863 {
1864     int rc=0;
1865
1866     if( pk->local_id ) {
1867         read_record( pk->local_id, rec, RECTYPE_DIR );
1868     }
1869     else { /* no local_id: scan the trustdb */
1870         if( (rc=tdbio_search_dir_bypk( pk, rec )) && rc != -1 )
1871             log_error(_("get_dir_record: search_record failed: %s\n"),
1872                                                             g10_errstr(rc));
1873     }
1874     return rc;
1875 }
1876
1877
1878
1879 /****************
1880  * This function simply looks for the key in the trustdb
1881  * and makes sure that pk->local_id is set to the correct value.
1882  * Return: 0 = found
1883  *         -1 = not found
1884  *        other = error
1885  */
1886 int
1887 query_trust_record( PKT_public_key *pk )
1888 {
1889     TRUSTREC rec;
1890     return get_dir_record( pk, &rec );
1891 }
1892
1893
1894 int
1895 clear_trust_checked_flag( PKT_public_key *pk )
1896 {
1897     TRUSTREC rec;
1898     int rc;
1899
1900     rc = get_dir_record( pk, &rec );
1901     if( rc )
1902         return rc;
1903
1904     /* check whether they are already reset */
1905     if(   !(rec.r.dir.dirflags & DIRF_CHECKED)
1906        && !(rec.r.dir.dirflags & DIRF_VALVALID) )
1907         return 0;
1908
1909     /* reset the flag */
1910     rec.r.dir.dirflags &= ~DIRF_CHECKED;
1911     rec.r.dir.dirflags &= ~DIRF_VALVALID;
1912     write_record( &rec );
1913     do_sync();
1914     return 0;
1915 }
1916
1917
1918
1919
1920 static void
1921 check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
1922                 TRUSTREC *sigrec, int sigidx, ulong hint_owner )
1923 {
1924     KBNODE node;
1925     int rc, state;
1926     byte uhash[20];
1927     int is_selfsig;
1928     PKT_signature *sigpkt = NULL;
1929     TRUSTREC tmp;
1930     u32 sigkid[2];
1931     int revoke = 0;
1932
1933     if( sigrec->r.sig.sig[sigidx].flag & SIGF_CHECKED )
1934         log_info(_("NOTE: sig rec %lu[%d] in hintlist "
1935                    "of %lu but marked as checked\n"),
1936                     sigrec->recnum, sigidx, hint_owner );
1937     if( !(sigrec->r.sig.sig[sigidx].flag & SIGF_NOPUBKEY) )
1938         log_info(_("NOTE: sig rec %lu[%d] in hintlist "
1939                    "of %lu but not marked\n"),
1940                     sigrec->recnum, sigidx, hint_owner );
1941
1942     read_record( sigrec->r.sig.sig[sigidx].lid, &tmp, 0 );
1943     if( tmp.rectype != RECTYPE_DIR ) {
1944         /* we need the dir record */
1945         log_error(_("sig rec %lu[%d] in hintlist "
1946                     "of %lu does not point to a dir record\n"),
1947                     sigrec->recnum, sigidx, hint_owner );
1948         return;
1949     }
1950     if( !tmp.r.dir.keylist ) {
1951         log_error(_("lid %lu: no primary key\n"), tmp.r.dir.lid );
1952         return;
1953     }
1954     read_record(tmp.r.dir.keylist, &tmp, RECTYPE_KEY );
1955     keyid_from_fingerprint( tmp.r.key.fingerprint,
1956                             tmp.r.key.fingerprint_len, sigkid );
1957
1958
1959     /* find the correct signature packet */
1960     state = 0;
1961     for( node=keyblock; node; node = node->next ) {
1962         if( node->pkt->pkttype == PKT_USER_ID ) {
1963             PKT_user_id *uidpkt = node->pkt->pkt.user_id;
1964
1965             if( state )
1966                 break;
1967             rmd160_hash_buffer( uhash, uidpkt->name, uidpkt->len );
1968             if( !memcmp( uhash, uidrec_hash, 20 ) )
1969                 state = 1;
1970         }
1971         else if( state && node->pkt->pkttype == PKT_SIGNATURE ) {
1972             sigpkt = node->pkt->pkt.signature;
1973             if( sigpkt->keyid[0] == sigkid[0]
1974                 && sigpkt->keyid[1] == sigkid[1]
1975                 && ( (sigpkt->sig_class&~3) == 0x10
1976                      || ( revoke = (sigpkt->sig_class == 0x30)) ) ) {
1977                 state = 2;
1978                 break; /* found */
1979             }
1980         }
1981     }
1982
1983     if( !node ) {
1984         log_info(_("lid %lu: user id not found in keyblock\n"), lid );
1985         return ;
1986     }
1987     if( state != 2 ) {
1988         log_info(_("lid %lu: user id without signature\n"), lid );
1989         return ;
1990     }
1991
1992     /* and check the sig */
1993     rc = check_key_signature( keyblock, node, &is_selfsig );
1994     if( is_selfsig ) {
1995         log_error(_("lid %lu: self-signature in hintlist\n"), lid );
1996         return;
1997     }
1998
1999     /* FiXME: handling fo SIGF_REVOKED is not correct! */
2000
2001     if( !rc ) { /* valid signature */
2002         if( opt.verbose )
2003             log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2004                     (ulong)keyid[1], lid, uhash[18], uhash[19],
2005                     (ulong)sigpkt->keyid[1],
2006                     revoke? _("Valid certificate revocation")
2007                           : _("Good certificate") );
2008         sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED | SIGF_VALID;
2009         if( revoke )
2010             sigrec->r.sig.sig[sigidx].flag |= SIGF_REVOKED;
2011     }
2012     else if( rc == G10ERR_NO_PUBKEY ) {
2013         log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2014               (ulong)keyid[1], lid, uhash[18], uhash[19],
2015                (ulong)sigpkt->keyid[1],
2016                  _("very strange: no public key\n") );
2017         sigrec->r.sig.sig[sigidx].flag = SIGF_NOPUBKEY;
2018     }
2019     else {
2020         log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2021                     (ulong)keyid[1], lid, uhash[18], uhash[19],
2022                     (ulong)sigpkt->keyid[1], g10_errstr(rc) );
2023         sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED;
2024     }
2025     sigrec->dirty = 1;
2026 }
2027
2028
2029 /****************
2030  * Process a hintlist.
2031  * Fixme: this list is not anymore anchored to another
2032  *        record, so it should be put elsewehere in case of an error
2033  */
2034 static void
2035 process_hintlist( ulong hintlist, ulong hint_owner )
2036 {
2037     ulong hlst_rn;
2038     int rc;
2039
2040     for( hlst_rn = hintlist; hlst_rn; ) {
2041         TRUSTREC hlstrec;
2042         int hlst_idx;
2043
2044         read_record( hlst_rn, &hlstrec, RECTYPE_HLST );
2045
2046         for( hlst_idx=0; hlst_idx < ITEMS_PER_HLST_RECORD; hlst_idx++ ) {
2047             TRUSTREC dirrec;
2048             TRUSTREC uidrec;
2049             TRUSTREC tmprec;
2050             KBNODE keyblock = NULL;
2051             u32 keyid[2];
2052             ulong lid;
2053             ulong r1, r2;
2054
2055             lid = hlstrec.r.hlst.rnum[hlst_idx];
2056             if( !lid )
2057                 continue;
2058
2059             read_record( lid, &dirrec, 0 );
2060             /* make sure it points to a dir record:
2061              * this should be true because it only makes sense to
2062              * call this function if the dir record is available */
2063             if( dirrec.rectype != RECTYPE_DIR )  {
2064                 log_error(_("hintlist %lu[%d] of %lu "
2065                             "does not point to a dir record\n"),
2066                             hlst_rn, hlst_idx, hint_owner );
2067                 continue;
2068             }
2069             if( !dirrec.r.dir.keylist ) {
2070                 log_error(_("lid %lu does not have a key\n"), lid );
2071                 continue;
2072             }
2073
2074             /* get the keyblock */
2075             read_record( dirrec.r.dir.keylist, &tmprec, RECTYPE_KEY );
2076             rc = get_keyblock_byfprint( &keyblock,
2077                                         tmprec.r.key.fingerprint,
2078                                         tmprec.r.key.fingerprint_len );
2079             if( rc ) {
2080                 log_error(_("lid %lu: can't get keyblock: %s\n"),
2081                                                     lid, g10_errstr(rc) );
2082                 continue;
2083             }
2084             keyid_from_fingerprint( tmprec.r.key.fingerprint,
2085                                     tmprec.r.key.fingerprint_len, keyid );
2086
2087             /* Walk over all user ids and their signatures and check all
2088              * the signature which are created by hint_owner */
2089             for( r1 = dirrec.r.dir.uidlist; r1; r1 = uidrec.r.uid.next ) {
2090                 TRUSTREC sigrec;
2091
2092                 read_record( r1, &uidrec, RECTYPE_UID );
2093                 for( r2 = uidrec.r.uid.siglist; r2; r2 = sigrec.r.sig.next ) {
2094                     int i;
2095
2096                     read_record( r2, &sigrec, RECTYPE_SIG );
2097                     sigrec.dirty = 0;
2098                     for(i=0; i < SIGS_PER_RECORD; i++ ) {
2099                         if( !sigrec.r.sig.sig[i].lid )
2100                             continue; /* skip deleted sigs */
2101                         if( sigrec.r.sig.sig[i].lid != hint_owner )
2102                             continue; /* not for us */
2103                         /* some diagnostic messages */
2104                         /* and do the signature check */
2105                         check_hint_sig( lid, keyblock, keyid,
2106                                         uidrec.r.uid.namehash,
2107                                         &sigrec, i, hint_owner );
2108                     }
2109                     if( sigrec.dirty )
2110                         write_record( &sigrec );
2111                 }
2112             }
2113             release_kbnode( keyblock );
2114         } /* loop over hlst entries */
2115
2116         /* delete this hlst record */
2117         hlst_rn = hlstrec.r.hlst.next;
2118         delete_record( hlstrec.recnum );
2119     } /* loop over hintlist */
2120 }
2121
2122
2123 /****************
2124  * Create or update shadow dir record and return the LID of the record
2125  */
2126 static ulong
2127 create_shadow_dir( PKT_signature *sig, ulong lid  )
2128 {
2129     TRUSTREC sdir, hlst, tmphlst;
2130     ulong recno, newlid;
2131     int tmpidx=0; /* avoids gcc warnign - this is controlled by tmphlst */
2132     int rc;
2133
2134     /* first see whether we already have such a record */
2135     rc = tdbio_search_sdir( sig->keyid, sig->pubkey_algo, &sdir );
2136     if( rc && rc != -1 ) {
2137         log_error(_("tdbio_search_dir failed: %s\n"), g10_errstr(rc));
2138         die_invalid_db();
2139     }
2140     if( rc == -1 ) { /* not found: create */
2141         memset( &sdir, 0, sizeof sdir );
2142         sdir.recnum = tdbio_new_recnum();
2143         sdir.rectype= RECTYPE_SDIR;
2144         sdir.r.sdir.lid = sdir.recnum;
2145         sdir.r.sdir.keyid[0] = sig->keyid[0];
2146         sdir.r.sdir.keyid[1] = sig->keyid[1];
2147         sdir.r.sdir.pubkey_algo = sig->pubkey_algo;
2148         sdir.r.sdir.hintlist = 0;
2149         write_record( &sdir );
2150     }
2151     newlid = sdir.recnum;
2152     /* Put the record number into the hintlist.
2153      * (It is easier to use the lid and not the record number of the
2154      *  key to save some space (assuming that a signator has
2155      *  signed more than one user id - and it is easier to implement.)
2156      */
2157     tmphlst.recnum = 0;
2158     for( recno=sdir.r.sdir.hintlist; recno; recno = hlst.r.hlst.next) {
2159         int i;
2160         read_record( recno, &hlst, RECTYPE_HLST );
2161         for( i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
2162             if( !hlst.r.hlst.rnum[i] ) {
2163                 if( !tmphlst.recnum ) {
2164                     tmphlst = hlst;
2165                     tmpidx = i;
2166                 }
2167             }
2168             else if( hlst.r.hlst.rnum[i] == lid )
2169                 return newlid; /* the signature is already in the hintlist */
2170         }
2171     }
2172     /* not yet in the hint list, write it */
2173     if( tmphlst.recnum ) { /* we have an empty slot */
2174         tmphlst.r.hlst.rnum[tmpidx] = lid;
2175         write_record( &tmphlst );
2176     }
2177     else { /* must append a new hlst record */
2178         memset( &hlst, 0, sizeof hlst );
2179         hlst.recnum = tdbio_new_recnum();
2180         hlst.rectype = RECTYPE_HLST;
2181         hlst.r.hlst.next = sdir.r.sdir.hintlist;
2182         hlst.r.hlst.rnum[0] = lid;
2183         write_record( &hlst );
2184         sdir.r.sdir.hintlist = hlst.recnum;
2185         write_record( &sdir );
2186     }
2187
2188     return newlid;
2189 }
2190
2191
2192 /****************
2193  * This function checks the given public key and inserts or updates
2194  * the keyrecord from the trustdb.  Revocation certificates
2195  * are handled here and the keybinding of subkeys is checked.
2196  * Hmmm: Should we check here, that the key has at least one valid
2197  * user ID or do we allow keys w/o user ID?
2198  *
2199  * keyblock points to the first node in the keyblock,
2200  * keynode is the node with the public key to check
2201  * (either primary or secondary), keyid is the keyid of
2202  * the primary key, drec is the directory record and recno_list
2203  * is a list used to keep track of visited records.
2204  * Existing keyflags are recalculated if recheck is true.
2205  */
2206 static void
2207 upd_key_record( KBNODE keyblock, KBNODE keynode, u32 *keyid,
2208                 TRUSTREC *drec, RECNO_LIST *recno_list, int recheck )
2209 {
2210     TRUSTREC krec;
2211     KBNODE  node;
2212     PKT_public_key *pk = keynode->pkt->pkt.public_key;
2213     ulong lid = drec->recnum;
2214     byte fpr[MAX_FINGERPRINT_LEN];
2215     size_t fprlen;
2216     ulong recno, newrecno;
2217     int keybind_seen = 0;
2218     int revoke_seen = 0;
2219     int rc;
2220
2221     fingerprint_from_pk( pk, fpr, &fprlen );
2222     /* do we already have this key? */
2223     for( recno=drec->r.dir.keylist; recno; recno = krec.r.key.next ) {
2224         read_record( recno, &krec, RECTYPE_KEY );
2225         if( krec.r.key.fingerprint_len == fprlen
2226             && !memcmp( krec.r.key.fingerprint, fpr, fprlen ) )
2227             break;
2228     }
2229     if( recno ) { /* yes */
2230         ins_recno_list( recno_list, recno, RECTYPE_KEY );
2231     }
2232     else { /* no: insert this new key */
2233         recheck = 1;
2234         memset( &krec, 0, sizeof(krec) );
2235         krec.rectype = RECTYPE_KEY;
2236         krec.r.key.lid = lid;
2237         krec.r.key.pubkey_algo = pk->pubkey_algo;
2238         krec.r.key.fingerprint_len = fprlen;
2239         memcpy(krec.r.key.fingerprint, fpr, fprlen );
2240         krec.recnum = newrecno = tdbio_new_recnum();
2241         write_record( &krec );
2242         ins_recno_list( recno_list, newrecno, RECTYPE_KEY );
2243         /* and put this new record at the end of the keylist */
2244         if( !(recno=drec->r.dir.keylist) ) {
2245             /* this is the first key */
2246             drec->r.dir.keylist = newrecno;
2247             drec->dirty = 1;
2248         }
2249         else { /* we already have a key, append the new one */
2250             TRUSTREC save = krec;
2251             for( ; recno; recno = krec.r.key.next )
2252                 read_record( recno, &krec, RECTYPE_KEY );
2253             krec.r.key.next = newrecno;
2254             write_record( &krec );
2255             krec = save;
2256         }
2257     }
2258
2259     if( !recheck && (krec.r.key.keyflags & KEYF_CHECKED) )
2260         return;
2261
2262     /* check keybindings and revocations */
2263     krec.r.key.keyflags = 0;
2264     if( keynode->pkt->pkttype == PKT_PUBLIC_KEY ) {
2265         /* we assume that a primary key is always valid
2266          * and check later whether we have a revocation */
2267         krec.r.key.keyflags |= KEYF_CHECKED | KEYF_VALID;
2268     }
2269
2270     for( node=keynode->next; node; node = node->next ) {
2271         PKT_signature *sig;
2272
2273         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2274             break; /* ready */
2275         else if( node->pkt->pkttype != PKT_SIGNATURE )
2276             continue;
2277
2278         sig = node->pkt->pkt.signature;
2279
2280         if( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
2281             continue; /* not a self signature */
2282         if( sig->sig_class == 0x18 && !keybind_seen ) { /* a keybinding */
2283             if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
2284                 continue; /* oops, not for a main key */
2285             /* we check until we find a valid keybinding */
2286             rc = check_key_signature( keyblock, node, NULL );
2287             if( !rc ) {
2288                 if( opt.verbose )
2289                     log_info(_(
2290                         "key %08lX.%lu: Good subkey binding\n"),
2291                          (ulong)keyid_from_pk(pk,NULL), lid );
2292                 krec.r.key.keyflags |= KEYF_CHECKED | KEYF_VALID;
2293             }
2294             else {
2295                 log_info(_(
2296                   "key %08lX.%lu: Invalid subkey binding: %s\n"),
2297                     (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
2298                 krec.r.key.keyflags |= KEYF_CHECKED;
2299                 krec.r.key.keyflags &= ~KEYF_VALID;
2300             }
2301             keybind_seen = 1;
2302         }
2303         else if( sig->sig_class == 0x20 && !revoke_seen ) {
2304             if( keynode->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2305                 continue; /* a subkey is not expected here */
2306             /* This is a key revocation certificate: check it */
2307             rc = check_key_signature( keyblock, node, NULL );
2308             if( !rc ) {
2309                 if( opt.verbose )
2310                     log_info(_(
2311                         "key %08lX.%lu: Valid key revocation\n"),
2312                          (ulong)keyid_from_pk(pk,NULL), lid );
2313                 krec.r.key.keyflags |= KEYF_REVOKED;
2314             }
2315             else {
2316                 log_info(_(
2317                   "key %08lX.%lu: Invalid key revocation: %s\n"),
2318                   (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
2319             }
2320             revoke_seen = 1;
2321         }
2322         else if( sig->sig_class == 0x28 && !revoke_seen ) {
2323             if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
2324                 continue; /* a mainkey is not expected here */
2325             /* This is a subkey revocation certificate: check it */
2326             /* fixme: we should also check the revocation
2327              * is newer than the key (OpenPGP) */
2328             rc = check_key_signature( keyblock, node, NULL );
2329             if( !rc ) {
2330                 if( opt.verbose )
2331                     log_info(_(
2332                         "key %08lX.%lu: Valid subkey revocation\n"),
2333                          (ulong)keyid_from_pk(pk,NULL), lid );
2334                 krec.r.key.keyflags |= KEYF_REVOKED;
2335             }
2336             else {
2337                 log_info(_(
2338                   "key %08lX.%lu: Invalid subkey binding: %s\n"),
2339                   (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
2340             }
2341             revoke_seen = 1;
2342         }
2343     }
2344
2345     write_record( &krec );
2346 }
2347
2348
2349 /****************
2350  * This function checks the given user ID and inserts or updates
2351  * the uid record of the trustdb.  Revocation certificates
2352  * are handled here.
2353  *
2354  * keyblock points to the first node in the keyblock,
2355  * uidnode is the node with the user id to check
2356  * keyid is the keyid of
2357  * the primary key, drec is the directory record and recno_list
2358  * is a list used to keep track of visited records.
2359  * Existing uidflags are recalculated if recheck is true.
2360  */
2361 static void
2362 upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
2363                 TRUSTREC *drec, RECNO_LIST *recno_list, int recheck )
2364 {
2365     ulong lid = drec->recnum;
2366     PKT_user_id *uid = uidnode->pkt->pkt.user_id;
2367     TRUSTREC urec;
2368     PKT_signature *selfsig = NULL;
2369     byte uidhash[20];
2370     KBNODE node;
2371     ulong recno, newrecno;
2372     int rc;
2373
2374     /* see whether we already have an uid record */
2375     rmd160_hash_buffer( uidhash, uid->name, uid->len );
2376     for( recno=drec->r.dir.uidlist; recno; recno = urec.r.uid.next ) {
2377         read_record( recno, &urec, RECTYPE_UID );
2378         if( !memcmp( uidhash, urec.r.uid.namehash, 20 ) )
2379             break;
2380     }
2381     if( recno ) { /* we already have this record */
2382         ins_recno_list( recno_list, recno, RECTYPE_UID );
2383     }
2384     else { /* new user id */
2385         recheck = 1;
2386         memset( &urec, 0 , sizeof(urec) );
2387         urec.rectype = RECTYPE_UID;
2388         urec.r.uid.lid = drec->recnum;
2389         memcpy(urec.r.uid.namehash, uidhash, 20 );
2390         urec.recnum = newrecno = tdbio_new_recnum();
2391         write_record( &urec );
2392         ins_recno_list( recno_list, newrecno, RECTYPE_UID );
2393         /* and put this new record at the end of the uidlist */
2394         if( !(recno=drec->r.dir.uidlist) ) { /* this is the first uid */
2395             drec->r.dir.uidlist = newrecno;
2396             drec->dirty = 1;
2397         }
2398         else { /* we already have an uid, append it to the list */
2399             TRUSTREC save = urec;
2400             for( ; recno; recno = urec.r.key.next )
2401                 read_record( recno, &urec, RECTYPE_UID );
2402             urec.r.uid.next = newrecno;
2403             write_record( &urec );
2404             urec = save;
2405         }
2406     }
2407
2408     if( recheck || !(urec.r.uid.uidflags & UIDF_CHECKED) ) {
2409         /* check self signatures */
2410         urec.r.uid.uidflags = 0;
2411         for( node=uidnode->next; node; node = node->next ) {
2412             PKT_signature *sig;
2413
2414             if( node->pkt->pkttype == PKT_USER_ID )
2415                 break; /* ready */
2416             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2417                 break; /* ready */
2418             if( node->pkt->pkttype != PKT_SIGNATURE )
2419                 continue;
2420
2421             sig = node->pkt->pkt.signature;
2422
2423             if( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
2424                 continue; /* not a self signature */
2425
2426             if( (sig->sig_class&~3) == 0x10 ) { /* regular self signature */
2427                 rc = check_key_signature( keyblock, node, NULL );
2428                 if( !rc ) {
2429                     if( opt.verbose )
2430                         log_info( "uid %08lX.%lu/%02X%02X: %s\n",
2431                            (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2432                                   _("Good self-signature") );
2433                     urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID;
2434                     if( !selfsig )
2435                         selfsig = sig; /* use the first valid sig */
2436                     else if( sig->timestamp > selfsig->timestamp
2437                              && sig->sig_class >= selfsig->sig_class )
2438                         selfsig = sig; /* but this one is newer */
2439                 }
2440                 else {
2441                     log_info( "uid %08lX/%02X%02X: %s: %s\n",
2442                                (ulong)keyid[1], uidhash[18], uidhash[19],
2443                               _("Invalid self-signature"),
2444                                g10_errstr(rc) );
2445                     urec.r.uid.uidflags |= UIDF_CHECKED;
2446                 }
2447             }
2448             else if( sig->sig_class == 0x30 ) { /* cert revocation */
2449                 rc = check_key_signature( keyblock, node, NULL );
2450                 if( !rc && selfsig && selfsig->timestamp > sig->timestamp ) {
2451                     log_info( "uid %08lX.%lu/%02X%02X: %s\n",
2452                            (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2453                            _("Valid user ID revocation skipped "
2454                              "due to a newer self signature\n") );
2455                 }
2456                 else if( !rc ) {
2457                     if( opt.verbose )
2458                         log_info( "uid %08lX.%lu/%02X%02X: %s\n",
2459                            (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2460                                  _("Valid user ID revocation\n") );
2461                     urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID;
2462                     urec.r.uid.uidflags |= UIDF_REVOKED;
2463                 }
2464                 else {
2465                     log_info("uid %08lX/%02X%02X: %s: %s\n",
2466                                 (ulong)keyid[1], uidhash[18], uidhash[19],
2467                                _("Invalid user ID revocation"),
2468                                                         g10_errstr(rc) );
2469                 }
2470             }
2471         }
2472         write_record( &urec );
2473     } /* end check self-signatures */
2474
2475
2476     if( (urec.r.uid.uidflags & (UIDF_CHECKED|UIDF_VALID))
2477         != (UIDF_CHECKED|UIDF_VALID) )
2478         return; /* user ID is not valid, so no need to check more things */
2479
2480     /* check the preferences */
2481     if( selfsig )
2482         upd_pref_record( &urec, keyid, selfsig );
2483
2484     /* check non-self signatures */
2485     for( node=uidnode->next; node; node = node->next ) {
2486         PKT_signature *sig;
2487
2488         if( node->pkt->pkttype == PKT_USER_ID )
2489             break; /* ready */
2490         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2491             break; /* ready */
2492         if( node->pkt->pkttype != PKT_SIGNATURE )
2493             continue;
2494
2495         sig = node->pkt->pkt.signature;
2496
2497         if( keyid[0] == sig->keyid[0] || keyid[1] == sig->keyid[1] )
2498             continue; /* skip self signature */
2499
2500         if( (sig->sig_class&~3) == 0x10 ) { /* regular certification */
2501             upd_cert_record( keyblock, node, keyid, drec, recno_list,
2502                              recheck, &urec, uidhash, 0 );
2503         }
2504         else if( sig->sig_class == 0x30 ) { /* cert revocation */
2505             upd_cert_record( keyblock, node, keyid, drec, recno_list,
2506                              recheck, &urec, uidhash, 1 );
2507         }
2508     } /* end check certificates */
2509
2510     write_record( &urec );
2511 }
2512
2513
2514
2515 /****************
2516  *
2517  *
2518  */
2519 static void
2520 upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig )
2521 {
2522     static struct {
2523         sigsubpkttype_t subpkttype;
2524         int preftype;
2525     } ptable[] = {
2526         { SIGSUBPKT_PREF_SYM,   PREFTYPE_SYM    },
2527         { SIGSUBPKT_PREF_HASH,  PREFTYPE_HASH   },
2528         { SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR  },
2529         { 0, 0 }
2530     };
2531     TRUSTREC prec;
2532     ulong lid = urec->r.uid.lid ;
2533     const byte *uidhash = urec->r.uid.namehash;
2534     const byte *s;
2535     size_t n;
2536     int k, i;
2537     ulong recno;
2538     byte prefs_sig[200];
2539     int n_prefs_sig = 0;
2540     byte prefs_rec[200];
2541     int n_prefs_rec = 0;
2542
2543     /* check for changed preferences */
2544     for(k=0; ptable[k].subpkttype; k++ ) {
2545         s = parse_sig_subpkt2( sig, ptable[k].subpkttype, &n );
2546         if( s ) {
2547             for( ; n; n--, s++ ) {
2548                 if( n_prefs_sig >= DIM(prefs_sig)-1 ) {
2549                     log_info("uid %08lX.%lu/%02X%02X: %s\n",
2550                               (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2551                               _("Too many preferences") );
2552                     break;
2553                 }
2554                 prefs_sig[n_prefs_sig++] = ptable[k].preftype;
2555                 prefs_sig[n_prefs_sig++] = *s;
2556             }
2557         }
2558     }
2559     for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
2560         read_record( recno, &prec, RECTYPE_PREF );
2561         for(i = 0; i < ITEMS_PER_PREF_RECORD; i +=2 )  {
2562             if( n_prefs_rec >= DIM(prefs_rec)-1 ) {
2563                 log_info("uid %08lX.%lu/%02X%02X: %s\n",
2564                           (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2565                           _("Too many preference items") );
2566                 break;
2567             }
2568             if( prec.r.pref.data[i] ) {
2569                 prefs_rec[n_prefs_rec++] = prec.r.pref.data[i];
2570                 prefs_rec[n_prefs_rec++] = prec.r.pref.data[i+1];
2571             }
2572         }
2573     }
2574     if( n_prefs_sig == n_prefs_rec
2575         && !memcmp( prefs_sig, prefs_rec, n_prefs_sig ) )
2576         return;  /* not changed */
2577
2578     /* Preferences have changed:  Delete all pref records
2579      * This is much simpler than checking whether we have to
2580      * do update the record at all - the record cache may care about it
2581      */
2582     for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
2583         read_record( recno, &prec, RECTYPE_PREF );
2584         delete_record( recno );
2585     }
2586
2587     if( n_prefs_sig > ITEMS_PER_PREF_RECORD )
2588          log_info(_("WARNING: can't yet handle long pref records\n"));
2589
2590     memset( &prec, 0, sizeof prec );
2591     prec.recnum = tdbio_new_recnum();
2592     prec.rectype = RECTYPE_PREF;
2593     prec.r.pref.lid = lid;
2594     if( n_prefs_sig <= ITEMS_PER_PREF_RECORD )
2595         memcpy( prec.r.pref.data, prefs_sig, n_prefs_sig );
2596     else { /* need more than one pref record */
2597         TRUSTREC tmp;
2598         ulong nextrn;
2599         int n = n_prefs_sig;
2600         byte *pp = prefs_sig;
2601
2602         memcpy( prec.r.pref.data, pp, ITEMS_PER_PREF_RECORD );
2603         n -= ITEMS_PER_PREF_RECORD;
2604         pp += ITEMS_PER_PREF_RECORD;
2605         nextrn = prec.r.pref.next = tdbio_new_recnum();
2606         do {
2607             memset( &tmp, 0, sizeof tmp );
2608             tmp.recnum = nextrn;
2609             tmp.rectype = RECTYPE_PREF;
2610             tmp.r.pref.lid = lid;
2611             if( n <= ITEMS_PER_PREF_RECORD ) {
2612                 memcpy( tmp.r.pref.data, pp, n );
2613                 n = 0;
2614             }
2615             else {
2616                 memcpy( tmp.r.pref.data, pp, ITEMS_PER_PREF_RECORD );
2617                 n -= ITEMS_PER_PREF_RECORD;
2618                 pp += ITEMS_PER_PREF_RECORD;
2619                 nextrn = tmp.r.pref.next = tdbio_new_recnum();
2620             }
2621             write_record( &tmp );
2622         } while( n );
2623     }
2624     write_record( &prec );
2625     urec->r.uid.prefrec = prec.recnum;
2626     urec->dirty = 1;
2627 }
2628
2629
2630
2631 static void
2632 upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
2633                  TRUSTREC *drec, RECNO_LIST *recno_list, int recheck,
2634                  TRUSTREC *urec, const byte *uidhash, int revoke )
2635 {
2636     /* We simply insert the signature into the sig records but
2637      * avoid duplicate ones.  We do not check them here because
2638      * there is a big chance, that we import required public keys
2639      * later.  The problem with this is that we must somewhere store
2640      * the information about this signature (we need a record id).
2641      * We do this by using the record type shadow dir, which will
2642      * be converted to a dir record as soon as a new public key is
2643      * inserted into the trustdb.
2644      */
2645     ulong lid = drec->recnum;
2646     PKT_signature *sig = signode->pkt->pkt.signature;
2647     TRUSTREC rec;
2648     ulong recno;
2649     TRUSTREC delrec;
2650     int delrecidx=0;
2651     int newflag = 0;
2652     ulong newlid = 0;
2653     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
2654     ulong pk_lid = 0;
2655     int found_sig = 0;
2656     int found_delrec = 0;
2657     int rc;
2658
2659     delrec.recnum = 0;
2660
2661     /* get the LID of the pubkey of the signature under verification */
2662     rc = get_pubkey( pk, sig->keyid );
2663     if( !rc ) {
2664         if( pk->local_id )
2665             pk_lid = pk->local_id;
2666         else {
2667             rc = tdbio_search_dir_bypk( pk, &rec );
2668             if( !rc )
2669                 pk_lid = rec.recnum;
2670             else if( rc == -1 ) { /* see whether there is a sdir instead */
2671                 u32 akid[2];
2672
2673                 keyid_from_pk( pk, akid );
2674                 rc = tdbio_search_sdir( akid, pk->pubkey_algo, &rec );
2675                 if( !rc )
2676                     pk_lid = rec.recnum;
2677             }
2678         }
2679     }
2680     free_public_key( pk ); pk = NULL;
2681
2682     /* Loop over all signatures just in case one is not correctly
2683      * marked.  If we see the correct signature, set a flag.
2684      * delete duplicate signatures (should not happen but...) */
2685     for( recno = urec->r.uid.siglist; recno; recno = rec.r.sig.next ) {
2686         int i;
2687
2688         read_record( recno, &rec, RECTYPE_SIG );
2689         for(i=0; i < SIGS_PER_RECORD; i++ ) {
2690             TRUSTREC tmp;
2691             if( !rec.r.sig.sig[i].lid ) {
2692                 if( !found_delrec && !delrec.recnum ) {
2693                     delrec = rec;
2694                     delrecidx = i;
2695                     found_delrec=1;
2696                 }
2697                 continue; /* skip deleted sigs */
2698             }
2699             if( rec.r.sig.sig[i].lid == pk_lid ) {
2700                 if( found_sig ) {
2701                     log_info( "sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2702                               (ulong)keyid[1], lid, uidhash[18],
2703                                uidhash[19], (ulong)sig->keyid[1],
2704                              _("Duplicated certificate - deleted") );
2705                     rec.r.sig.sig[i].lid = 0;
2706                     rec.dirty = 1;
2707                     continue;
2708                 }
2709                 found_sig = 1;
2710             }
2711             if( !recheck && !revoke && (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
2712                 continue; /* we already checked this signature */
2713             if( !recheck && (rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
2714                 continue; /* we do not have the public key */
2715
2716             read_record( rec.r.sig.sig[i].lid, &tmp, 0 );
2717             if( tmp.rectype == RECTYPE_DIR ) {
2718                 /* In this case we should now be able to check the signature */
2719                 rc = check_key_signature( keyblock, signode, NULL );
2720                 if( !rc ) { /* valid signature */
2721                     if( opt.verbose )
2722                         log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2723                                 (ulong)keyid[1], lid, uidhash[18],
2724                                 uidhash[19], (ulong)sig->keyid[1],
2725                                 revoke? _("Valid certificate revocation")
2726                                       : _("Good certificate") );
2727                     rec.r.sig.sig[i].flag = SIGF_CHECKED | SIGF_VALID;
2728                     if( revoke )
2729                         rec.r.sig.sig[i].flag |= SIGF_REVOKED;
2730                 }
2731                 else if( rc == G10ERR_NO_PUBKEY ) {
2732                   #if 0 /* fixme: For some reason this really happens? */
2733                     if( (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
2734                         log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2735                                   (ulong)keyid[1], lid, uidhash[18],
2736                                  uidhash[19], (ulong)sig->keyid[1],
2737                                  _("Hmmm, public key lost?") );
2738                   #endif
2739                     rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
2740                     if( revoke )
2741                         rec.r.sig.sig[i].flag |= SIGF_REVOKED;
2742                 }
2743                 else {
2744                     log_info("sig %08lX.%lu/%02X%02X/%08lX: %s: %s\n",
2745                                 (ulong)keyid[1], lid, uidhash[18],
2746                                 uidhash[19], (ulong)sig->keyid[1],
2747                                 revoke? _("Invalid certificate revocation")
2748                                       : _("Invalid certificate"),
2749                                                     g10_errstr(rc));
2750                     rec.r.sig.sig[i].flag = SIGF_CHECKED;
2751                     if( revoke )
2752                         rec.r.sig.sig[i].flag |= SIGF_REVOKED;
2753                 }
2754                 rec.dirty = 1;
2755             }
2756             else if( tmp.rectype == RECTYPE_SDIR ) {
2757                 /* must check that it is the right one */
2758                 if( tmp.r.sdir.keyid[0] == sig->keyid[0]
2759                     && tmp.r.sdir.keyid[1] == sig->keyid[1]
2760                     && (!tmp.r.sdir.pubkey_algo
2761                          || tmp.r.sdir.pubkey_algo == sig->pubkey_algo )) {
2762                     if( !(rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
2763                         log_info(_("uid %08lX.%lu/%02X%02X: "
2764                                 "has shadow dir %lu but is not yet marked.\n"),
2765                                 (ulong)keyid[1], lid,
2766                                 uidhash[18], uidhash[19], tmp.recnum );
2767                     rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
2768                     if( revoke )
2769                         rec.r.sig.sig[i].flag |= SIGF_REVOKED;
2770                     rec.dirty = 1;
2771                     /* fixme: should we verify that the record is
2772                      * in the hintlist? - This case here should anyway
2773                      * never occur */
2774                 }
2775             }
2776             else {
2777                 log_error(_("sig record %lu[%d] points to wrong record.\n"),
2778                             rec.r.sig.sig[i].lid, i );
2779                 die_invalid_db();
2780             }
2781         }
2782         if( found_delrec && delrec.recnum ) {
2783             delrec = rec;
2784             found_delrec = 0; /* we only want the first one */
2785         }
2786         if( rec.dirty ) {
2787             write_record( &rec );
2788             rec.dirty = 0;
2789         }
2790     }
2791
2792     if( found_sig )
2793         return;
2794
2795     /* at this point, we have verified, that the signature is not in
2796      * our list of signatures.  Add a new record with that signature
2797      * and if the public key is there, check the signature. */
2798
2799     if( !pk_lid ) /* we have already seen that there is no pubkey */
2800         rc = G10ERR_NO_PUBKEY;
2801     else
2802         rc = check_key_signature( keyblock, signode, NULL );
2803
2804     if( !rc ) { /* valid signature */
2805         if( opt.verbose )
2806             log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2807                           (ulong)keyid[1], lid, uidhash[18],
2808                            uidhash[19], (ulong)sig->keyid[1],
2809                                 revoke? _("Valid certificate revocation")
2810                                       : _("Good certificate") );
2811         newlid = pk_lid;  /* this is the pk of the signature */
2812         newflag = SIGF_CHECKED | SIGF_VALID;
2813         if( revoke )
2814             newflag |= SIGF_REVOKED;
2815     }
2816     else if( rc == G10ERR_NO_PUBKEY ) {
2817         if( opt.verbose > 1 )
2818             log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
2819                      (ulong)keyid[1], lid, uidhash[18],
2820                       uidhash[19], (ulong)sig->keyid[1], g10_errstr(rc) );
2821         newlid = create_shadow_dir( sig, lid );
2822         newflag = SIGF_NOPUBKEY;
2823         if( revoke )
2824             newflag |= SIGF_REVOKED;
2825     }
2826     else {
2827         log_info( "sig %08lX.%lu/%02X%02X/%08lX: %s: %s\n",
2828                     (ulong)keyid[1], lid, uidhash[18], uidhash[19],
2829                               (ulong)sig->keyid[1],
2830                 revoke? _("Invalid certificate revocation")
2831                       : _("Invalid certificate"),
2832                                             g10_errstr(rc));
2833         newlid = create_shadow_dir( sig, lid );
2834         newflag = SIGF_CHECKED;
2835         if( revoke )
2836             newflag |= SIGF_REVOKED;
2837     }
2838
2839     if( delrec.recnum ) { /* we can reuse a deleted/unused slot */
2840         delrec.r.sig.sig[delrecidx].lid = newlid;
2841         delrec.r.sig.sig[delrecidx].flag= newflag;
2842         write_record( &delrec );
2843     }
2844     else { /* must insert a new sig record */
2845         TRUSTREC tmp;
2846
2847         memset( &tmp, 0, sizeof tmp );
2848         tmp.recnum = tdbio_new_recnum();
2849         tmp.rectype = RECTYPE_SIG;
2850         tmp.r.sig.lid = lid;
2851         tmp.r.sig.next = urec->r.uid.siglist;
2852         tmp.r.sig.sig[0].lid = newlid;
2853         tmp.r.sig.sig[0].flag= newflag;
2854         write_record( &tmp );
2855         urec->r.uid.siglist = tmp.recnum;
2856         urec->dirty = 1;
2857     }
2858 }
2859
2860
2861 /****************
2862  * Update all the info from the public keyblock.
2863  * The key must already exist in the keydb.
2864  * This function is responsible for checking the signatures in cases
2865  * where the public key is already available.  If we do not have the public
2866  * key, the check is done by some special code in insert_trust_record().
2867  */
2868 int
2869 update_trust_record( KBNODE keyblock, int recheck, int *modified )
2870 {
2871     PKT_public_key *primary_pk;
2872     KBNODE node;
2873     TRUSTREC drec;
2874     TRUSTREC krec;
2875     TRUSTREC urec;
2876     TRUSTREC prec;
2877     TRUSTREC helprec;
2878     int rc = 0;
2879     u32 keyid[2]; /* keyid of primary key */
2880     ulong recno, lastrecno;
2881     RECNO_LIST recno_list = NULL; /* list of verified records */
2882     /* fixme: replace recno_list by a lookup on node->recno */
2883
2884     if( modified )
2885         *modified = 0;
2886
2887     node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
2888     primary_pk = node->pkt->pkt.public_key;
2889     rc = get_dir_record( primary_pk, &drec );
2890     if( rc )
2891         return rc;
2892     if( !primary_pk->local_id )
2893         primary_pk->local_id = drec.recnum;
2894
2895     keyid_from_pk( primary_pk, keyid );
2896
2897     /* fixme: check that the keyblock has a valid structure */
2898
2899     rc = tdbio_begin_transaction();
2900     if( rc )
2901         return rc;
2902
2903     /* update the keys */
2904     for( node=keyblock; node; node = node->next ) {
2905         if( node->pkt->pkttype == PKT_PUBLIC_KEY
2906             || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2907             upd_key_record( keyblock, node, keyid,
2908                             &drec, &recno_list, recheck );
2909     }
2910     /* update the user IDs */
2911     for( node=keyblock; node; node = node->next ) {
2912         if( node->pkt->pkttype == PKT_USER_ID )
2913             upd_uid_record( keyblock, node, keyid,
2914                             &drec, &recno_list, recheck );
2915     }
2916
2917     /* delete keyrecords from the trustdb which are not anymore used */
2918     /* should we really do this, or is it better to keep them and */
2919     /* mark as unused? */
2920     lastrecno = 0;
2921     for( recno=drec.r.dir.keylist; recno; recno = krec.r.key.next ) {
2922         read_record( recno, &krec, RECTYPE_KEY );
2923         if( !qry_recno_list( recno_list, recno, RECTYPE_KEY ) ) {
2924             /* delete this one */
2925             if( !lastrecno ) {
2926                 drec.r.dir.keylist = krec.r.key.next;
2927                 drec.dirty = 1;
2928             }
2929             else {
2930                 read_record( lastrecno, &helprec, RECTYPE_KEY );
2931                 helprec.r.key.next = krec.r.key.next;
2932                 write_record( &helprec );
2933             }
2934             delete_record( recno );
2935         }
2936         else
2937             lastrecno = recno;
2938     }
2939     /* delete uid records and sig and their pref records from the
2940      * trustdb which are not anymore used */
2941     lastrecno = 0;
2942     for( recno=drec.r.dir.uidlist; recno; recno = urec.r.uid.next ) {
2943         read_record( recno, &urec, RECTYPE_UID );
2944         if( !qry_recno_list( recno_list, recno, RECTYPE_UID ) ) {
2945             ulong r2;
2946             /* delete this one */
2947             if( !lastrecno ) {
2948                 drec.r.dir.uidlist = urec.r.uid.next;
2949                 drec.dirty = 1;
2950             }
2951             else {
2952                 read_record( lastrecno, &helprec, RECTYPE_UID );
2953                 helprec.r.uid.next = urec.r.uid.next;
2954                 write_record( &helprec );
2955             }
2956             for(r2=urec.r.uid.prefrec ; r2; r2 = prec.r.pref.next ) {
2957                 read_record( r2, &prec, RECTYPE_PREF );
2958                 delete_record( r2 );
2959             }
2960             for(r2=urec.r.uid.siglist ; r2; r2 = helprec.r.sig.next ) {
2961                 read_record( r2, &helprec, RECTYPE_SIG );
2962                 delete_record( r2 );
2963             }
2964             delete_record( recno );
2965         }
2966         else
2967             lastrecno = recno;
2968     }
2969
2970
2971
2972     if( rc )
2973         rc = tdbio_cancel_transaction();
2974     else {
2975         drec.r.dir.dirflags |= DIRF_CHECKED;
2976         drec.r.dir.dirflags &= ~DIRF_VALVALID;
2977         write_record( &drec );
2978         if( modified && tdbio_is_dirty() )
2979             *modified = 1;
2980         rc = tdbio_end_transaction();
2981     }
2982     rel_recno_list( &recno_list );
2983     return rc;
2984 }
2985
2986
2987 /****************
2988  * Insert a trust record into the TrustDB
2989  * This function assumes that the record does not yet exist.
2990  */
2991 int
2992 insert_trust_record( PKT_public_key *pk )
2993 {
2994     TRUSTREC dirrec;
2995     TRUSTREC shadow;
2996     KBNODE keyblock = NULL;
2997     KBNODE node;
2998     byte fingerprint[MAX_FINGERPRINT_LEN];
2999     size_t fingerlen;
3000     int rc = 0;
3001     ulong hintlist = 0;
3002
3003     if( pk->local_id )
3004         log_bug("pk->local_id=%lu\n", pk->local_id );
3005
3006     fingerprint_from_pk( pk, fingerprint, &fingerlen );
3007
3008     /* fixme: assert that we do not have this record.
3009      * we can do this by searching for the primary keyid
3010      *
3011      * fixme: If there is no such key we should look whether one
3012      * of the subkeys has been used to sign another key and in this case
3013      * we got the key anyway.  Because a secondary key can't be used
3014      * without a primary key (it is needed to bind the secondary one
3015      * to the primary one which has the user ids etc.)
3016      */
3017
3018     /* get the keyblock which has the key */
3019     rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
3020     if( rc ) { /* that should never happen */
3021         log_error( _("insert_trust_record: keyblock not found: %s\n"),
3022                                                           g10_errstr(rc) );
3023         goto leave;
3024     }
3025
3026     /* check that we used the primary key (we are little bit paranoid) */
3027     {   PKT_public_key *a_pk;
3028         u32 akid[2], bkid[2];
3029
3030         node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
3031         a_pk = node->pkt->pkt.public_key;
3032
3033         /* we can't use cmp_public_keys here because some parts (expiredate)
3034          * might not be set in pk <--- but why (fixme) */
3035         keyid_from_pk( a_pk, akid );
3036         keyid_from_pk( pk, bkid );
3037
3038         if( akid[0] != bkid[0] || akid[1] != bkid[1] ) {
3039             log_error(_("did not use primary key for insert_trust_record()\n"));
3040             rc = G10ERR_GENERAL;
3041             goto leave;
3042         }
3043     }
3044
3045     /* We have to look for a shadow dir record which must be reused
3046      * as the dir record. And: check all signatures which are listed
3047      * in the hintlist of the shadow dir record.
3048      */
3049     rc = tdbio_search_sdir( pk->keyid, pk->pubkey_algo, &shadow );
3050     if( rc && rc != -1 ) {
3051         log_error(_("tdbio_search_dir failed: %s\n"), g10_errstr(rc));
3052         die_invalid_db();
3053     }
3054     memset( &dirrec, 0, sizeof dirrec );
3055     dirrec.rectype = RECTYPE_DIR;
3056     if( !rc ) {
3057         /* hey, great: this key has already signed other keys
3058          * convert this to a real directory entry */
3059         hintlist = shadow.r.sdir.hintlist;
3060         dirrec.recnum = shadow.recnum;
3061     }
3062     else {
3063         dirrec.recnum = tdbio_new_recnum();
3064     }
3065     dirrec.r.dir.lid = dirrec.recnum;
3066     write_record( &dirrec );
3067
3068     /* store the LID */
3069     pk->local_id = dirrec.r.dir.lid;
3070     for( node=keyblock; node; node = node->next ) {
3071         if( node->pkt->pkttype == PKT_PUBLIC_KEY
3072             || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
3073             PKT_public_key *pk = node->pkt->pkt.public_key;
3074             pk->local_id = dirrec.r.dir.lid;
3075         }
3076         else if( node->pkt->pkttype == PKT_SIGNATURE ) {
3077             PKT_signature *sig = node->pkt->pkt.signature;
3078             sig->local_id = dirrec.r.dir.lid;
3079         }
3080     }
3081
3082     /* and put all the other stuff into the keydb */
3083     rc = update_trust_record( keyblock, 1, NULL );
3084     if( !rc )
3085         process_hintlist( hintlist, dirrec.r.dir.lid );
3086
3087   leave:
3088     if( rc && hintlist )
3089         ; /* fixme: the hintlist is not anymore anchored */
3090     release_kbnode( keyblock );
3091     do_sync();
3092     return rc;
3093 }
3094
3095
3096 int
3097 update_ownertrust( ulong lid, unsigned new_trust )
3098 {
3099     TRUSTREC rec;
3100
3101     read_record( lid, &rec, RECTYPE_DIR );
3102     rec.r.dir.ownertrust = new_trust;
3103     write_record( &rec );
3104     do_sync();
3105     return 0;
3106 }
3107
3108