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