*** empty log message ***
[gnupg.git] / g10 / trustdb.c
1 /* trustdb.c
2  *      Copyright (c) 1997 by Werner Koch (dd9jn)
3  *
4  * This file is part of G10.
5  *
6  * G10 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  * G10 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 <unistd.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <fcntl.h>
29
30 #include "errors.h"
31 #include "iobuf.h"
32 #include "keydb.h"
33 #include "memory.h"
34 #include "util.h"
35 #include "trustdb.h"
36 #include "options.h"
37
38
39 #define TRUST_RECORD_LEN 40
40 #define SIGS_PER_RECORD ((TRUST_RECORD_LEN-10)/5)
41
42 struct trust_record {
43     byte rectype;
44     byte reserved;
45     union {
46         struct {            /* version record: */
47             byte magic[2];
48             byte version;   /* should be 1 */
49             byte reserved[3];
50             u32  locked;    /* pid of process which holds a lock */
51             u32  created;   /* timestamp of trustdb creation  */
52             u32  modified;  /* timestamp of last modification */
53             u32  validated; /* timestamp of last validation   */
54             u32  local_id_counter;
55             byte marginals_needed;
56             byte completes_needed;
57             byte max_cert_depth;
58         } version;
59         struct {            /* public key record */
60             u32 local_id;
61             u32 keyid[2];
62             byte algo;
63             byte reserved;
64             byte fingerprint[20];
65             byte ownertrust;
66             /* fixme: indicate a flag to */
67         } pubkey;
68         struct {            /* cache record */
69             u32 owner;
70             u32 keyid[2];       /* needed?? */
71             byte valid;
72             byte reserved;
73             byte blockhash[20];
74             byte n_untrusted;
75             byte n_marginal;
76             byte n_fully;
77             byte trustlevel;
78         } cache;
79         struct {
80             u32 owner;  /* local_id of record owner (pubkey record) */
81             u32 chain;  /* offset of next record or NULL for last one */
82             struct {
83                 u32  local_id; /* of pubkey record of signator (0=unused) */
84                 byte flag;     /* reserved */
85             } sig[SIGS_PER_RECORD];
86         } sigrec;
87     } r;
88 };
89 typedef struct trust_record TRUSTREC;
90
91
92 static void create_db( const char *fname );
93 static void open_db(void);
94 static int  read_record( u32 recnum, TRUSTREC *rec );
95 static u32 new_local_id(void);
96
97 static char *db_name;
98 static int  db_fd = -1;
99 static int no_io_dbg = 0;
100
101 #define buftou32( p )  ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
102                        (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
103 #define buftou16( p )  ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
104 #define u32tobuf( p, a ) do {                           \
105                             ((byte*)p)[0] = a >> 24;    \
106                             ((byte*)p)[1] = a >> 16;    \
107                             ((byte*)p)[2] = a >>  8;    \
108                             ((byte*)p)[3] = a      ;    \
109                         } while(0)
110 #define u16tobuf( p, a ) do {                           \
111                             ((byte*)p)[0] = a >>  8;    \
112                             ((byte*)p)[1] = a      ;    \
113                         } while(0)
114
115
116 /**************************************************
117  ************** read and write helpers ************
118  **************************************************/
119
120 static void
121 fwrite_8(FILE *fp, byte a)
122 {
123     if( putc( a & 0xff, fp ) == EOF )
124         log_fatal("error writing byte to trustdb: %s\n", strerror(errno) );
125 }
126
127 static void
128 fwrite_16(FILE *fp, u16 a)
129 {
130     putc( (a>>8) & 0x0ff , fp );
131     if( putc( a & 0xff, fp ) == EOF )
132         log_fatal("error writing u16 to trustdb: %s\n", strerror(errno) );
133 }
134
135 static int
136 fwrite_32( FILE*fp, u32 a)
137 {
138     putc( (a>>24) & 0xff, fp );
139     putc( (a>>16) & 0xff, fp );
140     putc( (a>> 8) & 0xff, fp );
141     if( putc( a & 0xff, fp ) == EOF )
142         log_fatal("error writing u32 to trustdb: %s\n", strerror(errno) );
143 }
144
145 static int
146 fwrite_zeros( FILE *fp, size_t n)
147 {
148     while( n-- )
149         if( putc( 0, fp ) == EOF )
150             log_fatal("error writing zeros to trustdb: %s\n", strerror(errno) );
151 }
152
153
154 /**************************************************
155  ************** read and write stuff **************
156  **************************************************/
157
158
159 /****************
160  * Create a new trustdb
161  */
162 static void
163 create_db( const char *fname )
164 {
165     FILE *fp;
166     u32 along;
167     u16 ashort;
168
169     fp =fopen( fname, "w" );
170     if( !fp )
171         log_fatal("can't create %s: %s\n", fname, strerror(errno) );
172     fwrite_8( fp, 1 );
173     fwrite_8( fp, 'g' );
174     fwrite_8( fp, '1' );
175     fwrite_8( fp, '0' );
176     fwrite_8( fp, 1 );  /* version */
177     fwrite_zeros( fp, 3 ); /* reserved */
178     fwrite_32( fp, 0 ); /* not locked */
179     fwrite_32( fp, make_timestamp() ); /* created */
180     fwrite_32( fp, 0 ); /* not yet modified */
181     fwrite_32( fp, 0 ); /* not yet validated*/
182     fwrite_32( fp, 0 ); /* local-id-counter (not used) */
183     fwrite_8( fp, 3 );  /* marginals needed */
184     fwrite_8( fp, 1 );  /* completes needed */
185     fwrite_8( fp, 4 );  /* max_cet_depth */
186     fwrite_zeros( fp, 9 ); /* filler */
187     fclose(fp);
188 }
189
190 static void
191 open_db()
192 {
193     TRUSTREC rec;
194     assert( db_fd == -1 );
195
196     db_fd = open( db_name, O_RDWR );
197     if( db_fd == -1 )
198         log_fatal("can't open %s: %s\n", db_name, strerror(errno) );
199     if( read_record( 0, &rec ) )
200         log_fatal("TrustDB %s is invalid\n", db_name );
201     /* fixme: check ->locked and other stuff */
202 }
203
204
205 /****************
206  * read the record with number recnum
207  * returns: -1 on error, 0 on success
208  */
209 static int
210 read_record( u32 recnum, TRUSTREC *rec )
211 {
212     byte buf[TRUST_RECORD_LEN], *p;
213     int rc = 0;
214     int n, i;
215
216     if( db_fd == -1 )
217         open_db();
218     if( DBG_TRUST && !no_io_dbg )
219         log_debug("trustdb: read_record(%lu)\n", (ulong)recnum);
220     if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
221         log_error("trustdb: lseek failed: %s\n", strerror(errno) );
222         return G10ERR_READ_FILE;
223     }
224     n = read( db_fd, buf, TRUST_RECORD_LEN);
225     if( !n ) {
226         if( DBG_TRUST )
227             log_debug("trustdb: no record at %lu\n", (ulong)recnum );
228         return -1; /* eof */
229     }
230     else if( n != TRUST_RECORD_LEN ) {
231         log_error("trustdb: read failed (n=%d): %s\n", n, strerror(errno) );
232         return G10ERR_READ_FILE;
233     }
234     p = buf;
235     rec->rectype = *p++;
236     rec->reserved = *p++;
237     switch( rec->rectype ) {
238       case 0:  /* unused record */
239         break;
240       case 1: /* version record */
241         rec->r.version.magic[0] = *p++;
242         rec->r.version.magic[1] = *p++;
243         rec->r.version.version  = *p++;
244         memcpy( rec->r.version.reserved, p, 3); p += 3;
245         rec->r.version.locked   = buftou32(p); p += 4;
246         rec->r.version.created  = buftou32(p); p += 4;
247         rec->r.version.modified = buftou32(p); p += 4;
248         rec->r.version.validated= buftou32(p); p += 4;
249         rec->r.version.local_id_counter = buftou32(p); p += 4;
250         rec->r.version.marginals_needed = *p++;
251         rec->r.version.completes_needed = *p++;
252         rec->r.version.max_cert_depth = *p++;
253         if( recnum ) {
254             log_error("%s: version record with recnum %lu\n",
255                                                     db_name, (ulong)recnum );
256             rc = G10ERR_TRUSTDB;
257         }
258         if( rec->reserved != 'g' || rec->r.version.magic[0] != '1'
259                                   || rec->r.version.magic[1] != '0' ) {
260             log_error("%s: not a trustdb file\n", db_name );
261             rc = G10ERR_TRUSTDB;
262         }
263         if( rec->r.version.version != 1 ) {
264             log_error("%s: invalid file version %d\n",
265                                        db_name, rec->r.version.version );
266             rc = G10ERR_TRUSTDB;
267         }
268         break;
269       case 2:
270         rec->r.pubkey.local_id = buftou32(p); p += 4;
271         rec->r.pubkey.keyid[0] = buftou32(p); p += 4;
272         rec->r.pubkey.keyid[1] = buftou32(p); p += 4;
273         rec->r.pubkey.algo = *p++;
274         rec->r.pubkey.reserved = *p++;
275         memcpy( rec->r.pubkey.fingerprint, p, 20); p += 20;
276         rec->r.pubkey.ownertrust = *p++;
277         if( rec->r.pubkey.local_id != recnum ) {
278             log_error("%s: pubkey local_id != recnum (%lu,%lu)\n",
279                                         db_name,
280                                         (ulong)rec->r.pubkey.local_id,
281                                         (ulong)recnum );
282             rc = G10ERR_TRUSTDB;
283         }
284         break;
285       case 3:
286         rec->r.cache.local_id = buftou32(p); p += 4;
287         rec->r.cache.keyid[0] = buftou32(p); p += 4;
288         rec->r.cache.keyid[1] = buftou32(p); p += 4;
289         rec->r.cache.valid = *p++;
290         rec->r.cache.reserved = *p++;
291         memcpy(rec->r.cache.blockhash, p, 20); p += 20;
292         rec->r.cache.n_untrusted = *p++;
293         rec->r.cache.n_marginal = *p++;
294         rec->r.cache.n_fully = *p++;
295         rec->r.cache.trustlevel = *p++;
296         break;
297       case 4:
298       case 5:
299         rec->r.sigrec.owner   = buftou32(p); p += 4;
300         rec->r.sigrec.chain   = buftou32(p); p += 4;
301         for(i=0; i < SIGS_PER_RECORD; i++ ) {
302             rec->r.sigrec.sig[i].local_id = buftou32(p); p += 4;
303             rec->r.sigrec.sig[i].flag = *p++;
304         }
305         break;
306       default:
307         log_error("%s: invalid record type %d at recnum %lu\n",
308                                         db_name, rec->rectype, (ulong)recnum );
309         rc = G10ERR_TRUSTDB;
310         break;
311     }
312
313
314     return rc;
315 }
316
317 /****************
318  * Write the record at RECNUM
319  */
320 static int
321 write_record( u32 recnum, TRUSTREC *rec )
322 {
323     byte buf[TRUST_RECORD_LEN], *p;
324     int rc = 0;
325     int i, n;
326
327     if( db_fd == -1 )
328         open_db();
329
330     if( DBG_TRUST && !no_io_dbg )
331         log_debug("trustdb: write_record(%lu)\n", (ulong)recnum);
332     memset(buf, 0, TRUST_RECORD_LEN);
333     p = buf;
334     *p++ = rec->rectype;
335     *p++ = rec->reserved;
336     switch( rec->rectype ) {
337       case 0:  /* unused record */
338         break;
339       case 1: /* version record */
340         log_bug(NULL);
341         break;
342       case 2:
343         u32tobuf(p, rec->r.pubkey.local_id); p += 4;
344         u32tobuf(p, rec->r.pubkey.keyid[0]); p += 4;
345         u32tobuf(p, rec->r.pubkey.keyid[1]); p += 4;
346         *p++ = rec->r.pubkey.algo;
347         *p++ = rec->r.pubkey.reserved;
348         memcpy( p, rec->r.pubkey.fingerprint, 20); p += 20;
349         *p++ = rec->r.pubkey.ownertrust;
350         assert( rec->r.pubkey.local_id == recnum );
351         break;
352       case 3:
353         u32tobuf(p, rec->r.cache.local_id); p += 4;
354         u32tobuf(p, rec->r.cache.keyid[0]); p += 4;
355         u32tobuf(p, rec->r.cache.keyid[1]); p += 4;
356         *p++ = rec->r.cache.valid;
357         *p++ = rec->r.cache.reserved;
358         memcpy(p, rec->r.cache.blockhash, 20); p += 20;
359         *p++ = rec->r.cache.n_untrusted;
360         *p++ = rec->r.cache.n_marginal;
361         *p++ = rec->r.cache.n_fully;
362         *p++ = rec->r.cache.trustlevel;
363         break;
364       case 4:
365       case 5:
366         u32tobuf(p, rec->r.sigrec.owner); p += 4;
367         u32tobuf(p, rec->r.sigrec.chain); p += 4;
368         for(i=0; i < SIGS_PER_RECORD; i++ ) {
369             u32tobuf(p, rec->r.sigrec.sig[i].local_id); p += 4;
370             *p++ = rec->r.sigrec.sig[i].flag;
371         }
372         break;
373       default:
374         log_bug(NULL);
375     }
376
377     if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
378         log_error("trustdb: lseek failed: %s\n", strerror(errno) );
379         return G10ERR_WRITE_FILE;
380     }
381     n = write( db_fd, buf, TRUST_RECORD_LEN);
382     if( n != TRUST_RECORD_LEN ) {
383         log_error("trustdb: write failed (n=%d): %s\n", n, strerror(errno) );
384         return G10ERR_WRITE_FILE;
385     }
386
387     return rc;
388 }
389
390 static u32
391 new_local_id()
392 {
393     off_t offset;
394     u32 recnum;
395
396     /* fixme: look for unused records */
397     offset = lseek( db_fd, 0, SEEK_END );
398     if( offset == -1 )
399         log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) );
400     recnum = offset / TRUST_RECORD_LEN;
401     assert(recnum); /* this is will never be the first record */
402     return recnum ;
403 }
404
405 /****************
406  * Scan the trustdb for a record of type RECTYPE which matches PKC
407  * The local_id is set to the correct value
408  */
409 static int
410 scan_record_by_pkc( PKT_public_cert *pkc, TRUSTREC *rec, int rectype )
411 {
412     u32 recnum;
413     u32 keyid[2];
414     byte *fingerprint;
415     size_t fingerlen;
416     int dbg = DBG_TRUST;
417     int rc;
418
419     assert( rectype == 2 || rectype == 3 );
420
421     if( DBG_TRUST )
422         log_debug("trustdb: scan_record_by_pkc\n");
423     keyid_from_pkc( pkc, keyid );
424     fingerprint = fingerprint_from_pkc( pkc, &fingerlen );
425     assert( fingerlen == 20 || fingerlen == 16 );
426
427     no_io_dbg = 1;
428     for(recnum=1; !(rc=read_record( recnum, rec)); recnum++ ) {
429         if( rec->rectype != rectype )
430             continue;
431         if( rec->rectype == 2 ) {
432             if( rec->r.pubkey.keyid[0] == keyid[0]
433                 && rec->r.pubkey.keyid[1] == keyid[1]
434                 && rec->r.pubkey.algo     == pkc->pubkey_algo
435                 && !memcmp(rec->r.pubkey.fingerprint, fingerprint, fingerlen)
436               ) { /* found */
437                 /* store the local_id */
438                 if( pkc->local_id && pkc->local_id != recnum )
439                     log_error("%s: found record, but local_id from mem does "
440                               "not match recnum (%lu,%lu)\n", db_name,
441                                          (ulong)pkc->local_id, (ulong)recnum );
442                 pkc->local_id = recnum;
443                 no_io_dbg = 0;
444                 return 0;
445             }
446         }
447         else
448             log_bug("not yet implemented\n");
449     }
450     no_io_dbg = 0;
451     if( DBG_TRUST )
452         log_debug("trustdb: scan_record_by_pkc: %s\n", rc==-1?"eof": g10_errstr(rc));
453     if( rc != -1 )
454         log_error("%s: scan_record_by_pkc failed: %s\n",db_name, g10_errstr(rc) );
455     return rc;
456 }
457
458 /****************
459  * scan the DB for a record of type RECTYPE which can be localized
460  * with LOCAL_ID
461  */
462 static int
463 scan_record( u32 local_id, TRUSTREC *rec, int rectype, u32 *r_recnum )
464 {
465     u32 recnum;
466     u32 keyid[2];
467     int dbg = DBG_TRUST;
468     int rc;
469
470     assert( rectype == 3 || rectype == 4 );
471
472     if( DBG_TRUST )
473         log_debug("trustdb: scan_record type %d local_id %lu\n",
474                                                 rectype, (ulong)local_id);
475     no_io_dbg = 1;
476     for(recnum=1; !(rc=read_record( recnum, rec)); recnum++ ) {
477         if( rec->rectype != rectype )
478             continue;
479         if( rec->rectype == 34 ) {
480             if( rec->r.cache.owner == local_id ) { /* found */
481                 *r_recnum = recnum;
482                 no_io_dbg = 0;
483                 return 0;
484             }
485         }
486         else if( rec->rectype == 4 ) {
487             if( rec->r.sigrec.owner == local_id ) { /* found */
488                 *r_recnum = recnum;
489                 no_io_dbg = 0;
490                 return 0;
491             }
492         }
493         else
494             log_bug("not yet implemented\n");
495     }
496     no_io_dbg = 0;
497     if( DBG_TRUST )
498         log_debug("trustdb: scan_record: %s\n", rc==-1?"eof": g10_errstr(rc));
499     if( rc != -1 )
500         log_error("%s: scan_record failed: %s\n",db_name, g10_errstr(rc) );
501     return rc;
502 }
503
504
505
506 /***********************************************
507  *************  trust logic  *******************
508  ***********************************************/
509
510 /****************
511  * Verify, that all our public keys are in the trustDB and marked as
512  * ultimately trusted.
513  */
514 static int
515 verify_own_certs()
516 {
517     int rc;
518     void *enum_context = NULL;
519     PKT_secret_cert *skc = m_alloc_clear( sizeof *skc );
520     PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
521     u32 keyid[2];
522     int trust;
523
524     while( !(rc=enum_secret_keys( &enum_context, skc) ) ) {
525         /* fixme: to be sure that it is a secret key of our own,
526          *        we should check it, but this needs a passphrase
527          *        for every key and this boring for the user.
528          *        Solution:  Sign the secring and the trustring
529          *                   and verify this signature during
530          *                   startup
531          */
532
533         keyid_from_skc( skc, keyid );
534
535         if( DBG_TRUST )
536             log_debug("checking secret key %08lX\n", (ulong)keyid[1] );
537
538         /* look wether we can access the public key of this secret key */
539         rc = get_pubkey( pkc, keyid );
540         if( rc ) {
541             log_error("keyid %08lX: secret key without public key\n",
542                                                             (ulong)keyid[1] );
543             goto leave;
544         }
545         if( cmp_public_secret_cert( pkc, skc ) ) {
546             log_error("keyid %08lX: secret and public key don't match\n",
547                                                             (ulong)keyid[1] );
548             rc = G10ERR_GENERAL;
549             goto leave;
550         }
551         /* look into the trustdb */
552         rc = check_pkc_trust( pkc, &trust );
553         if( rc ) {
554             log_info("keyid %08lX: problem in trustdb: %s\n", (ulong)keyid[1],
555                                                               g10_errstr(rc) );
556             goto leave;
557         }
558         if( trust & TRUST_NO_PUBKEY ) {
559             log_info("keyid %08lX: not yet in trustdb\n", (ulong)keyid[1] );
560             /* FIXME: insert */
561         }
562         else if( (trust & TRUST_MASK) != TRUST_ULT_TRUST )  {
563             log_error("keyid %08lX: not marked as ultimately trusted\n",
564                                                            (ulong)keyid[1] );
565             /* FIXME: mark */
566         }
567
568         release_secret_cert_parts( skc );
569         release_public_cert_parts( pkc );
570     }
571     if( rc != -1 )
572         log_error("enum_secret_keys failed: %s\n", g10_errstr(rc) );
573     else
574         rc = 0;
575
576   leave:
577     free_secret_cert( skc );
578     free_public_cert( pkc );
579     return rc;
580 }
581
582
583
584 /****************
585  * Check all the sigs of the given keyblock and mark them
586  * as checked.
587  */
588 static int
589 check_sigs( KBNODE keyblock )
590 {
591     KBNODE kbctx;
592     KBNODE node;
593     int rc;
594
595     for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
596         if( node->pkt->pkttype == PKT_SIGNATURE
597             && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
598             PKT_signature *sig = node->pkt->pkt.signature;
599
600             rc = check_key_signature( keyblock, node );
601             if( !rc )
602                 node->flag |= 1; /* mark signature valid */
603             if( DBG_TRUST )
604                 log_debug("trustdb: sig from %08lX: %s\n",
605                                                 rc? g10_errstr(rc): "okay" );
606         }
607     }
608     return 0;
609 }
610
611
612 /****************
613  * If we do not have sigrecs for the given key, build them and write them
614  * to the trustdb
615  */
616 static int
617 build_sigrecs( KBNODE keyblock )
618 {
619 }
620
621
622
623
624 /****************
625  * Recursive check the signatures.
626  */
627 static int
628 walk( KBNODE keyblock, int levels )
629 {
630     KBNODE kbctx, node;
631
632     check_sigs( keyblock );
633     if( levels ) { /* check the next level */
634         for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
635             if( node->pkt->pkttype == PKT_SIGNATURE && (node->flag & 1) ) {
636                 /* read the keyblock for this signator */
637
638                 /* and check his signatures */
639                 /*walk( his_keyblock, levels-1)*/
640             }
641         }
642     }
643
644 }
645
646
647
648
649
650 /****************
651  *
652  */
653 static int
654 check_trust()
655 {
656     /* check the ca
657
658 }
659
660
661
662 /*********************************************************
663  ****************  API Interface  ************************
664  *********************************************************/
665
666 /****************
667  * Perform some checks over the trustdb
668  *  level 0: used for initial program startup
669  */
670 int
671 check_trustdb( int level )
672 {
673     int rc=0;
674
675     if( !level ) {
676         char *fname = make_filename("~/.g10", "trustDB", NULL );
677         if( access( fname, R_OK ) ) {
678             if( errno != ENOENT ) {
679                 log_error("can't access %s: %s\n", fname, strerror(errno) );
680                 m_free(fname);
681                 return G10ERR_TRUSTDB;
682             }
683             create_db( fname );
684         }
685         m_free(db_name);
686         db_name = fname;
687
688         /* we can verify a signature about our local data (secring and trustdb)
689          * in ~/.g10/ here */
690         rc = verify_private_data();
691         if( !rc ) {
692             /* verify, that our own certificates are in the trustDB
693              * or move them to the trustdb. */
694             rc = verify_own_certs();
695
696             /* should we check wether there is no other ultimately trusted
697              * key in the database? */
698
699         }
700     }
701     else
702         log_bug(NULL);
703
704     return rc;
705 }
706
707
708 /****************
709  * Get the trustlevel for this PKC.
710  * Note: This does not ask any questions
711  * Returns: 0 okay of an errorcode
712  *
713  * It operates this way:
714  *  locate the pkc in the trustdb
715  *      found:
716  *          Do we have a valid cache record for it?
717  *              yes: return trustlevel from cache
718  *              no:  make a cache record and all the other stuff
719  *      not found:
720  *          Return with a trustlevel, saying that we do not have
721  *          a trust record for it. The caller may use insert_trust_record()
722  *          and then call this function here again.
723  *
724  * Problems: How do we get the complete keyblock to check that the
725  *           cache record is actually valid?  Think we need a clever
726  *           cache in getkey.c  to keep track of this stuff. Maybe it
727  *           is not necessary to check this if we use a local pubring. Hmmmm.
728  */
729 int
730 check_pkc_trust( PKT_public_cert *pkc, int *r_trustlevel )
731 {
732     TRUSTREC rec;
733     int trustlevel = 0;
734     int rc=0;
735
736     if( opt.verbose )
737         log_info("check_pkc_trust() called.\n");
738
739     /* get the pubkey record */
740     if( pkc->local_id ) {
741         if( read_record( pkc->local_id, &rec ) ) {
742             log_error("check_pkc_trust: read record failed\n");
743             return G10ERR_TRUSTDB;
744         }
745     }
746     else { /* no local_id: scan the trustdb */
747         if( (rc=scan_record_by_pkc( pkc, &rec, 2 )) && rc != -1 ) {
748             log_error("check_pkc_trust: scan_record_by_pkc(2) failed: %s\n",
749                                                             g10_errstr(rc));
750             return G10ERR_TRUSTDB;
751         }
752         else if( rc == -1 ) {
753             log_error("check_pkc_trust: pubkey not in TrustDB\n");
754             trustlevel = TRUST_NO_PUBKEY;
755             goto leave;
756         }
757     }
758     /* fixme: do some additional checks on the pubkey record */
759
760     /* see wether we have a cache record */
761
762
763   leave:
764     if( opt.verbose )
765         log_info("check_pkc_trust() returns trustlevel %04x.\n", trustlevel);
766     *r_trustlevel = trustlevel;
767     return 0;
768 }
769
770
771 /****************
772  * Insert a trust record into the TrustDB
773  * This function failes if this record already exists.
774  */
775 int
776 insert_trust_record( PKT_public_cert *pkc )
777 {
778     TRUSTREC rec;
779     u32 keyid[2];
780     u32 recnum;
781     byte *fingerprint;
782     size_t fingerlen;
783
784
785     if( DBG_TRUST )
786         log_debug("trustdb: insert_record\n");
787
788     assert( !pkc->local_id );
789
790     keyid_from_pkc( pkc, keyid );
791     fingerprint = fingerprint_from_pkc( pkc, &fingerlen );
792
793     /* FIXME: check that we do not have this record. */
794
795     recnum = new_local_id();
796     /* build record */
797     memset( &rec, 0, sizeof rec );
798     rec.rectype = 2; /* the pubkey record */
799     rec.r.pubkey.local_id = recnum;
800     rec.r.pubkey.keyid[0] = keyid[0];
801     rec.r.pubkey.keyid[1] = keyid[1];
802     rec.r.pubkey.algo = pkc->pubkey_algo;
803     memcpy(rec.r.pubkey.fingerprint, fingerprint, fingerlen );
804     rec.r.pubkey.ownertrust = 0;
805     if( write_record( recnum, &rec ) ) {
806         log_error("insert_trust_record: write failed\n");
807         return G10ERR_TRUSTDB;
808     }
809
810     pkc->local_id = recnum;
811
812     return 0;
813 }
814
815
816 int
817 update_trust_record( PKT_public_cert *pkc, int new_trust )
818 {
819     TRUSTREC rec;
820     u32 keyid[2];
821     u32 recnum;
822
823     if( DBG_TRUST )
824         log_debug("trustdb: update_record\n");
825
826     assert( pkc->local_id );
827
828     if( read_record( pkc->local_id, &rec ) ) {
829         log_error("update_trust_record: read failed\n");
830         return G10ERR_TRUSTDB;
831     }
832     /* check keyid, fingerprint etc ? */
833
834     rec.r.pubkey.ownertrust = 0;
835     if( write_record( recnum, &rec ) ) {
836         log_error("insert_trust_record: write failed\n");
837         return G10ERR_TRUSTDB;
838     }
839
840     return 0;
841 }
842
843
844 int
845 verify_private_data()
846 {
847     int rc = 0;
848     char *sigfile = make_filename("~/.g10", "sig", NULL );
849
850     if( access( sigfile, R_OK ) ) {
851         if( errno != ENOENT ) {
852             log_error("can't access %s: %s\n", sigfile, strerror(errno) );
853             rc = G10ERR_TRUSTDB;
854             goto leave;
855         }
856         log_info("private data signature missing; creating ...\n");
857         rc = sign_private_data();
858         if( rc ) {
859             log_error("error creating %s: %s\n", sigfile, g10_errstr(rc) );
860             goto leave;
861         }
862     }
863
864     /* FIXME: verify this signature */
865
866   leave:
867     m_free(sigfile);
868     return rc;
869 }
870
871
872 int
873 sign_private_data()
874 {
875     int rc;
876     char *sigfile = make_filename("~/.g10", "sig", NULL );
877     char *secring = make_filename("~/.g10", "secring.g10", NULL );
878     STRLIST list = NULL;
879
880     add_to_strlist( &list, db_name );
881     add_to_strlist( &list, secring );
882
883     rc = sign_file( list, 1, NULL, 0, NULL, sigfile);
884
885     m_free(sigfile);
886     m_free(secring);
887     free_strlist(list);
888     return rc;
889 }
890