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