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