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