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