593e12cd2b69f91534bae486e9e2f8ae48221324
[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 <assert.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31
32 #include "errors.h"
33 #include "iobuf.h"
34 #include "keydb.h"
35 #include "memory.h"
36 #include "util.h"
37 #include "trustdb.h"
38 #include "options.h"
39 #include "packet.h"
40 #include "main.h"
41 #include "i18n.h"
42 #include "tdbio.h"
43
44
45 #if MAX_FINGERPRINT_LEN > 20
46   #error Must change structure of trustdb
47 #endif
48
49 typedef struct local_id_info *LOCAL_ID_INFO;
50 struct local_id_info {
51     LOCAL_ID_INFO next;
52     ulong lid;
53     unsigned flag;
54 };
55
56
57 typedef struct trust_info TRUST_INFO;
58 struct trust_info {
59     ulong    lid;
60     unsigned trust;
61 };
62
63
64 typedef struct trust_seg_list *TRUST_SEG_LIST;
65 struct trust_seg_list {
66     TRUST_SEG_LIST next;
67     int   nseg;     /* number of segmens */
68     int   dup;
69     TRUST_INFO seg[1];   /* segment list */
70 };
71
72
73 typedef struct {
74     TRUST_SEG_LIST tsl;
75     int index;
76 } ENUM_TRUST_WEB_CONTEXT;
77
78
79 static int walk_sigrecs( SIGREC_CONTEXT *c, int create );
80
81 static LOCAL_ID_INFO *new_lid_table(void);
82 static void release_lid_table( LOCAL_ID_INFO *tbl );
83 static int ins_lid_table_item( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
84 static int qry_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned *flag );
85 static void upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
86
87 static void print_user_id( const char *text, u32 *keyid );
88 static int do_list_path( TRUST_INFO *stack, int depth, int max_depth,
89                          LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist );
90
91 static int list_sigs( ulong pubkey_id );
92 static int build_sigrecs( ulong local_id );
93 static int propagate_trust( TRUST_SEG_LIST tslist );
94 static int do_check( TRUSTREC *drec, unsigned *trustlevel );
95
96
97 /* a table used to keep track of ultimately trusted keys
98  * which are the ones from our secrings */
99 static LOCAL_ID_INFO *ultikey_table;
100
101 static ulong last_trust_web_key;
102 static TRUST_SEG_LIST last_trust_web_tslist;
103
104
105 /**********************************************
106  ************* list helpers *******************
107  **********************************************/
108
109 static LOCAL_ID_INFO *
110 new_lid_table(void)
111 {
112     return m_alloc_clear( 16 * sizeof(LOCAL_ID_INFO));
113 }
114
115 static void
116 release_lid_table( LOCAL_ID_INFO *tbl )
117 {
118     LOCAL_ID_INFO a, a2;
119     int i;
120
121     for(i=0; i < 16; i++ ) {
122         for(a=tbl[i]; a; a = a2 ) {
123             a2 = a->next;
124             m_free(a);
125         }
126     }
127     m_free(tbl);
128 }
129
130 /****************
131  * Add a new item to the table or return 1 if we already have this item
132  * fixme: maybe it's a good idea to take items from an unused item list.
133  */
134 static int
135 ins_lid_table_item( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag )
136 {
137     LOCAL_ID_INFO a;
138
139     for( a = tbl[lid & 0x0f]; a; a = a->next )
140         if( a->lid == lid )
141             return 1;
142     a = m_alloc( sizeof *a );
143     a->lid = lid;
144     a->flag = flag;
145     a->next = tbl[lid & 0x0f];
146     tbl[lid & 0x0f] = a;
147     return 0;
148 }
149
150 static int
151 qry_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned *flag )
152 {
153     LOCAL_ID_INFO a;
154
155     for( a = tbl[lid & 0x0f]; a; a = a->next )
156         if( a->lid == lid ) {
157             if( flag )
158                 *flag = a->flag;
159             return 0;
160         }
161     return -1;
162 }
163
164 static void
165 upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag )
166 {
167     LOCAL_ID_INFO a;
168
169     for( a = tbl[lid & 0x0f]; a; a = a->next )
170         if( a->lid == lid ) {
171             a->flag = flag;
172             return;
173         }
174     BUG();
175 }
176
177 /****************
178  * If we do not have a local_id in a signature packet, find the owner of
179  * the signature packet in our trustdb or insert them into the trustdb
180  */
181 static int
182 set_signature_packets_local_id( PKT_signature *sig )
183 {
184     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
185     TRUSTREC rec;
186     int rc;
187
188     rc = get_pubkey( pk, sig->keyid );
189     if( rc)
190         goto leave;
191     if( !pk->local_id ) {
192         rc = tdbio_search_dir_record( pk, &rec );
193         if( rc == -1 )
194             rc = insert_trust_record( pk );
195         if( rc )
196             goto leave;
197     }
198     sig->local_id = pk->local_id;
199
200   leave:
201     free_public_key( pk );
202     return rc;
203 }
204
205
206
207 static int
208 keyid_from_local_id( ulong lid, u32 *keyid )
209 {
210     TRUSTREC rec;
211     int rc;
212
213     rc = tdbio_read_record( lid, &rec, RECTYPE_DIR );
214     if( rc ) {
215         log_error(_("error reading record with local_id %lu: %s\n"),
216                                                     lid, g10_errstr(rc));
217         return G10ERR_TRUSTDB;
218     }
219     if( rec.rectype != RECTYPE_DIR ) {
220         log_error(_("record with local_id %lu is not a dir record\n"), lid);
221         return G10ERR_TRUSTDB;
222     }
223     keyid[0] = rec.r.dir.keyid[0];
224     keyid[1] = rec.r.dir.keyid[1];
225     return 0;
226 }
227
228 /****************
229  * Walk through the signatures of a public key.
230  * The caller must provide a context structure, with all fields set
231  * to zero, but the local_id field set to the requested key;
232  * This function does not change this field.  On return the context
233  * is filled with the local-id of the signature and the signature flag.
234  * No fields should be changed (clearing all fields and setting
235  * pubkeyid is okay to continue with an other pubkey)
236  * Returns: 0 - okay, -1 for eof (no more sigs) or any other errorcode
237  */
238 static int
239 walk_sigrecs( SIGREC_CONTEXT *c, int create )
240 {
241     int rc=0;
242     TRUSTREC *r;
243     ulong rnum;
244
245     if( c->ctl.eof )
246         return -1;
247     r = &c->ctl.rec;
248     if( !c->ctl.init_done ) {
249         c->ctl.init_done = 1;
250         if( !c->sigrec ) {
251             rc = tdbio_read_record( c->local_id, r, RECTYPE_DIR );
252             if( rc ) {
253                 log_error(_("%lu: error reading dir record: %s\n"),
254                                         c->local_id, g10_errstr(rc));
255                 return rc;
256             }
257             c->sigrec = r->r.dir.sigrec;
258             if( !c->sigrec && create && !r->r.dir.no_sigs ) {
259                 rc = build_sigrecs( c->local_id );
260                 if( rc ) {
261                     if( rc == G10ERR_BAD_CERT )
262                         rc = -1;  /* maybe no selcficnature */
263                     if( rc != -1 )
264                         log_info(_("%lu: error building sigs on the fly: %s\n"),
265                                c->local_id, g10_errstr(rc) );
266                     c->ctl.eof = 1;
267                     return rc;
268                 }
269                 rc = tdbio_read_record( c->local_id, r, RECTYPE_DIR );
270                 if( rc ) {
271                     log_error(_("%lu: error re-reading dir record: %s\n"),
272                                             c->local_id, g10_errstr(rc));
273                     return rc;
274                 }
275                 c->sigrec = r->r.dir.sigrec;
276             }
277             if( !c->sigrec ) {
278                 c->ctl.eof = 1;
279                 return -1;
280             }
281         }
282         /* force a read */
283         c->ctl.index = SIGS_PER_RECORD;
284         r->r.sig.chain = c->sigrec;
285     }
286
287     /* enter loop to skip deleted sigs */
288     do {
289         if( c->ctl.index >= SIGS_PER_RECORD ) {
290             /* read the record */
291             rnum = r->r.sig.chain;
292             if( !rnum ) {
293                 c->ctl.eof = 1;
294                 return -1;  /* return eof */
295             }
296             rc = tdbio_read_record( rnum, r, RECTYPE_SIG );
297             if( rc ) {
298                 log_error(_("error reading sigrec: %s\n"), g10_errstr(rc));
299                 c->ctl.eof = 1;
300                 return rc;
301             }
302             if( r->r.sig.owner != c->local_id ) {
303                 log_error(_("chained sigrec %lu has a wrong owner\n"), rnum );
304                 c->ctl.eof = 1;
305                 return G10ERR_TRUSTDB;
306             }
307             c->ctl.index = 0;
308         }
309     } while( !r->r.sig.sig[c->ctl.index++].local_id );
310     c->sig_id = r->r.sig.sig[c->ctl.index-1].local_id;
311     c->sig_flag = r->r.sig.sig[c->ctl.index-1].flag;
312     return 0;
313 }
314
315
316
317
318 /***********************************************
319  *************  Trust  stuff  ******************
320  ***********************************************/
321
322
323 /****************
324  * Verify that all our public keys are in the trustDB.
325  */
326 static int
327 verify_own_keys()
328 {
329     int rc;
330     void *enum_context = NULL;
331     PKT_secret_key *sk = m_alloc_clear( sizeof *sk );
332     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
333     u32 keyid[2];
334
335     while( !(rc=enum_secret_keys( &enum_context, sk) ) ) {
336         /* To be sure that it is a secret key of our own,
337          * we should check it, but this needs a passphrase
338          * for every key and this is boring for the user.
339          * Anyway, access to the seret keyring should be
340          * granted to the user only as it is poosible to
341          * crack it with dictionary attacks.
342          */
343         keyid_from_sk( sk, keyid );
344
345         if( DBG_TRUST )
346             log_debug("key %08lX: checking secret key\n", (ulong)keyid[1] );
347
348         /* see whether we can access the public key of this secret key */
349         memset( pk, 0, sizeof *pk );
350         rc = get_pubkey( pk, keyid );
351         if( rc ) {
352             log_error(_("key %08lX: secret key without public key\n"),
353                                                             (ulong)keyid[1] );
354             goto leave;
355         }
356         if( cmp_public_secret_key( pk, sk ) ) {
357             log_error(_("key %08lX: secret and public key don't match\n"),
358                                                             (ulong)keyid[1] );
359             rc = G10ERR_GENERAL;
360             goto leave;
361         }
362
363         /* make sure that the pubkey is in the trustdb */
364         rc = query_trust_record( pk );
365         if( rc == -1 ) { /* put it into the trustdb */
366             rc = insert_trust_record( pk );
367             if( rc ) {
368                 log_error(_("key %08lX: can't put it into the trustdb\n"),
369                                                             (ulong)keyid[1] );
370                 goto leave;
371             }
372         }
373         else if( rc ) {
374             log_error(_("key %08lX: query record failed\n"), (ulong)keyid[1] );
375             goto leave;
376
377         }
378
379         if( DBG_TRUST )
380             log_debug("key %08lX.%lu: stored into ultikey_table\n",
381                                     (ulong)keyid[1], pk->local_id );
382         if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
383             log_error(_("key %08lX: already in ultikey_table\n"),
384                                                         (ulong)keyid[1]);
385
386
387         release_secret_key_parts( sk );
388         release_public_key_parts( pk );
389     }
390     if( rc != -1 )
391         log_error(_("enum_secret_keys failed: %s\n"), g10_errstr(rc) );
392     else
393         rc = 0;
394
395   leave:
396     free_secret_key( sk );
397     free_public_key( pk );
398     return rc;
399 }
400
401
402 static void
403 print_user_id( const char *text, u32 *keyid )
404 {
405     char *p;
406     size_t n;
407
408     p = get_user_id( keyid, &n );
409     if( *text ) {
410         fputs( text, stdout);
411         putchar(' ');
412     }
413     putchar('\"');
414     print_string( stdout, p, n, 0 );
415     putchar('\"');
416     putchar('\n');
417     m_free(p);
418 }
419
420 static void
421 print_keyid( FILE *fp, ulong lid )
422 {
423     u32 ki[2];
424     if( keyid_from_trustdb( lid, ki ) )
425         fprintf(fp, "????????.%lu", lid );
426     else
427         fprintf(fp, "%08lX.%lu", (ulong)ki[1], lid );
428 }
429
430 static void
431 print_trust( FILE *fp, unsigned trust )
432 {
433     int c;
434     switch( trust ) {
435       case TRUST_UNKNOWN:   c = 'o'; break;
436       case TRUST_EXPIRED:   c = 'e'; break;
437       case TRUST_UNDEFINED: c = 'q'; break;
438       case TRUST_NEVER:     c = 'n'; break;
439       case TRUST_MARGINAL:  c = 'm'; break;
440       case TRUST_FULLY:     c = 'f'; break;
441       case TRUST_ULTIMATE:  c = 'u'; break;
442       default: fprintf(fp, "%02x", trust ); return;
443     }
444     putc(c, fp);
445 }
446
447 /* (a non-recursive algorithm would be easier) */
448 static int
449 do_list_sigs( ulong root, ulong pubkey, int depth,
450               LOCAL_ID_INFO *lids, unsigned *lineno )
451 {
452     SIGREC_CONTEXT sx;
453     int rc;
454     u32 keyid[2];
455
456     memset( &sx, 0, sizeof sx );
457     sx.local_id = pubkey;
458     for(;;) {
459         rc = walk_sigrecs( &sx, 0 );
460         if( rc )
461             break;
462         rc = keyid_from_local_id( sx.sig_id, keyid );
463         if( rc ) {
464             printf("%6u: %*s????????.%lu:%02x\n", *lineno, depth*4, "",
465                                                    sx.sig_id, sx.sig_flag );
466             ++*lineno;
467         }
468         else {
469             printf("%6u: %*s%08lX.%lu:%02x ", *lineno, depth*4, "",
470                               (ulong)keyid[1], sx.sig_id, sx.sig_flag );
471             /* check whether we already checked this pubkey */
472             if( !qry_lid_table_flag( ultikey_table, sx.sig_id, NULL ) ) {
473                 print_user_id("[ultimately trusted]", keyid);
474                 ++*lineno;
475             }
476             else if( sx.sig_id == pubkey ) {
477                 printf("[self-signature]\n");
478                 ++*lineno;
479             }
480             else if( sx.sig_id == root ) {
481                 printf("[closed]\n");
482                 ++*lineno;
483             }
484             else if( ins_lid_table_item( lids, sx.sig_id, *lineno ) ) {
485                 unsigned refline;
486                 qry_lid_table_flag( lids, sx.sig_id, &refline );
487                 printf("[see line %u]\n", refline);
488                 ++*lineno;
489             }
490             else if( depth+1 >= MAX_LIST_SIGS_DEPTH  ) {
491                 print_user_id( "[too deeply nested]", keyid );
492                 ++*lineno;
493             }
494             else {
495                 print_user_id( "", keyid );
496                 ++*lineno;
497                 rc = do_list_sigs( root, sx.sig_id, depth+1, lids, lineno );
498                 if( rc )
499                     break;
500             }
501         }
502     }
503     return rc==-1? 0 : rc;
504 }
505
506 /****************
507  * List all signatures of a public key
508  */
509 static int
510 list_sigs( ulong pubkey_id )
511 {
512     int rc;
513     u32 keyid[2];
514     LOCAL_ID_INFO *lids;
515     unsigned lineno = 1;
516
517     rc = keyid_from_local_id( pubkey_id, keyid );
518     if( rc ) {
519         log_error("Hmmm, no pubkey record for local_id %lu\n", pubkey_id);
520         return rc;
521     }
522     printf("Signatures of %08lX.%lu ", (ulong)keyid[1], pubkey_id );
523     print_user_id("", keyid);
524     printf("----------------------\n");
525
526     lids = new_lid_table();
527     rc = do_list_sigs( pubkey_id, pubkey_id, 0, lids, &lineno );
528     putchar('\n');
529     release_lid_table(lids);
530     return rc;
531 }
532
533
534
535 /****************
536  * Function to collect all trustpaths
537  */
538 static int
539 do_list_path( TRUST_INFO *stack, int depth, int max_depth,
540               LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist )
541 {
542     SIGREC_CONTEXT sx;
543     unsigned last_depth;
544     int rc;
545
546     assert(depth);
547
548     /*printf("%2lu/%d: scrutinizig\n", stack[depth-1], depth);*/
549     if( depth >= max_depth || depth >= MAX_LIST_SIGS_DEPTH-1 ) {
550         /*printf("%2lu/%d: too deeply nested\n", stack[depth-1], depth);*/
551         return 0;
552     }
553     memset( &sx, 0, sizeof sx );
554     sx.local_id = stack[depth-1].lid;
555     /* loop over all signatures. If we do not have any, try to
556      * create them */
557     while( !(rc = walk_sigrecs( &sx, 1 )) ) {
558         TRUST_SEG_LIST tsl, t2, tl;
559         int i;
560
561         stack[depth].lid = sx.sig_id;
562         stack[depth].trust = 0;
563         if( qry_lid_table_flag( lids, sx.sig_id, &last_depth) ) {
564             /*printf("%2lu/%d: marked\n", sx.sig_id, depth );*/
565             ins_lid_table_item( lids, sx.sig_id, depth);
566             last_depth = depth;
567         }
568         else if( depth  < last_depth ) {
569             /*printf("%2lu/%d: last_depth=%u - updated\n", sx.sig_id, depth, last_depth);*/
570             last_depth = depth;
571             upd_lid_table_flag( lids, sx.sig_id, depth);
572         }
573
574         if( last_depth < depth )
575             /*printf("%2lu/%d: already visited\n", sx.sig_id, depth)*/;
576         else if( !qry_lid_table_flag( ultikey_table, sx.sig_id, NULL ) ) {
577             /* found end of path; store it, ordered by path length */
578             tsl = m_alloc( sizeof *tsl + depth*sizeof(TRUST_INFO) );
579             tsl->nseg = depth+1;
580             tsl->dup = 0;
581             for(i=0; i <= depth; i++ )
582                 tsl->seg[i] = stack[i];
583             for(t2=*tslist,tl=NULL; t2; tl=t2, t2 = t2->next )
584                 if( depth < t2->nseg )
585                     break;
586             if( !tl ) {
587                 tsl->next = t2;
588                 *tslist = tsl;
589             }
590             else {
591                 tsl->next = t2;
592                 tl->next = tsl;
593             }
594             /*putchar('.'); fflush(stdout);*/
595             /*printf("%2lu/%d: found\n", sx.sig_id, depth);*/
596         }
597         else {
598             rc = do_list_path( stack, depth+1, max_depth, lids, tslist);
599             if( rc && rc != -1 )
600                 break;
601         }
602     }
603     return rc==-1? 0 : rc;
604 }
605
606
607
608 /****************
609  * Check all the sigs of the given keyblock and mark them
610  * as checked. Valid signatures which are duplicates are
611  * also marked [shall we check them at all?]
612  * FIXME: what shall we do if we have duplicate signatures where only
613  *        some of them are bad?
614  */
615 static int
616 check_sigs( KBNODE keyblock, int *selfsig_okay, int *revoked )
617 {
618     KBNODE node;
619     int rc;
620     LOCAL_ID_INFO *dups = NULL;
621
622     *selfsig_okay = 0;
623     *revoked = 0;
624     for( node=keyblock; node; node = node->next ) {
625         if( node->pkt->pkttype == PKT_SIGNATURE
626             && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
627                   || node->pkt->pkt.signature->sig_class == 0x20
628                   || node->pkt->pkt.signature->sig_class == 0x30) ) {
629             int selfsig;
630             rc = check_key_signature( keyblock, node, &selfsig );
631             if( !rc ) {
632                 rc = set_signature_packets_local_id( node->pkt->pkt.signature );
633                 if( rc )
634                     log_fatal("set_signature_packets_local_id failed: %s\n",
635                                                               g10_errstr(rc));
636                 if( selfsig ) {
637                     node->flag |= 2; /* mark signature valid */
638                     *selfsig_okay = 1;
639                 }
640                 else if( node->pkt->pkt.signature->sig_class == 0x20 )
641                     *revoked = 1;
642                 else
643                     node->flag |= 1; /* mark signature valid */
644
645                 if( node->pkt->pkt.signature->sig_class != 0x20 ) {
646                     if( !dups )
647                         dups = new_lid_table();
648                     if( ins_lid_table_item( dups,
649                                         node->pkt->pkt.signature->local_id, 0) )
650                         node->flag |= 4; /* mark as duplicate */
651                 }
652             }
653             if( DBG_TRUST )
654                 log_debug("trustdb: sig from %08lX.%lu: %s%s\n",
655                                 (ulong)node->pkt->pkt.signature->keyid[1],
656                                 node->pkt->pkt.signature->local_id,
657                                 g10_errstr(rc), (node->flag&4)?"  (dup)":"" );
658         }
659     }
660     if( dups )
661         release_lid_table(dups);
662     return 0;
663 }
664
665
666 /****************
667  * If we do not have sigrecs for the given key, build them and write them
668  * to the trustdb
669  */
670 static int
671 build_sigrecs( ulong lid )
672 {
673     TRUSTREC rec, krec, rec2;
674    KBNODE keyblock = NULL;
675    KBNODE node;
676     int rc=0;
677     int i, selfsig, revoked;
678     ulong rnum, rnum2;
679     ulong first_sigrec = 0;
680
681     if( DBG_TRUST )
682         log_debug("trustdb: build_sigrecs for LID %lu\n", lid );
683
684     /* get the keyblock */
685     if( (rc=tdbio_read_record( lid, &rec, RECTYPE_DIR )) ) {
686         log_error( "build_sigrecs: can't read dir record %lu\n"), lid );
687         goto leave;
688     }
689     if( (rc=tdbio_read_record( rec.r.dir.keylist, &krec, RECTYPE_KEY )) ) {
690         log_error("build_sigrecs: can't read primary key record %lu\n"), lid);
691         goto leave;
692     }
693     rc = get_keyblock_byfprint( &keyblock, krec.r.key.fingerprint,
694                                            krec.r.key.fingerprint_len );
695     if( rc ) {
696         log_error( "build_sigrecs: keyblock for %lu not found: %s\n",
697                                                     lid, g10_errstr(rc) );
698         goto leave;
699     }
700
701     /* check all key signatures */
702     rc = check_sigs( keyblock, &selfsig, &revoked );
703     if( rc ) {
704         log_error(_("build_sigrecs: check_sigs failed\n") );
705         goto leave;
706     }
707     if( !selfsig ) {
708         log_error(_("build_sigrecs: self-signature missing\n") );
709         tdbio_update_sigflag( lid, 2 );
710         rc = G10ERR_BAD_CERT;
711         goto leave;
712     }
713     if( revoked ) {
714         log_info(_("build_sigrecs: key has been revoked\n") );
715         tdbio_update_sigflag( lid, 3 );
716     }
717     else
718         tdbio_update_sigflag( lid, 0 ); /* assume we have sigs */
719
720     /* valid key signatures are now marked; we can now build the sigrecs */
721     memset( &rec, 0, sizeof rec );
722     rec.rectype = RECTYPE_SIG;
723     i = 0;
724     rnum = rnum2 = 0;
725     for( node=keyblock; node; node = node->next ) {
726         /* insert sigs which are not a selfsig nor a duplicate */
727         if( (node->flag & 1) && !(node->flag & 4) ) {
728             assert( node->pkt->pkttype == PKT_SIGNATURE );
729             if( !node->pkt->pkt.signature->local_id )  {
730                 /* the next function should always succeed, because
731                  * we have already checked the signature, and for this
732                  * it was necessary to have the pubkey. The only reason
733                  * this can fail are I/O errors of the trustdb or a
734                  * remove operation on the pubkey database - which should
735                  * not disturb us, because we have to change them anyway. */
736                 rc = set_signature_packets_local_id( node->pkt->pkt.signature );
737                 if( rc )
738                     log_fatal(_("set_signature_packets_local_id failed: %s\n"),
739                                                               g10_errstr(rc));
740             }
741             if( i == SIGS_PER_RECORD ) {
742                 /* write the record */
743                 rnum = tdbio_new_recnum();
744                 if( rnum2 ) { /* write the stored record */
745                     rec2.r.sig.lid  = lid;
746                     rec2.r.sig.next = rnum; /* the next record number */
747                     rc = tdbio_write_record( rnum2, &rec2 );
748                     if( rc ) {
749                         log_error(_("build_sigrecs: write_record failed\n") );
750                         goto leave;
751                     }
752                     if( !first_sigrec )
753                         first_sigrec = rnum2;
754                 }
755                 rec2 = rec;
756                 rnum2 = rnum;
757                 memset( &rec, 0, sizeof rec );
758                 rec.rectype = RECTYPE_SIG;
759                 i = 0;
760             }
761             rec.r.sig.sig[i].lid  = node->pkt->pkt.signature->local_id;
762             rec.r.sig.sig[i].flag = 0;
763             i++;
764         }
765     }
766     if( i || rnum2 ) {
767         /* write the record */
768         rnum = tdbio_new_recnum();
769         if( rnum2 ) { /* write the stored record */
770             rec2.r.sig.lid  = lid;
771             rec2.r.sig.next = rnum;
772             rc = tdbio_write_record( rnum2, &rec2 );
773             if( rc ) {
774                 log_error(_("build_sigrecs: write_record failed\n") );
775                 goto leave;
776             }
777             if( !first_sigrec )
778                 first_sigrec = rnum2;
779         }
780         if( i ) { /* write the pending record */
781             rec.r.sig.lid = lid;
782             rec.r.sig.next = 0;
783             rc = tdbio_write_record( rnum, &rec );
784             if( rc ) {
785                 log_error(_("build_sigrecs: write_record failed\n") );
786                 goto leave;
787             }
788             if( !first_sigrec )
789                 first_sigrec = rnum;
790         }
791     }
792     if( first_sigrec ) { /* update the uid records */
793         if( (rc =tdbio_read_record( pubkeyid, &rec, RECTYPE_DIR )) ) {
794             log_error(_("update_dir_record: read failed\n"));
795             goto leave;
796         }
797         rec.r.dir.sigrec = first_sigrec;
798         if( (rc=tdbio_write_record( pubkeyid, &rec )) ) {
799             log_error(_("update_dir_record: write failed\n"));
800             goto leave;
801         }
802     }
803     else
804         tdbio_update_sigflag( lid, revoked? 3:1 ); /* no signatures */
805
806   leave:
807     release_kbnode( keyblock );
808     if( DBG_TRUST )
809         log_debug(_("trustdb: build_sigrecs: %s\n"), g10_errstr(rc) );
810     return rc;
811 }
812
813 /****************
814  * Make a list of trust paths
815  */
816 static int
817 make_tsl( ulong pubkey_id, TRUST_SEG_LIST *ret_tslist )
818 {
819     int i, rc;
820     LOCAL_ID_INFO *lids = new_lid_table();
821     TRUST_INFO stack[MAX_LIST_SIGS_DEPTH];
822     TRUST_SEG_LIST tsl, tslist;
823     int max_depth = 4;
824
825     tslist = *ret_tslist = NULL;
826
827     if( !qry_lid_table_flag( ultikey_table, pubkey_id, NULL ) ) {
828         tslist = m_alloc( sizeof *tslist );
829         tslist->nseg = 1;
830         tslist->dup = 0;
831         tslist->seg[0].lid = pubkey_id;
832         tslist->seg[0].trust = 0;
833         tslist->next = NULL;
834         rc = 0;
835     }
836     else {
837         stack[0].lid = pubkey_id;
838         stack[0].trust = 0;
839         rc = do_list_path( stack, 1, max_depth, lids, &tslist );
840     }
841     if( !rc ) { /* wipe out duplicates */
842         LOCAL_ID_INFO *work = new_lid_table();
843         for( tsl=tslist; tsl; tsl = tsl->next ) {
844             for(i=1; i < tsl->nseg-1; i++ ) {
845                 if( ins_lid_table_item( work, tsl->seg[i].lid, 0 ) ) {
846                     tsl->dup = 1; /* mark as duplicate */
847                     break;
848                 }
849             }
850         }
851         release_lid_table(work);
852         *ret_tslist = tslist;
853     }
854     else
855         ; /* FIXME: release tslist */
856     release_lid_table(lids);
857     return rc;
858 }
859
860
861 /****************
862  * Given a trust segment list tslist, walk over all paths and fill in
863  * the trust information for each segment.  What this function does is
864  * to assign a trustvalue to the first segment (which is the requested key)
865  * of each path.
866  *
867  * FIXME: We have to do more thinking here. e.g. we should never increase
868  *        the trust value.
869  *
870  * Do not do it for duplicates.
871  */
872 static int
873 propagate_trust( TRUST_SEG_LIST tslist )
874 {
875     int i, rc;
876     unsigned trust, tr;
877     TRUST_SEG_LIST tsl;
878
879     for(tsl = tslist; tsl; tsl = tsl->next ) {
880         if( tsl->dup )
881             continue;
882         assert( tsl->nseg );
883         /* the last segment is always an ultimately trusted one, so we can
884          * assign a fully trust to the next one */
885         i = tsl->nseg-1;
886         tsl->seg[i].trust = TRUST_ULTIMATE;
887         trust = TRUST_FULLY;
888         for(i-- ; i >= 0; i-- ) {
889             tsl->seg[i].trust = trust;
890             if( i > 0 ) {
891                 /* get the trust of this pubkey */
892                 rc = get_ownertrust( tsl->seg[i].lid, &tr );
893                 if( rc )
894                     return rc;
895                 if( tr < trust )
896                     trust = tr;
897             }
898         }
899     }
900     return 0;
901 }
902
903
904
905 /****************
906  * check whether we already build signature records
907  * Return: true if we have.
908  */
909 static int
910 do_we_have_sigs( TRUSTREC *dr )
911 {
912 }
913
914
915 /****************
916  * we have the pubkey record and all needed informations are in the trustdb
917  * but nothing more is known.
918  * (this function may re-read the dir record dr)
919  */
920 static int
921 do_check( TRUSTREC *dr, unsigned *trustlevel )
922 {
923     int i, rc=0;
924     TRUST_SEG_LIST tsl, tsl2, tslist;
925     int marginal, fully;
926     int fully_needed = opt.completes_needed;
927     int marginal_needed = opt.marginals_needed;
928     unsigned tflags = 0;
929
930     assert( fully_needed > 0 && marginal_needed > 1 );
931
932
933     *trustlevel = TRUST_UNDEFINED;
934
935     if( !dr->r.dir.keylist ) {
936         log_error("Ooops, no keys\n");
937         return G10ERR_TRUSTDB
938     }
939     if( !dr->r.dir.uidlist ) {
940         log_error("Ooops, no user ids\n");
941         return G10ERR_TRUSTDB
942     }
943
944     /* verify the cache */
945
946     /* do we have sigrecs */
947     if( !do_we_have_sigs( dr ) ) { /* no sigrecs, so build them */
948         rc = build_sigrecs( dr->lid );
949         if( !rc ) /* and read again */
950             rc = tdbio_read_record( dr->lid, dr, RECTYPE_DIR );
951     }
952
953
954    !!!!WORK!!!!
955
956     if( dr->r.dir.no_sigs == 3 )
957         tflags |= TRUST_FLAG_REVOKED;
958
959     if( !rc && !dr->r.dir.sigrec ) {
960         /* See whether this is our own key */
961         if( !qry_lid_table_flag( ultikey_table, pubkeyid, NULL ) )
962             *trustlevel = tflags | TRUST_ULTIMATE;
963         return 0;
964     }
965     if( rc )
966         return rc;  /* error while looking for sigrec or building sigrecs */
967
968     /* fixme: take it from the cache if it is valid */
969
970     /* Make a list of all possible trust-paths */
971     rc = make_tsl( pubkeyid, &tslist );
972     if( rc )
973         return rc;
974     rc = propagate_trust( tslist );
975     if( rc )
976         return rc;
977     for(tsl = tslist; tsl; tsl = tsl->next ) {
978         if( tsl->dup )
979             continue;
980
981         if( opt.verbose ) {
982             log_info("trust path:" );
983             for(i=0; i < tsl->nseg; i++ ) {
984                 putc(' ',stderr);
985                 print_keyid( stderr, tsl->seg[i].lid );
986                 putc(':',stderr);
987                 print_trust( stderr, tsl->seg[i].trust );
988             }
989             putc('\n',stderr);
990         }
991     }
992
993     /* and see whether there is a trusted path.
994      * We only have to look at the first segment, because
995      * propagate_trust has investigated all other segments */
996     marginal = fully = 0;
997     for(tsl = tslist; tsl; tsl = tsl->next ) {
998         if( tsl->dup )
999             continue;
1000         if( tsl->seg[0].trust == TRUST_ULTIMATE ) {
1001             *trustlevel = tflags | TRUST_ULTIMATE; /* our own key */
1002             break;
1003         }
1004         if( tsl->seg[0].trust == TRUST_FULLY ) {
1005             marginal++;
1006             fully++;
1007         }
1008         else if( tsl->seg[0].trust == TRUST_MARGINAL )
1009             marginal++;
1010
1011         if( fully >= fully_needed ) {
1012             *trustlevel = tflags | TRUST_FULLY;
1013             break;
1014         }
1015     }
1016     if( !tsl && marginal >= marginal_needed )
1017         *trustlevel = tflags | TRUST_MARGINAL;
1018
1019     /* cache the tslist */
1020     if( last_trust_web_key ) {
1021         for( tsl = last_trust_web_tslist; tsl; tsl = tsl2 ) {
1022             tsl2 = tsl->next;
1023             m_free(tsl);
1024         }
1025     }
1026     last_trust_web_key = pubkeyid;
1027     last_trust_web_tslist = tslist;
1028     return 0;
1029 }
1030
1031
1032 /***********************************************
1033  ****************  API  ************************
1034  ***********************************************/
1035
1036 /****************
1037  * Perform some checks over the trustdb
1038  *  level 0: only open the db
1039  *        1: used for initial program startup
1040  */
1041 int
1042 init_trustdb( int level, const char *dbname )
1043 {
1044     int rc=0;
1045
1046     if( !ultikey_table )
1047         ultikey_table = new_lid_table();
1048
1049     if( !level || level==1 ) {
1050         rc = tdbio_set_dbname( dbname, !!level );
1051         if( rc )
1052             return rc;
1053         if( !level )
1054             return 0;
1055
1056         /* verify that our own keys are in the trustDB
1057          * or move them to the trustdb. */
1058         rc = verify_own_keys();
1059
1060         /* should we check whether there is no other ultimately trusted
1061          * key in the database? */
1062
1063     }
1064     else
1065         BUG();
1066
1067     return rc;
1068 }
1069
1070
1071 void
1072 list_trustdb( const char *username )
1073 {
1074     TRUSTREC rec;
1075
1076     if( username ) {
1077         PKT_public_key *pk = m_alloc_clear( sizeof *pk );
1078         int rc;
1079
1080         if( (rc = get_pubkey_byname( pk, username )) )
1081             log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
1082         else if( (rc=tdbio_search_record( pk, &rec )) && rc != -1 )
1083             log_error("problem finding '%s' in trustdb: %s\n",
1084                                                 username, g10_errstr(rc));
1085         else if( rc == -1 )
1086             log_error("user '%s' not in trustdb\n", username);
1087         else if( (rc = list_sigs( pk->local_id )) )
1088             log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
1089         free_public_key( pk );
1090     }
1091     else {
1092         ulong recnum;
1093         int i;
1094
1095         printf("TrustDB: %s\n", tdbio_get_dbname() );
1096         for(i=9+strlen(tdbio_get_dbname()); i > 0; i-- )
1097             putchar('-');
1098         putchar('\n');
1099         for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ )
1100             tdbio_dump_record( recnum, &rec, stdout );
1101     }
1102 }
1103
1104 /****************
1105  * make a list of all owner trust value.
1106  */
1107 void
1108 list_ownertrust()
1109 {
1110     TRUSTREC rec;
1111     ulong recnum;
1112     int i;
1113     byte *p;
1114
1115     for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
1116         if( rec.rectype == RECTYPE_KEY ) {
1117             p = rec.r.key.fingerprint;
1118             for(i=0; i < rec.r.key.fingerprint_len; i++, p++ )
1119                 printf("%02X", *p );
1120             printf(":%u:\n", (unsigned)rec.r.key.ownertrust );
1121         }
1122     }
1123 }
1124
1125 void
1126 list_trust_path( int max_depth, const char *username )
1127 {
1128     int rc;
1129     int wipe=0;
1130     int i;
1131     TRUSTREC rec;
1132     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
1133
1134     if( max_depth < 0 ) {
1135         wipe = 1;
1136         max_depth = -max_depth;
1137     }
1138
1139     if( (rc = get_pubkey_byname( pk, username )) )
1140         log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
1141     else if( (rc=tdbio_search_record( pk, &rec )) && rc != -1 )
1142         log_error("problem finding '%s' in trustdb: %s\n",
1143                                             username, g10_errstr(rc));
1144     else if( rc == -1 ) {
1145         log_info("user '%s' not in trustdb - inserting\n", username);
1146         rc = insert_trust_record( pk );
1147         if( rc )
1148             log_error("failed to put '%s' into trustdb: %s\n", username, g10_errstr(rc));
1149         else {
1150             assert( pk->local_id );
1151         }
1152     }
1153
1154     if( !rc ) {
1155         TRUST_SEG_LIST tsl, tslist = NULL;
1156
1157         if( !qry_lid_table_flag( ultikey_table, pk->local_id, NULL ) ) {
1158             tslist = m_alloc( sizeof *tslist );
1159             tslist->nseg = 1;
1160             tslist->dup = 0;
1161             tslist->seg[0].lid = pk->local_id;
1162             tslist->seg[0].trust = 0;
1163             tslist->next = NULL;
1164             rc = 0;
1165         }
1166         else {
1167             LOCAL_ID_INFO *lids = new_lid_table();
1168             TRUST_INFO stack[MAX_LIST_SIGS_DEPTH];
1169
1170             stack[0].lid = pk->local_id;
1171             stack[0].trust = 0;
1172             rc = do_list_path( stack, 1, max_depth, lids, &tslist );
1173             if( wipe ) { /* wipe out duplicates */
1174                 LOCAL_ID_INFO *work;
1175
1176                 work = new_lid_table();
1177                 for( tsl=tslist; tsl; tsl = tsl->next ) {
1178                     for(i=1; i < tsl->nseg-1; i++ ) {
1179                         if( ins_lid_table_item( work, tsl->seg[i].lid, 0 ) ) {
1180                             tsl->dup = 1; /* mark as duplicate */
1181                             break;
1182                         }
1183                     }
1184                 }
1185                 release_lid_table(work);
1186             }
1187             release_lid_table(lids);
1188         }
1189         if( rc )
1190             log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
1191         rc = propagate_trust( tslist );
1192         if( rc )
1193             log_error("user '%s' trust problem: %s\n", username, g10_errstr(rc));
1194         for(tsl = tslist; tsl; tsl = tsl->next ) {
1195             int i;
1196
1197             if( tsl->dup )
1198                 continue;
1199             printf("trust path:" );
1200             for(i=0; i < tsl->nseg; i++ ) {
1201                 putc(' ',stdout);
1202                 print_keyid( stdout, tsl->seg[i].lid );
1203                 putc(':',stdout);
1204                 print_trust( stdout, tsl->seg[i].trust );
1205             }
1206             putchar('\n');
1207         }
1208     }
1209
1210     free_public_key( pk );
1211 }
1212
1213
1214 /****************
1215  * Get the trustlevel for this PK.
1216  * Note: This does not ask any questions
1217  * Returns: 0 okay of an errorcode
1218  *
1219  * It operates this way:
1220  *  locate the pk in the trustdb
1221  *      found:
1222  *          Do we have a valid cache record for it?
1223  *              yes: return trustlevel from cache
1224  *              no:  make a cache record and all the other stuff
1225  *      not found:
1226  *          try to insert the pubkey into the trustdb and check again
1227  *
1228  * Problems: How do we get the complete keyblock to check that the
1229  *           cache record is actually valid?  Think we need a clever
1230  *           cache in getkey.c  to keep track of this stuff. Maybe it
1231  *           is not necessary to check this if we use a local pubring. Hmmmm.
1232  */
1233 int
1234 check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
1235 {
1236     TRUSTREC rec;
1237     unsigned trustlevel = TRUST_UNKNOWN;
1238     int rc=0;
1239     u32 cur_time;
1240     u32 keyid[2];
1241
1242
1243     if( DBG_TRUST )
1244         log_info("check_trust() called.\n");
1245     keyid_from_pk( pk, keyid );
1246
1247     /* get the pubkey record */
1248     if( pk->local_id ) {
1249         if( tdbio_read_record( pk->local_id, &rec, RECTYPE_DIR ) ) {
1250             log_error("check_trust: read dir record failed\n");
1251             return G10ERR_TRUSTDB;
1252         }
1253     }
1254     else { /* no local_id: scan the trustdb */
1255         if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) {
1256             log_error("check_trust: search dir record failed: %s\n",
1257                                                             g10_errstr(rc));
1258             return rc;
1259         }
1260         else if( rc == -1 ) { /* not found - insert */
1261             rc = insert_trust_record( pk );
1262             if( rc ) {
1263                 log_error(_("key %08lX: insert trust record failed: %s\n"),
1264                                                 keyid[1], g10_errstr(rc));
1265                 goto leave;
1266             }
1267             log_info(_("key %08lX.%lu: inserted into trustdb\n"),
1268                                           keyid[1], pk->local_id );
1269         }
1270     }
1271     cur_time = make_timestamp();
1272     if( pk->timestamp > cur_time ) {
1273         log_info(_("key %08lX.%lu: created in future "
1274                    "(time warp or clock problem)\n"),
1275                                           keyid[1], pk->local_id );
1276         return G10ERR_TIME_CONFLICT;
1277     }
1278
1279     if( pk->valid_days && add_days_to_timestamp(pk->timestamp,
1280                                                 pk->valid_days) < cur_time ) {
1281         log_info(_("key %08lX.%lu: expired at %s\n"),
1282                         keyid[1], pk->local_id,
1283                     strtimestamp( add_days_to_timestamp(pk->timestamp,
1284                                                         pk->valid_days)));
1285          trustlevel = TRUST_EXPIRED;
1286     }
1287     else {
1288         rc = do_check( &rec, &trustlevel );
1289         if( rc ) {
1290             log_error(_("key %08lX.%lu: trust check failed: %s\n"),
1291                             keyid[1], pk->local_id, g10_errstr(rc));
1292             return rc;
1293         }
1294     }
1295
1296
1297   leave:
1298     if( DBG_TRUST )
1299         log_debug("check_trust() returns trustlevel %04x.\n", trustlevel);
1300     *r_trustlevel = trustlevel;
1301     return 0;
1302 }
1303
1304
1305 int
1306 query_trust_info( PKT_public_key *pk )
1307 {
1308     unsigned trustlevel;
1309     int c;
1310
1311     if( check_trust( pk, &trustlevel ) )
1312         return '?';
1313     if( trustlevel & TRUST_FLAG_REVOKED )
1314         return 'r';
1315     switch( (trustlevel & TRUST_MASK) ) {
1316       case TRUST_UNKNOWN:   c = 'o'; break;
1317       case TRUST_EXPIRED:   c = 'e'; break;
1318       case TRUST_UNDEFINED: c = 'q'; break;
1319       case TRUST_NEVER:     c = 'n'; break;
1320       case TRUST_MARGINAL:  c = 'm'; break;
1321       case TRUST_FULLY:     c = 'f'; break;
1322       case TRUST_ULTIMATE:  c = 'u'; break;
1323       default: BUG();
1324     }
1325     return c;
1326 }
1327
1328
1329
1330 /****************
1331  * Enumerate all keys, which are needed to build all trust paths for
1332  * the given key.  This function does not return the key itself or
1333  * the ultimate key.
1334  *
1335  *  1) create a void pointer and initialize it to NULL
1336  *  2) pass this void pointer by reference to this function.
1337  *     Set lid to the key you want to enumerate and pass it by reference.
1338  *  3) call this function as long as it does not return -1
1339  *     to indicate EOF. LID does contain the next key used to build the web
1340  *  4) Always call this function a last time with LID set to NULL,
1341  *     so that it can free its context.
1342  */
1343 int
1344 enum_trust_web( void **context, ulong *lid )
1345 {
1346     ENUM_TRUST_WEB_CONTEXT *c = *context;
1347
1348     if( !c ) { /* make a new context */
1349         c = m_alloc_clear( sizeof *c );
1350         *context = c;
1351         if( *lid != last_trust_web_key && last_trust_web_key )
1352             log_bug("enum_trust_web: nyi\n"); /* <--- FIXME */
1353         c->tsl = last_trust_web_tslist;
1354         c->index = 1;
1355     }
1356
1357     if( !lid ) { /* free the context */
1358         m_free( c );
1359         *context = NULL;
1360         return 0;
1361     }
1362
1363     while( c->tsl ) {
1364         if( !c->tsl->dup && c->index < c->tsl->nseg-1 ) {
1365             *lid = c->tsl->seg[c->index].lid;
1366             c->index++;
1367             return 0;
1368         }
1369         c->index = 1;
1370         c->tsl = c->tsl->next;
1371     }
1372     return -1; /* eof */
1373 }
1374
1375
1376 /****************
1377  * Return the assigned ownertrust value for the given LID
1378  */
1379 int
1380 get_ownertrust( ulong lid, unsigned *r_otrust )
1381 {
1382     TRUSTREC rec;
1383
1384     if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
1385         log_error("get_ownertrust: read dir record failed\n");
1386         return G10ERR_TRUSTDB;
1387     }
1388     if( tdbio_read_record( rec.r.dir.keyrec, &rec, RECTYPE_KEY ) ) {
1389         log_error("get_ownertrust: read key record failed\n");
1390         return G10ERR_TRUSTDB;
1391     }
1392     if( r_otrust )
1393         *r_otrust = rec.r.key.ownertrust;
1394     return 0;
1395 }
1396
1397 int
1398 keyid_from_trustdb( ulong lid, u32 *keyid )
1399 {
1400     TRUSTREC rec;
1401
1402     if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
1403         log_error("keyid_from_trustdb: read record failed\n");
1404         return G10ERR_TRUSTDB;
1405     }
1406     if( keyid ) {
1407         keyid[0] = rec.r.dir.keyid[0];
1408         keyid[1] = rec.r.dir.keyid[1];
1409     }
1410     return 0;
1411 }
1412
1413
1414 /****************
1415  * This function simply looks for the key in the trustdb
1416  * and sets PK->local_id.
1417  * Return: 0 = found
1418  *         -1 = not found
1419  *        other = error
1420  */
1421 int
1422 query_trust_record( PKT_public_key *pk )
1423 {
1424     TRUSTREC rec;
1425     int rc=0;
1426
1427     if( pk->local_id ) {
1428         if( tdbio_read_record( pk->local_id, &rec, RECTYPE_DIR ) ) {
1429             log_error("query_trust_record: read record failed\n");
1430             return G10ERR_TRUSTDB;
1431         }
1432     }
1433     else { /* no local_id: scan the trustdb */
1434         if( (rc=tdbio_search_record( pk, &rec )) && rc != -1 ) {
1435             log_error("query_trust_record: search_record failed: %s\n",
1436                                                             g10_errstr(rc));
1437             return rc;
1438         }
1439     }
1440     return rc;
1441 }
1442
1443
1444 /****************
1445  * Insert a trust record into the TrustDB
1446  * This function fails if this record already exists.
1447  */
1448 int
1449 insert_trust_record( PKT_public_key *orig_pk )
1450 {
1451     TRUSTREC dirrec, *rec;
1452     TRUSTREC **keylist_tail, *keylist;
1453     TRUSTREC **uidlist_tail, *uidlist;
1454     KBNODE keyblock = NULL;
1455     KBNODE node;
1456     u32 keyid[2];
1457     ulong knum, dnum;
1458     byte *fingerprint;
1459     size_t fingerlen;
1460     int rc = 0;
1461
1462
1463     if( orig_pk->local_id )
1464         log_bug("pk->local_id=%lu\n", (ulong)pk->local_id );
1465
1466     fingerprint = fingerprint_from_pk( orig_pk, &fingerlen );
1467
1468     /* fixme: assert that we do not have this record.
1469      * we can do this by searching for the primary keyid
1470      */
1471
1472     /* get the keyblock which has the key */
1473     rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
1474     if( rc ) { /* that should never happen */
1475         log_error( "insert_trust_record: keyblock not found: %s\n",
1476                                                           g10_errstr(rc) );
1477         return rc;
1478     }
1479
1480     /* prepare dir record */
1481     memset( &dirrec, 0, sizeof dirrec );
1482     dirrec.rectype = RECTYPE_DIR;
1483     dirrec.r.dir.lid = tdbio_new_recnum();
1484
1485     keylist = NULL;
1486     keylist_tail = &dirrec.r.dir.keylist;
1487     uidlist = NULL;
1488     uidlist_tail = &dirrec.r.dir.uidlist;
1489     /* loop over the keyblock */
1490     for( node=keyblock; node; node = node->next ) {
1491         if( node->pkt->pkttype == PKT_PUBLIC_KEY
1492             || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
1493             PKT_public_key *pk = node->pkt->pkt.public_key;
1494
1495             if( keylist && node->pkt->pkttype == PKT_PUBLIC_KEY )
1496                 BUG();  /* more than one primary key */
1497             fingerprint = fingerprint_from_pk( orig_pk, &fingerlen );
1498             rec = m_alloc_clear( sizeof *rec );
1499             rec->r.key.pubkey_algo = pk->pubkey_algo;
1500             rec->r.key.fingerprint_len = fingerlen;
1501             memcpy(rec->r.key.fingerprint, fingerprint, fingerlen );
1502
1503             if( keylist )
1504                 keylist_tail = &keylist->next;
1505             *keylist_tail = keylist = rec;
1506         }
1507         else if( node->pkt->pkttype == PKT_USER_ID ) {
1508             PKT_user_id *uid = node->pkt->pkt.user_id;
1509
1510             rec = m_alloc_clear( sizeof *rec );
1511             rmd160_hash_buffer( rec->r.uid.namehash, uid->name, uid->len );
1512
1513             if( uidlist )
1514                 uidlist_tail = &uidlist->next;
1515             *uidlist_tail = uidlist = rec;
1516         }
1517         if( node->pkt->pkttype == PKT_SIGNATURE
1518             && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
1519                   || node->pkt->pkt.signature->sig_class == 0x20
1520                   || node->pkt->pkt.signature->sig_class == 0x30) ) {
1521             int selfsig;
1522             rc = check_key_signature( keyblock, node, &selfsig );
1523             if( !rc ) {
1524                 rc = set_signature_packets_local_id( node->pkt->pkt.signature );
1525                 if( rc )
1526                     log_fatal("set_signature_packets_local_id failed: %s\n",
1527                                                               g10_errstr(rc));
1528                 if( selfsig ) {
1529                     node->flag |= 2; /* mark signature valid */
1530                     *selfsig_okay = 1;
1531                 }
1532                 else if( node->pkt->pkt.signature->sig_class == 0x20 )
1533                     *revoked = 1;
1534                 else
1535                     node->flag |= 1; /* mark signature valid */
1536
1537                 if( node->pkt->pkt.signature->sig_class != 0x20 ) {
1538                     if( !dups )
1539                         dups = new_lid_table();
1540                     if( ins_lid_table_item( dups,
1541                                         node->pkt->pkt.signature->local_id, 0) )
1542                         node->flag |= 4; /* mark as duplicate */
1543                 }
1544             }
1545             if( DBG_TRUST )
1546                 log_debug("trustdb: sig from %08lX.%lu: %s%s\n",
1547                                 (ulong)node->pkt->pkt.signature->keyid[1],
1548                                 node->pkt->pkt.signature->local_id,
1549                                 g10_errstr(rc), (node->flag&4)?"  (dup)":"" );
1550         }
1551     }
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562     knum = tdbio_new_recnum();
1563     /* build dir record */
1564     memset( &rec, 0, sizeof rec );
1565     rec.rectype = RECTYPE_DIR;
1566     rec.r.dir.local_id = dnum;
1567     rec.r.dir.keyid[0] = keyid[0];
1568     rec.r.dir.keyid[1] = keyid[1];
1569     rec.r.dir.keyrec   = knum;
1570     rec.r.dir.no_sigs = 0;
1571     /* and the key record */
1572     memset( &rec, 0, sizeof rec );
1573     rec.rectype = RECTYPE_KEY;
1574     rec.r.key.owner    = dnum;
1575     rec.r.key.keyid[0] = keyid[0];
1576     rec.r.key.keyid[1] = keyid[1];
1577     rec.r.key.pubkey_algo = pk->pubkey_algo;
1578     rec.r.key.fingerprint_len = fingerlen;
1579     memcpy(rec.r.key.fingerprint, fingerprint, fingerlen );
1580     rec.r.key.ownertrust = 0;
1581     if( tdbio_write_record( knum, &rec ) ) {
1582         log_error("wrinting key record failed\n");
1583         return G10ERR_TRUSTDB;
1584     }
1585
1586     if( tdbio_write_record( dirrec.r.dir.lid, &dirrec ) ) {
1587         log_error("writing dir record failed\n");
1588         return G10ERR_TRUSTDB;
1589     }
1590
1591     /* and store the LID */
1592     orig_pk->local_id = dnum;
1593
1594     return 0;
1595 }
1596
1597
1598 int
1599 update_ownertrust( ulong lid, unsigned new_trust )
1600 {
1601     TRUSTREC rec;
1602     ulong recnum;
1603
1604     if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
1605         log_error("update_ownertrust: read dir failed\n");
1606         return G10ERR_TRUSTDB;
1607     }
1608     recnum = rec.r.dir.keyrec;
1609     if( tdbio_read_record( recnum, &rec, RECTYPE_KEY ) ) {
1610         log_error("update_ownertrust: read key failed\n");
1611         return G10ERR_TRUSTDB;
1612     }
1613     /* check keyid, fingerprint etc ? */
1614
1615     rec.r.key.ownertrust = new_trust;
1616     if( tdbio_write_record( recnum, &rec ) ) {
1617         log_error("update_ownertrust: write failed\n");
1618         return G10ERR_TRUSTDB;
1619     }
1620
1621     return 0;
1622 }
1623
1624
1625
1626
1627