2 * Copyright (C) 1998 Free Software Foundation, Inc.
4 * This file is part of GNUPG.
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.
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.
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
28 #include <sys/types.h>
46 #if MAX_FINGERPRINT_LEN > 20
47 #error Must change structure of trustdb
50 typedef struct local_id_info *LOCAL_ID_INFO;
51 struct local_id_info {
58 typedef struct trust_info TRUST_INFO;
65 typedef struct trust_seg_list *TRUST_SEG_LIST;
66 struct trust_seg_list {
68 int nseg; /* number of segmens */
70 TRUST_INFO seg[1]; /* segment list */
77 } ENUM_TRUST_WEB_CONTEXT;
80 static int walk_sigrecs( SIGREC_CONTEXT *c, int create );
82 static LOCAL_ID_INFO *new_lid_table(void);
83 static void release_lid_table( LOCAL_ID_INFO *tbl );
84 static int ins_lid_table_item( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
85 static int qry_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned *flag );
86 static void upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
88 static void print_user_id( const char *text, u32 *keyid );
89 static int do_list_path( TRUST_INFO *stack, int depth, int max_depth,
90 LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist );
91 static int update_sigs_by_lid( ulong lid );
93 static int list_sigs( ulong pubkey_id );
94 static int propagate_trust( TRUST_SEG_LIST tslist );
95 static int do_check( TRUSTREC *drec, unsigned *trustlevel );
98 /* a table used to keep track of ultimately trusted keys
99 * which are the ones from our secrings */
100 static LOCAL_ID_INFO *ultikey_table;
102 static ulong last_trust_web_key;
103 static TRUST_SEG_LIST last_trust_web_tslist;
106 #define HEXTOBIN(a) ( (a) >= '0' && (a) <= '9' ? ((a)-'0') : \
107 (a) >= 'A' && (a) <= 'F' ? ((a)-'A'+10) : ((a)-'a'+10))
109 /**********************************************
110 ************* list helpers *******************
111 **********************************************/
113 static LOCAL_ID_INFO *
116 return m_alloc_clear( 16 * sizeof(LOCAL_ID_INFO));
120 release_lid_table( LOCAL_ID_INFO *tbl )
125 for(i=0; i < 16; i++ ) {
126 for(a=tbl[i]; a; a = a2 ) {
135 * Add a new item to the table or return 1 if we already have this item
136 * fixme: maybe it's a good idea to take items from an unused item list.
139 ins_lid_table_item( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag )
143 for( a = tbl[lid & 0x0f]; a; a = a->next )
146 a = m_alloc( sizeof *a );
149 a->next = tbl[lid & 0x0f];
155 qry_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned *flag )
159 for( a = tbl[lid & 0x0f]; a; a = a->next )
160 if( a->lid == lid ) {
169 upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag )
173 for( a = tbl[lid & 0x0f]; a; a = a->next )
174 if( a->lid == lid ) {
182 * If we do not have a local_id in a signature packet, find the owner of
183 * the signature packet in our trustdb or insert them into the trustdb
186 set_signature_packets_lid( PKT_signature *sig )
188 PKT_public_key *pk = m_alloc_clear( sizeof *pk );
192 rc = get_pubkey( pk, sig->keyid );
195 if( !pk->local_id ) {
196 rc = tdbio_search_dir_bypk( pk, &rec );
198 rc = insert_trust_record( pk );
202 sig->local_id = pk->local_id;
205 free_public_key( pk );
212 * Return the keyid from the primary key identified by LID.
215 keyid_from_lid( ulong lid, u32 *keyid )
220 rc = tdbio_read_record( lid, &rec, RECTYPE_DIR );
222 log_error("error reading dir record for LID %lu: %s\n",
223 lid, g10_errstr(rc));
224 return G10ERR_TRUSTDB;
226 if( !rec.r.dir.keylist ) {
227 log_error("no primary key for LID %lu\n", lid );
228 return G10ERR_TRUSTDB;
230 rc = tdbio_read_record( rec.r.dir.keylist, &rec, RECTYPE_KEY );
232 log_error("error reading primary key for LID %lu: %s\n",
233 lid, g10_errstr(rc));
234 return G10ERR_TRUSTDB;
236 keyid_from_fingerprint( rec.r.key.fingerprint, rec.r.key.fingerprint_len,
243 * Walk through the signatures of a public key.
244 * The caller must provide a context structure, with all fields set
245 * to zero, but the local_id field set to the requested key;
246 * This function does not change this field. On return the context
247 * is filled with the local-id of the signature and the signature flag.
248 * No fields should be changed (clearing all fields and setting
249 * pubkeyid is okay to continue with an other pubkey)
250 * Returns: 0 - okay, -1 for eof (no more sigs) or any other errorcode
253 walk_sigrecs( SIGREC_CONTEXT *c, int create )
262 if( !c->ctl.init_done ) {
263 c->ctl.init_done = 1;
264 rc = tdbio_read_record( c->lid, r, RECTYPE_DIR );
266 log_error("LID %lu: error reading dir record: %s\n",
267 c->lid, g10_errstr(rc));
270 c->ctl.nextuid = r->r.dir.uidlist;
271 /* force a read (what a bad bad hack) */
272 c->ctl.index = SIGS_PER_RECORD;
276 /* need a loop to skip over deleted sigs */
278 if( c->ctl.index >= SIGS_PER_RECORD ) { /* read the record */
279 rnum = r->r.sig.next;
280 if( !rnum && c->ctl.nextuid ) { /* read next uid record */
281 rc = tdbio_read_record( c->ctl.nextuid, r, RECTYPE_UID );
283 log_error("error reading next uidrec: %s\n",
288 if( !r->r.uid.siglist && create ) {
289 rc = update_sigs_by_lid( c->lid );
291 if( rc == G10ERR_BAD_CERT )
292 rc = -1; /* maybe no selfsignature */
295 "error building sigs on the fly: %s\n",
296 c->lid, g10_errstr(rc) );
300 rc = tdbio_read_record( c->ctl.nextuid, r, RECTYPE_UID );
302 log_error("LID %lu: error re-reading uid record: %s\n",
303 c->lid, g10_errstr(rc));
307 c->ctl.nextuid = r->r.uid.next;
308 rnum = r->r.uid.siglist;
312 return -1; /* return eof */
314 rc = tdbio_read_record( rnum, r, RECTYPE_SIG );
316 log_error(_("error reading sigrec: %s\n"), g10_errstr(rc));
320 if( r->r.sig.lid != c->lid ) {
321 log_error(_("chained sigrec %lu has a wrong owner\n"), rnum );
323 return G10ERR_TRUSTDB;
327 } while( !r->r.sig.sig[c->ctl.index++].lid );
329 c->sig_lid = r->r.sig.sig[c->ctl.index-1].lid;
330 c->sig_flag = r->r.sig.sig[c->ctl.index-1].flag;
337 /***********************************************
338 ************* Trust stuff ******************
339 ***********************************************/
343 * Verify that all our public keys are in the trustDB.
349 void *enum_context = NULL;
350 PKT_secret_key *sk = m_alloc_clear( sizeof *sk );
351 PKT_public_key *pk = m_alloc_clear( sizeof *pk );
354 while( !(rc=enum_secret_keys( &enum_context, sk, 0 ) ) ) {
355 keyid_from_sk( sk, keyid );
358 log_debug("key %08lX: checking secret key\n", (ulong)keyid[1] );
360 /* see whether we can access the public key of this secret key */
361 memset( pk, 0, sizeof *pk );
362 rc = get_pubkey( pk, keyid );
364 log_error(_("key %08lX: secret key without public key\n"),
368 if( cmp_public_secret_key( pk, sk ) ) {
369 log_error(_("key %08lX: secret and public key don't match\n"),
375 /* make sure that the pubkey is in the trustdb */
376 rc = query_trust_record( pk );
377 if( rc == -1 ) { /* put it into the trustdb */
378 rc = insert_trust_record( pk );
380 log_error(_("key %08lX: can't put it into the trustdb\n"),
386 log_error(_("key %08lX: query record failed\n"), (ulong)keyid[1] );
392 log_debug("key %08lX.%lu: stored into ultikey_table\n",
393 (ulong)keyid[1], pk->local_id );
394 if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
395 log_error(_("key %08lX: already in ultikey_table\n"),
398 release_secret_key_parts( sk );
399 release_public_key_parts( pk );
402 log_error(_("enum_secret_keys failed: %s\n"), g10_errstr(rc) );
407 free_secret_key( sk );
408 free_public_key( pk );
414 print_user_id( const char *text, u32 *keyid )
419 p = get_user_id( keyid, &n );
421 fputs( text, stdout);
425 print_string( stdout, p, n, 0 );
432 print_keyid( FILE *fp, ulong lid )
435 if( keyid_from_lid( lid, ki ) )
436 fprintf(fp, "????????.%lu", lid );
438 fprintf(fp, "%08lX.%lu", (ulong)ki[1], lid );
442 print_trust( FILE *fp, unsigned trust )
446 case TRUST_UNKNOWN: c = 'o'; break;
447 case TRUST_EXPIRED: c = 'e'; break;
448 case TRUST_UNDEFINED: c = 'q'; break;
449 case TRUST_NEVER: c = 'n'; break;
450 case TRUST_MARGINAL: c = 'm'; break;
451 case TRUST_FULLY: c = 'f'; break;
452 case TRUST_ULTIMATE: c = 'u'; break;
453 default: fprintf(fp, "%02x", trust ); return;
458 /* (a non-recursive algorithm would be easier) */
460 do_list_sigs( ulong root, ulong pubkey, int depth,
461 LOCAL_ID_INFO *lids, unsigned *lineno )
467 memset( &sx, 0, sizeof sx );
470 rc = walk_sigrecs( &sx, 0 );
473 rc = keyid_from_lid( sx.sig_lid, keyid );
475 printf("%6u: %*s????????.%lu:%02x\n", *lineno, depth*4, "",
476 sx.sig_lid, sx.sig_flag );
480 printf("%6u: %*s%08lX.%lu:%02x ", *lineno, depth*4, "",
481 (ulong)keyid[1], sx.sig_lid, sx.sig_flag );
482 /* check whether we already checked this pubkey */
483 if( !qry_lid_table_flag( ultikey_table, sx.sig_lid, NULL ) ) {
484 print_user_id("[ultimately trusted]", keyid);
487 else if( sx.sig_lid == pubkey ) {
488 printf("[self-signature]\n");
491 else if( sx.sig_lid == root ) {
492 printf("[closed]\n");
495 else if( ins_lid_table_item( lids, sx.sig_lid, *lineno ) ) {
497 qry_lid_table_flag( lids, sx.sig_lid, &refline );
498 printf("[see line %u]\n", refline);
501 else if( depth+1 >= MAX_LIST_SIGS_DEPTH ) {
502 print_user_id( "[too deeply nested]", keyid );
506 print_user_id( "", keyid );
508 rc = do_list_sigs( root, sx.sig_lid, depth+1, lids, lineno );
514 return rc==-1? 0 : rc;
518 * List all signatures of a public key
521 list_sigs( ulong pubkey_id )
528 rc = keyid_from_lid( pubkey_id, keyid );
531 printf("Signatures of %08lX.%lu ", (ulong)keyid[1], pubkey_id );
532 print_user_id("", keyid);
533 printf("----------------------\n");
535 lids = new_lid_table();
536 rc = do_list_sigs( pubkey_id, pubkey_id, 0, lids, &lineno );
538 release_lid_table(lids);
543 * List all records of a public key
546 list_records( ulong lid )
549 TRUSTREC dr, ur, rec;
552 rc = tdbio_read_record( lid, &dr, RECTYPE_DIR );
554 log_error("lid %lu: read dir record failed: %s\n", lid, g10_errstr(rc));
557 tdbio_dump_record( &dr, stdout );
559 for( recno=dr.r.dir.keylist; recno; recno = rec.r.key.next ) {
560 rc = tdbio_read_record( recno, &rec, RECTYPE_KEY );
562 log_error("lid %lu: read key record failed: %s\n",
563 lid, g10_errstr(rc));
566 tdbio_dump_record( &rec, stdout );
569 for( recno=dr.r.dir.uidlist; recno; recno = ur.r.uid.next ) {
570 rc = tdbio_read_record( recno, &ur, RECTYPE_UID );
572 log_error("lid %lu: read uid record failed: %s\n",
573 lid, g10_errstr(rc));
576 tdbio_dump_record( &ur, stdout );
577 /* preference records */
578 for(recno=ur.r.uid.prefrec; recno; recno = rec.r.pref.next ) {
579 rc = tdbio_read_record( recno, &rec, RECTYPE_PREF );
581 log_error("lid %lu: read pref record failed: %s\n",
582 lid, g10_errstr(rc));
585 tdbio_dump_record( &rec, stdout );
588 for(recno=ur.r.uid.siglist; recno; recno = rec.r.sig.next ) {
589 rc = tdbio_read_record( recno, &rec, RECTYPE_SIG );
591 log_error("lid %lu: read sig record failed: %s\n",
592 lid, g10_errstr(rc));
595 tdbio_dump_record( &rec, stdout );
599 /* add cache record dump here */
609 * Function to collect all trustpaths
612 do_list_path( TRUST_INFO *stack, int depth, int max_depth,
613 LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist )
621 /*printf("%2lu/%d: scrutinizig\n", stack[depth-1], depth);*/
622 if( depth >= max_depth || depth >= MAX_LIST_SIGS_DEPTH-1 ) {
623 /*printf("%2lu/%d: too deeply nested\n", stack[depth-1], depth);*/
626 memset( &sx, 0, sizeof sx );
627 sx.lid = stack[depth-1].lid;
628 /* loop over all signatures. If we do not have any, try to create them */
629 while( !(rc = walk_sigrecs( &sx, 1 )) ) {
630 TRUST_SEG_LIST tsl, t2, tl;
633 stack[depth].lid = sx.sig_lid;
634 stack[depth].trust = 0;
635 if( qry_lid_table_flag( lids, sx.sig_lid, &last_depth) ) {
636 /*printf("%2lu/%d: marked\n", sx.sig_lid, depth );*/
637 ins_lid_table_item( lids, sx.sig_lid, depth);
640 else if( depth < last_depth ) {
641 /*printf("%2lu/%d: last_depth=%u - updated\n", sx.sig_lid, depth, last_depth);*/
643 upd_lid_table_flag( lids, sx.sig_lid, depth);
646 if( last_depth < depth )
647 /*printf("%2lu/%d: already visited\n", sx.sig_lid, depth)*/;
648 else if( !qry_lid_table_flag( ultikey_table, sx.sig_lid, NULL ) ) {
649 /* found end of path; store it, ordered by path length */
650 tsl = m_alloc( sizeof *tsl + depth*sizeof(TRUST_INFO) );
653 for(i=0; i <= depth; i++ )
654 tsl->seg[i] = stack[i];
655 for(t2=*tslist,tl=NULL; t2; tl=t2, t2 = t2->next )
656 if( depth < t2->nseg )
666 /*putchar('.'); fflush(stdout);*/
667 /*printf("%2lu/%d: found\n", sx.sig_lid, depth);*/
670 rc = do_list_path( stack, depth+1, max_depth, lids, tslist);
675 return rc==-1? 0 : rc;
680 * find the uid record given the uid packet and the dir-record.
682 * -1 = No such uid-record
686 find_urec( TRUSTREC *dir, PKT_user_id *uid, TRUSTREC *urec )
692 assert(dir->rectype == RECTYPE_DIR );
693 rmd160_hash_buffer( nhash, uid->name, uid->len );
694 for( recno=dir->r.dir.uidlist; recno; recno = urec->r.uid.next ) {
695 rc = tdbio_read_record( recno, urec, RECTYPE_UID );
697 return rc == -1 ? G10ERR_READ_FILE : rc;
698 if( !memcmp( nhash, urec->r.uid.namehash, 20 ) )
707 * Test whether zthe signature lid is already in the (in mem) list.
708 * Returns: True if it is a duplicate
711 test_dupsig( TRUSTREC *rec, ulong lid )
716 for( ; rec; rec = rec->next ) {
717 for(i=0; i < SIGS_PER_RECORD && (alid = rec->r.sig.sig[i].lid); i++ )
726 * release the sigrec from the uidlist
729 rel_uidsigs( TRUSTREC *urec )
732 assert( urec->rectype == RECTYPE_UID );
734 for(rec=urec->next ; rec; rec = r2 ) {
735 assert( rec->rectype == RECTYPE_SIG );
743 no_selfsig_del( ulong lid, u32 *keyid, TRUSTREC *urec )
747 log_error("key %08lX.%lu, uid %02X%02X: "
748 "no self-signature - user id removed\n",
749 (ulong)keyid[1], lid, urec->r.uid.namehash[18],
750 urec->r.uid.namehash[19] );
752 rc = tdbio_delete_uidrec( lid, urec->recnum );
754 log_error("no_selfsig_del: delete_uid %lu failed: %s\n",
755 lid, g10_errstr(rc) );
760 * Write the signature records from the in-mem list at urec
761 * (The sequence of signatures does not matter)
764 write_sigs_from_urec( ulong lid, u32 *keyid, TRUSTREC *urec )
771 nextrecno = urec->r.uid.siglist;
772 urec->r.uid.siglist = 0; /* end of list marker */
773 for( rec = urec->next; rec; rec = rec->next ) {
774 assert( rec->rectype == RECTYPE_SIG );
775 if( nextrecno ) { /* read the sig record, so it can be reused */
776 rc = tdbio_read_record( nextrecno, &srec, RECTYPE_SIG );
778 log_error("write_sig_from_urec: read sigrecno %lu failed: %s\n",
779 nextrecno, g10_errstr(rc) );
783 nextrecno = srec.r.sig.next;
786 recno = tdbio_new_recnum();
788 /* link together (the sequence of signatures does not matter) */
789 rec->r.sig.next = urec->r.uid.siglist;
790 urec->r.uid.siglist = recno;
791 rec->r.sig.lid = lid;
794 rc = tdbio_write_record( rec );
796 log_error("write_sig_from_urec: write sigrecno %lu failed: %s\n",
797 recno, g10_errstr(rc) );
802 /* write the urec back */
803 rc = tdbio_write_record( urec );
805 log_error("write_sig_from_urec: write urec %lu failed: %s\n",
806 urec->recnum, g10_errstr(rc) );
810 /* delete remaining old sigrecords */
812 rc = tdbio_read_record( nextrecno, &srec, RECTYPE_SIG );
814 log_error("write_sig_from_urec: read sigrecno %lu failed: %s\n",
815 nextrecno, g10_errstr(rc) );
818 rc = tdbio_delete_record( nextrecno );
820 log_error("write_sig_from_urec: delete old %lu failed: %s\n",
821 nextrecno, g10_errstr(rc) );
825 nextrecno = srec.r.sig.next;
832 * If we do not have sigrecs for the given key, build them and write them
836 update_sigs( TRUSTREC *dir )
840 TRUSTREC *sigrec_list;
841 KBNODE keyblock = NULL;
843 int i, sigidx, have_urec ;
844 ulong lid = dir->r.dir.lid;
850 log_debug("update_sigs for %lu\n", lid );
852 if( (rc=tdbio_read_record( dir->r.dir.keylist, &krec, RECTYPE_KEY )) ) {
853 log_error("update_sigs: can't read primary key for %lu\n", lid);
856 rc = get_keyblock_byfprint( &keyblock, krec.r.key.fingerprint,
857 krec.r.key.fingerprint_len );
859 log_error( "update_sigs: keyblock for %lu not found: %s\n",
860 lid, g10_errstr(rc) );
864 /* check all key signatures */
865 assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
869 for( node=keyblock; node; node = node->next ) {
870 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
871 keyid_from_pk( node->pkt->pkt.public_key, keyid );
872 else if( node->pkt->pkttype == PKT_USER_ID ) {
873 if( have_urec && !(urec.mark & 1) ) {
874 if( (rc = no_selfsig_del(lid, keyid, &urec )) )
879 rc = write_sigs_from_urec( lid, keyid, &urec );
882 rel_uidsigs( &urec );
884 rc = find_urec( dir, node->pkt->pkt.user_id, &urec );
887 have_urec = sigidx = 0;
889 log_info("update_sigs: new user id for %lu\n", lid );
890 /* fixme: we should add the new user id here */
893 log_error("update_sigs: find_urec %lu failed: %s\n",
894 lid, g10_errstr(rc) );
900 else if( have_urec && node->pkt->pkttype == PKT_SIGNATURE ) {
901 PKT_signature *sig = node->pkt->pkt.signature;
903 if( (sig->sig_class&~3) == 0x10 ) {
904 rc = check_key_signature( keyblock, node, &i );
905 if( rc == G10ERR_NO_PUBKEY ) {
906 log_info("key %08lX.%lu, uid %02X%02X: "
907 "no public key for signature %08lX\n",
908 (ulong)keyid[1], lid, urec.r.uid.namehash[18],
909 urec.r.uid.namehash[19], (ulong)sig->keyid[1] );
913 log_error("key %08lX.%lu, uid %02X%02X: "
914 "invalid %ssignature: %s\n",
915 (ulong)keyid[1], lid, urec.r.uid.namehash[18],
916 urec.r.uid.namehash[19],
917 i?"self-":"",g10_errstr(rc));
918 else if( i ) /* mark that we have a valid selfsignature */
920 else if( (rc = set_signature_packets_lid( sig )) )
921 log_error("key %08lX.%lu, uid %02X%02X: "
922 "can't get LID of signer: %s\n",
923 (ulong)keyid[1], lid, urec.r.uid.namehash[18],
924 urec.r.uid.namehash[19], g10_errstr(rc));
925 else if( !test_dupsig( urec.next, sig->local_id ) ) {
926 /* put the valid signature into a list */
928 if( !rec || sigidx == SIGS_PER_RECORD ) {
929 rec = m_alloc_clear( sizeof *rec );
930 rec->rectype = RECTYPE_SIG;
931 rec->next = urec.next;
935 rec->r.sig.sig[sigidx].lid = sig->local_id;
936 rec->r.sig.sig[sigidx].flag = 0;
939 log_debug("key %08lX.%lu, uid %02X%02X: "
940 "signed by LID %lu\n",
941 (ulong)keyid[1], lid, urec.r.uid.namehash[18],
942 urec.r.uid.namehash[19], sig->local_id);
945 log_debug("key %08lX.%lu, uid %02X%02X: "
946 "duplicate signature by LID %lu\n",
947 (ulong)keyid[1], lid, urec.r.uid.namehash[18],
948 urec.r.uid.namehash[19], sig->local_id );
952 /* fixme: handle other sig classes here */
953 /* FIXME: Revocations!!! */
957 if( have_urec && !(urec.mark & 1) ) {
958 if( (rc = no_selfsig_del(lid, keyid, &urec )) )
963 rc = write_sigs_from_urec( lid, keyid, &urec );
966 rel_uidsigs( &urec );
968 dir->r.dir.dirflags |= DIRF_CHECKED;
970 dir->r.dir.dirflags |= DIRF_MISKEY;
972 dir->r.dir.dirflags &= ~DIRF_MISKEY;
973 rc = tdbio_write_record( dir );
975 log_error("update_sigs: write dir record failed: %s\n", g10_errstr(rc));
980 /* fixme: need more cleanup in case of an error */
981 release_kbnode( keyblock );
983 log_debug("update_sigs for %lu: %s\n", lid, g10_errstr(rc) );
989 update_sigs_by_lid( ulong lid )
994 rc = tdbio_read_record( lid, &rec, RECTYPE_DIR );
996 log_error("LID %lu: error reading dir record: %s\n",
997 lid, g10_errstr(rc));
1000 if( !(rec.r.dir.dirflags & DIRF_CHECKED) )
1001 rc = update_sigs( &rec );
1006 * Make a list of trust paths
1009 make_tsl( ulong lid, TRUST_SEG_LIST *ret_tslist )
1012 LOCAL_ID_INFO *lids = new_lid_table();
1013 TRUST_INFO stack[MAX_LIST_SIGS_DEPTH];
1014 TRUST_SEG_LIST tsl, tslist;
1017 tslist = *ret_tslist = NULL;
1019 if( !qry_lid_table_flag( ultikey_table, lid, NULL ) ) {
1020 tslist = m_alloc( sizeof *tslist );
1023 tslist->seg[0].lid = lid;
1024 tslist->seg[0].trust = 0;
1025 tslist->next = NULL;
1031 rc = do_list_path( stack, 1, max_depth, lids, &tslist );
1033 if( !rc ) { /* wipe out duplicates */
1034 LOCAL_ID_INFO *work = new_lid_table();
1035 for( tsl=tslist; tsl; tsl = tsl->next ) {
1036 for(i=1; i < tsl->nseg-1; i++ ) {
1037 if( ins_lid_table_item( work, tsl->seg[i].lid, 0 ) ) {
1038 tsl->dup = 1; /* mark as duplicate */
1043 release_lid_table(work);
1044 *ret_tslist = tslist;
1047 ; /* FIXME: release tslist */
1048 release_lid_table(lids);
1054 * Given a trust segment list tslist, walk over all paths and fill in
1055 * the trust information for each segment. What this function does is
1056 * to assign a trustvalue to the first segment (which is the requested key)
1059 * FIXME: We have to do more thinking here. e.g. we should never increase
1062 * Do not do it for duplicates.
1065 propagate_trust( TRUST_SEG_LIST tslist )
1071 for(tsl = tslist; tsl; tsl = tsl->next ) {
1074 assert( tsl->nseg );
1075 /* the last segment is always an ultimately trusted one, so we can
1076 * assign a fully trust to the next one */
1078 tsl->seg[i].trust = TRUST_ULTIMATE;
1079 trust = TRUST_FULLY;
1080 for(i-- ; i >= 0; i-- ) {
1081 tsl->seg[i].trust = trust;
1083 /* get the trust of this pubkey */
1084 rc = get_ownertrust( tsl->seg[i].lid, &tr );
1097 * we have the pubkey record and all needed informations are in the trustdb
1098 * but nothing more is known.
1099 * (this function may re-read the dir record dr)
1102 do_check( TRUSTREC *dr, unsigned *trustlevel )
1105 TRUST_SEG_LIST tsl, tsl2, tslist;
1106 int marginal, fully;
1107 int fully_needed = opt.completes_needed;
1108 int marginal_needed = opt.marginals_needed;
1109 unsigned tflags = 0;
1111 assert( fully_needed > 0 && marginal_needed > 1 );
1114 *trustlevel = TRUST_UNDEFINED;
1116 if( !dr->r.dir.keylist ) {
1117 log_error("Ooops, no keys\n");
1118 return G10ERR_TRUSTDB;
1120 if( !dr->r.dir.uidlist ) {
1121 log_error("Ooops, no user ids\n");
1122 return G10ERR_TRUSTDB;
1125 /* did we already check the signatures */
1126 if( !(dr->r.dir.dirflags & DIRF_CHECKED) ) /* no - do it now */
1127 rc = update_sigs( dr );
1129 if( dr->r.dir.dirflags & DIRF_REVOKED )
1130 tflags |= TRUST_FLAG_REVOKED;
1133 if( !rc && !dr->r.dir.siglist ) {
1134 /* We do not have any signatures; check whether it is one of our
1136 if( !qry_lid_table_flag( ultikey_table, dr->r.dir.lid, NULL ) )
1137 *trustlevel = tflags | TRUST_ULTIMATE;
1142 return rc; /* error while looking for sigrec or building sigrecs */
1144 /* fixme: take it from the cache if it is valid */
1146 /* Make a list of all possible trust-paths */
1147 rc = make_tsl( dr->r.dir.lid, &tslist );
1150 rc = propagate_trust( tslist );
1153 for(tsl = tslist; tsl; tsl = tsl->next ) {
1158 log_info("trust path:" );
1159 for(i=0; i < tsl->nseg; i++ ) {
1161 print_keyid( stderr, tsl->seg[i].lid );
1163 print_trust( stderr, tsl->seg[i].trust );
1169 /* and see whether there is a trusted path.
1170 * We only have to look at the first segment, because
1171 * propagate_trust has investigated all other segments */
1172 marginal = fully = 0;
1173 for(tsl = tslist; tsl; tsl = tsl->next ) {
1176 if( tsl->seg[0].trust == TRUST_ULTIMATE ) {
1177 *trustlevel = tflags | TRUST_ULTIMATE; /* our own key */
1180 if( tsl->seg[0].trust == TRUST_FULLY ) {
1184 else if( tsl->seg[0].trust == TRUST_MARGINAL )
1187 if( fully >= fully_needed ) {
1188 *trustlevel = tflags | TRUST_FULLY;
1192 if( !tsl && marginal >= marginal_needed )
1193 *trustlevel = tflags | TRUST_MARGINAL;
1195 /* cache the tslist */
1196 if( last_trust_web_key ) {
1197 for( tsl = last_trust_web_tslist; tsl; tsl = tsl2 ) {
1202 last_trust_web_key = dr->r.dir.lid;
1203 last_trust_web_tslist = tslist;
1208 /***********************************************
1209 **************** API ************************
1210 ***********************************************/
1213 * Perform some checks over the trustdb
1214 * level 0: only open the db
1215 * 1: used for initial program startup
1218 init_trustdb( int level, const char *dbname )
1222 if( !ultikey_table )
1223 ultikey_table = new_lid_table();
1225 if( !level || level==1 ) {
1226 rc = tdbio_set_dbname( dbname, !!level );
1232 /* verify that our own keys are in the trustDB
1233 * or move them to the trustdb. */
1234 rc = verify_own_keys();
1236 /* should we check whether there is no other ultimately trusted
1237 * key in the database? */
1248 list_trustdb( const char *username )
1252 if( username && *username == '#' ) {
1254 ulong lid = atoi(username+1);
1256 if( (rc = list_records( lid)) )
1257 log_error("user '%s' read problem: %s\n", username, g10_errstr(rc));
1258 else if( (rc = list_sigs( lid )) )
1259 log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
1261 else if( username ) {
1262 PKT_public_key *pk = m_alloc_clear( sizeof *pk );
1265 if( (rc = get_pubkey_byname( pk, username )) )
1266 log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
1267 else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
1268 log_error("problem finding '%s' in trustdb: %s\n",
1269 username, g10_errstr(rc));
1271 log_error("user '%s' not in trustdb\n", username);
1272 else if( (rc = list_records( pk->local_id)) )
1273 log_error("user '%s' read problem: %s\n", username, g10_errstr(rc));
1274 else if( (rc = list_sigs( pk->local_id )) )
1275 log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
1276 free_public_key( pk );
1282 printf("TrustDB: %s\n", tdbio_get_dbname() );
1283 for(i=9+strlen(tdbio_get_dbname()); i > 0; i-- )
1286 for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ )
1287 tdbio_dump_record( &rec, stdout );
1292 * Print a list of all defined owner trust value.
1304 for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
1305 if( rec.rectype == RECTYPE_DIR ) {
1306 if( !rec.r.dir.keylist ) {
1307 log_error("Oops; directory record w/o primary key\n");
1310 if( !rec.r.dir.ownertrust )
1312 rc = tdbio_read_record( rec.r.dir.keylist, &rec2, RECTYPE_KEY);
1314 log_error("error reading key record: %s\n", g10_errstr(rc));
1317 p = rec2.r.key.fingerprint;
1318 for(i=0; i < rec2.r.key.fingerprint_len; i++, p++ )
1319 printf("%02X", *p );
1320 printf(":%u:\n", (unsigned)rec.r.dir.ownertrust );
1327 import_ownertrust( const char *fname )
1336 if( !fname || (*fname == '-' && !fname[1]) ) {
1341 else if( !(fp = fopen( fname, "r" )) ) {
1342 log_error_f(fname, _("can't open file: %s\n"), strerror(errno) );
1346 while( fgets( line, DIM(line)-1, fp ) ) {
1350 if( !*line || *line == '#' )
1353 if( line[n-1] != '\n' ) {
1354 log_error_f(fname, "line to long\n" );
1355 break; /* can't continue */
1357 for(p = line; *p && *p != ':' ; p++ )
1361 log_error_f(fname, "error: missing colon\n" );
1365 if( fprlen != 32 && fprlen != 40 ) {
1366 log_error_f(fname, "error: invalid fingerprint\n" );
1369 if( sscanf(p, ":%u:", &otrust ) != 1 ) {
1370 log_error_f(fname, "error: no otrust value\n" );
1374 continue; /* no otrust defined - no need to update or insert */
1375 /* convert the ascii fingerprint to binary */
1376 for(p=line, fprlen=0; *p != ':'; p += 2 )
1377 line[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]);
1381 rc = tdbio_search_dir_byfpr( line, fprlen, 0, &rec );
1382 if( !rc ) { /* found: update */
1383 if( rec.r.dir.ownertrust )
1384 log_info("LID %lu: changing trust from %u to %u\n",
1385 rec.r.dir.lid, rec.r.dir.ownertrust, otrust );
1387 log_info("LID %lu: setting trust to %u\n",
1388 rec.r.dir.lid, otrust );
1389 rec.r.dir.ownertrust = otrust;
1390 rc = tdbio_write_record( &rec );
1392 log_error_f(fname, "error updating otrust: %s\n",
1395 else if( rc == -1 ) { /* not found; get the key from the ring */
1396 PKT_public_key *pk = m_alloc_clear( sizeof *pk );
1398 log_info_f(fname, "key not in trustdb, searching ring.\n");
1399 rc = get_pubkey_byfprint( pk, line, fprlen );
1401 log_info_f(fname, "key not in ring: %s\n", g10_errstr(rc));
1403 rc = query_trust_record( pk ); /* only as assertion */
1405 log_error_f(fname, "Oops: key is now in trustdb???\n");
1407 rc = insert_trust_record( pk );
1409 goto repeat; /* update the ownertrust */
1410 log_error_f(fname, "insert trust record failed: %s\n",
1416 log_error_f(fname, "error finding dir record: %s\n",
1420 log_error_f(fname, _("read error: %s\n"), strerror(errno) );
1427 list_trust_path( int max_depth, const char *username )
1433 PKT_public_key *pk = m_alloc_clear( sizeof *pk );
1435 if( max_depth < 0 ) {
1437 max_depth = -max_depth;
1440 if( (rc = get_pubkey_byname( pk, username )) )
1441 log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
1442 else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
1443 log_error("problem finding '%s' in trustdb: %s\n",
1444 username, g10_errstr(rc));
1445 else if( rc == -1 ) {
1446 log_info("user '%s' not in trustdb - inserting\n", username);
1447 rc = insert_trust_record( pk );
1449 log_error("failed to put '%s' into trustdb: %s\n", username, g10_errstr(rc));
1451 assert( pk->local_id );
1456 TRUST_SEG_LIST tsl, tslist = NULL;
1458 if( !qry_lid_table_flag( ultikey_table, pk->local_id, NULL ) ) {
1459 tslist = m_alloc( sizeof *tslist );
1462 tslist->seg[0].lid = pk->local_id;
1463 tslist->seg[0].trust = 0;
1464 tslist->next = NULL;
1468 LOCAL_ID_INFO *lids = new_lid_table();
1469 TRUST_INFO stack[MAX_LIST_SIGS_DEPTH];
1471 stack[0].lid = pk->local_id;
1473 rc = do_list_path( stack, 1, max_depth, lids, &tslist );
1474 if( wipe ) { /* wipe out duplicates */
1475 LOCAL_ID_INFO *work;
1477 work = new_lid_table();
1478 for( tsl=tslist; tsl; tsl = tsl->next ) {
1479 for(i=1; i < tsl->nseg-1; i++ ) {
1480 if( ins_lid_table_item( work, tsl->seg[i].lid, 0 ) ) {
1481 tsl->dup = 1; /* mark as duplicate */
1486 release_lid_table(work);
1488 release_lid_table(lids);
1491 log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
1492 rc = propagate_trust( tslist );
1494 log_error("user '%s' trust problem: %s\n", username, g10_errstr(rc));
1495 for(tsl = tslist; tsl; tsl = tsl->next ) {
1500 printf("trust path:" );
1501 for(i=0; i < tsl->nseg; i++ ) {
1503 print_keyid( stdout, tsl->seg[i].lid );
1505 print_trust( stdout, tsl->seg[i].trust );
1511 free_public_key( pk );
1516 * Check the complete trustdb or only the entries for the given username
1519 check_trustdb( const char *username )
1524 if( username && *username == '#' ) {
1526 ulong lid = atoi(username+1);
1528 if( (rc = update_sigs_by_lid( lid )) )
1529 log_error("lid %lu: check failed: %s\n",
1530 lid, g10_errstr(rc));
1532 log_info("lid %lu: checked: %s\n", lid, g10_errstr(rc));
1534 else if( username ) {
1535 PKT_public_key *pk = m_alloc_clear( sizeof *pk );
1537 if( (rc = get_pubkey_byname( pk, username )) )
1538 log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
1539 else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
1540 log_error("problem finding '%s' in trustdb: %s\n",
1541 username, g10_errstr(rc));
1543 log_error("user '%s' not in trustdb\n", username);
1544 else if( (rc = update_sigs( &rec )) )
1545 log_error("lid %lu: check failed: %s\n",
1546 rec.recnum, g10_errstr(rc));
1548 log_info("lid %lu: checked: %s\n", rec.recnum, g10_errstr(rc));
1549 free_public_key( pk );
1554 for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
1555 if( rec.rectype == RECTYPE_DIR ) {
1556 rc = update_sigs( &rec );
1558 log_error("lid %lu: check failed: %s\n",
1559 recnum, g10_errstr(rc) );
1561 log_info("lid %lu: checked\n", recnum );
1568 * Get the trustlevel for this PK.
1569 * Note: This does not ask any questions
1570 * Returns: 0 okay of an errorcode
1572 * It operates this way:
1573 * locate the pk in the trustdb
1575 * Do we have a valid cache record for it?
1576 * yes: return trustlevel from cache
1577 * no: make a cache record and all the other stuff
1579 * try to insert the pubkey into the trustdb and check again
1581 * Problems: How do we get the complete keyblock to check that the
1582 * cache record is actually valid? Think we need a clever
1583 * cache in getkey.c to keep track of this stuff. Maybe it
1584 * is not necessary to check this if we use a local pubring. Hmmmm.
1587 check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
1590 unsigned trustlevel = TRUST_UNKNOWN;
1596 keyid_from_pk( pk, keyid );
1598 /* get the pubkey record */
1599 if( pk->local_id ) {
1600 if( tdbio_read_record( pk->local_id, &rec, RECTYPE_DIR ) ) {
1601 log_error("check_trust: read dir record failed\n");
1602 return G10ERR_TRUSTDB;
1605 else { /* no local_id: scan the trustdb */
1606 if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) {
1607 log_error("check_trust: search dir record failed: %s\n",
1611 else if( rc == -1 ) { /* not found - insert */
1612 rc = insert_trust_record( pk );
1614 log_error(_("key %08lX: insert trust record failed: %s\n"),
1615 keyid[1], g10_errstr(rc));
1618 log_info(_("key %08lX.%lu: inserted into trustdb\n"),
1619 keyid[1], pk->local_id );
1620 /* and re-read the dir record */
1621 if( tdbio_read_record( pk->local_id, &rec, RECTYPE_DIR ) ) {
1622 log_error("check_trust: reread dir record failed\n");
1623 return G10ERR_TRUSTDB;
1627 cur_time = make_timestamp();
1628 if( pk->timestamp > cur_time ) {
1629 log_info(_("key %08lX.%lu: created in future "
1630 "(time warp or clock problem)\n"),
1631 keyid[1], pk->local_id );
1632 return G10ERR_TIME_CONFLICT;
1635 if( pk->valid_days && add_days_to_timestamp(pk->timestamp,
1636 pk->valid_days) < cur_time ) {
1637 log_info(_("key %08lX.%lu: expired at %s\n"),
1638 keyid[1], pk->local_id,
1639 strtimestamp( add_days_to_timestamp(pk->timestamp,
1641 trustlevel = TRUST_EXPIRED;
1644 rc = do_check( &rec, &trustlevel );
1646 log_error(_("key %08lX.%lu: trust check failed: %s\n"),
1647 keyid[1], pk->local_id, g10_errstr(rc));
1655 log_debug("check_trust() returns trustlevel %04x.\n", trustlevel);
1656 *r_trustlevel = trustlevel;
1662 query_trust_info( PKT_public_key *pk )
1664 unsigned trustlevel;
1667 if( check_trust( pk, &trustlevel ) )
1669 if( trustlevel & TRUST_FLAG_REVOKED )
1671 switch( (trustlevel & TRUST_MASK) ) {
1672 case TRUST_UNKNOWN: c = 'o'; break;
1673 case TRUST_EXPIRED: c = 'e'; break;
1674 case TRUST_UNDEFINED: c = 'q'; break;
1675 case TRUST_NEVER: c = 'n'; break;
1676 case TRUST_MARGINAL: c = 'm'; break;
1677 case TRUST_FULLY: c = 'f'; break;
1678 case TRUST_ULTIMATE: c = 'u'; break;
1687 * Enumerate all keys, which are needed to build all trust paths for
1688 * the given key. This function does not return the key itself or
1691 * 1) create a void pointer and initialize it to NULL
1692 * 2) pass this void pointer by reference to this function.
1693 * Set lid to the key you want to enumerate and pass it by reference.
1694 * 3) call this function as long as it does not return -1
1695 * to indicate EOF. LID does contain the next key used to build the web
1696 * 4) Always call this function a last time with LID set to NULL,
1697 * so that it can free its context.
1700 enum_trust_web( void **context, ulong *lid )
1702 ENUM_TRUST_WEB_CONTEXT *c = *context;
1704 if( !c ) { /* make a new context */
1705 c = m_alloc_clear( sizeof *c );
1707 if( *lid != last_trust_web_key && last_trust_web_key )
1708 log_bug("enum_trust_web: nyi\n"); /* <--- FIXME */
1709 c->tsl = last_trust_web_tslist;
1713 if( !lid ) { /* free the context */
1720 if( !c->tsl->dup && c->index < c->tsl->nseg-1 ) {
1721 *lid = c->tsl->seg[c->index].lid;
1726 c->tsl = c->tsl->next;
1728 return -1; /* eof */
1733 * Return the assigned ownertrust value for the given LID
1736 get_ownertrust( ulong lid, unsigned *r_otrust )
1740 if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
1741 log_error("get_ownertrust: read dir record failed\n");
1742 return G10ERR_TRUSTDB;
1745 *r_otrust = rec.r.dir.ownertrust;
1750 get_ownertrust_info( ulong lid )
1755 if( get_ownertrust( lid, &otrust ) )
1757 switch( (otrust & TRUST_MASK) ) {
1758 case TRUST_NEVER: c = 'n'; break;
1759 case TRUST_MARGINAL: c = 'm'; break;
1760 case TRUST_FULLY: c = 'f'; break;
1761 case TRUST_ULTIMATE: c = 'u'; break;
1762 default: c = '-'; break;
1769 get_pref_data( ulong lid, const byte *namehash, size_t *ret_n )
1775 if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
1776 log_error("get_pref_data: read dir record failed\n");
1780 for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
1781 rc = tdbio_read_record( recno, &rec, RECTYPE_UID );
1783 log_error("get_pref_data: read uid record failed: %s\n",
1787 if( rec.r.uid.prefrec
1788 && ( !namehash || !memcmp(namehash, rec.r.uid.namehash, 20) )) {
1790 /* found the correct one or the first one */
1791 rc = tdbio_read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
1793 log_error("get_pref_data: read pref record failed: %s\n",
1797 if( rec.r.pref.next )
1798 log_info("warning: can't yet handle long pref records\n");
1799 buf = m_alloc( ITEMS_PER_PREF_RECORD );
1800 memcpy( buf, rec.r.pref.data, ITEMS_PER_PREF_RECORD );
1801 *ret_n = ITEMS_PER_PREF_RECORD;
1811 * Check whether the algorithm is in one of the pref records
1814 is_algo_in_prefs( ulong lid, int preftype, int algo )
1821 if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
1822 log_error("is_algo_in_prefs: read dir record failed\n");
1826 for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
1827 rc = tdbio_read_record( recno, &rec, RECTYPE_UID );
1829 log_error("is_algo_in_prefs: read uid record failed: %s\n",
1833 if( rec.r.uid.prefrec ) {
1834 rc = tdbio_read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
1836 log_error("is_algo_in_prefs: read pref record failed: %s\n",
1840 if( rec.r.pref.next )
1841 log_info("warning: can't yet handle long pref records\n");
1842 pref = rec.r.pref.data;
1843 for(i=0; i+1 < ITEMS_PER_PREF_RECORD; i+=2 ) {
1844 if( pref[i] == preftype && pref[i+1] == algo )
1854 * This function simply looks for the key in the trustdb
1855 * and makes sure that pk->local_id is set to the coreect value.
1861 query_trust_record( PKT_public_key *pk )
1866 if( pk->local_id ) {
1867 if( tdbio_read_record( pk->local_id, &rec, RECTYPE_DIR ) ) {
1868 log_error("query_trust_record: read record failed\n");
1869 return G10ERR_TRUSTDB;
1872 else { /* no local_id: scan the trustdb */
1873 if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) {
1874 log_error("query_trust_record: search_record failed: %s\n",
1885 * helper function for insert_trust_record()
1888 rel_mem_uidnode( u32 *keyid, int err, TRUSTREC *rec )
1893 log_error("key %08lX, uid %02X%02X: invalid user id - removed\n",
1894 (ulong)keyid[1], rec->r.uid.namehash[18], rec->r.uid.namehash[19] );
1895 for(r=rec->help_pref; r; r = r2 ) {
1905 * Insert a trust record into the TrustDB
1906 * This function fails if this record already exists.
1908 * We build everything we can do at this point. We cannot build
1909 * the sig records, because their LIDs are needed and we may not have them.
1912 insert_trust_record( PKT_public_key *orig_pk )
1914 TRUSTREC dirrec, *rec, *rec2;
1915 TRUSTREC *keylist_head, **keylist_tail, *keylist;
1916 TRUSTREC *uidlist_head, **uidlist_tail, *uidlist;
1917 KBNODE keyblock = NULL;
1919 u32 keyid[2]; /* of primary key */
1924 keylist_head = NULL; keylist_tail = &keylist_head; keylist = NULL;
1925 uidlist_head = NULL; uidlist_tail = &uidlist_head; uidlist = NULL;
1927 /* prepare dir record */
1928 memset( &dirrec, 0, sizeof dirrec );
1929 dirrec.rectype = RECTYPE_DIR;
1931 if( orig_pk->local_id )
1932 log_bug("pk->local_id=%lu\n", (ulong)orig_pk->local_id );
1934 fingerprint = fingerprint_from_pk( orig_pk, NULL, &fingerlen );
1936 /* fixme: assert that we do not have this record.
1937 * we can do this by searching for the primary keyid
1940 /* get the keyblock which has the key */
1941 rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
1942 if( rc ) { /* that should never happen */
1943 log_error( "insert_trust_record: keyblock not found: %s\n",
1948 /* build data structure as linked lists in memory */
1949 keyid[0] = keyid[1] = 0;
1950 for( node=keyblock; node; node = node->next ) {
1951 if( node->pkt->pkttype == PKT_PUBLIC_KEY
1952 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
1953 PKT_public_key *pk = node->pkt->pkt.public_key;
1955 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
1957 BUG(); /* more than one primary key */
1958 keyid_from_pk( pk, keyid );
1960 fingerprint = fingerprint_from_pk( pk, NULL, &fingerlen );
1961 rec = m_alloc_clear( sizeof *rec );
1962 rec->rectype = RECTYPE_KEY;
1963 rec->r.key.pubkey_algo = pk->pubkey_algo;
1964 rec->r.key.fingerprint_len = fingerlen;
1965 memcpy(rec->r.key.fingerprint, fingerprint, fingerlen );
1967 *keylist_tail = rec; keylist_tail = &rec->next;
1969 else if( node->pkt->pkttype == PKT_USER_ID ) {
1970 PKT_user_id *uid = node->pkt->pkt.user_id;
1972 rec = m_alloc_clear( sizeof *rec );
1973 rec->rectype = RECTYPE_UID;
1974 rmd160_hash_buffer( rec->r.uid.namehash, uid->name, uid->len );
1977 *uidlist_tail = rec; uidlist_tail = &rec->next;
1979 else if( node->pkt->pkttype == PKT_SIGNATURE ) {
1980 PKT_signature *sig = node->pkt->pkt.signature;
1982 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
1983 && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
1984 /* must verify this selfsignature here, so that we can
1985 * build the preference record and validate the uid record
1988 log_error("key %08lX: self-signature without user id\n",
1991 else if( (rc = check_key_signature( keyblock, node, NULL ))) {
1992 log_error("key %08lX, uid %02X%02X: "
1993 "invalid self-signature: %s\n",
1994 (ulong)keyid[1], uidlist->r.uid.namehash[18],
1995 uidlist->r.uid.namehash[19], g10_errstr(rc) );
1998 else { /* build the prefrecord */
2000 sigsubpkttype_t subpkttype;
2003 { SIGSUBPKT_PREF_SYM, PREFTYPE_SYM },
2004 { SIGSUBPKT_PREF_HASH, PREFTYPE_HASH },
2005 { SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR },
2012 assert(!uidlist->help_pref);
2013 uidlist->mark |= 1; /* mark valid */
2016 for(k=0; prefs[k].subpkttype; k++ ) {
2017 s = parse_sig_subpkt2( sig, prefs[k].subpkttype, &n );
2020 if( !i || i >= ITEMS_PER_PREF_RECORD ) {
2021 rec = m_alloc_clear( sizeof *rec );
2022 rec->rectype = RECTYPE_PREF;
2023 rec->next = uidlist->help_pref;
2024 uidlist->help_pref = rec;
2027 rec->r.pref.data[i++] = prefs[k].preftype;
2028 rec->r.pref.data[i++] = *s++;
2035 else if( 0 /* is revocation sig etc */ ) {
2036 /* handle it here */
2038 else { /* not a selfsignature */
2043 /* delete all invalid marked userids and their preferences and sigs */
2044 /* (ugly code - I know) */
2045 while( (rec=uidlist_head) && !(rec->mark & 1) ) {
2046 uidlist_head = rec->next;
2047 rel_mem_uidnode(keyid, 1, rec);
2049 for( ; rec; rec = rec->next ) {
2050 if( rec->next && !(rec->next->mark & 1) ) {
2051 TRUSTREC *r = rec->next;
2052 rec->next = r->next;
2053 rel_mem_uidnode(keyid, 1, r);
2057 /* check that we have at least one userid */
2058 if( !uidlist_head ) {
2059 log_error("key %08lX: no user ids - rejected\n", (ulong)keyid[1] );
2060 rc = G10ERR_BAD_CERT;
2064 /* insert the record numbers to build the real (on disk) list */
2065 /* fixme: should start a transaction here */
2066 dirrec.recnum = tdbio_new_recnum();
2067 dirrec.r.dir.lid = dirrec.recnum;
2068 /* (list of keys) */
2069 for(rec=keylist_head; rec; rec = rec->next ) {
2070 rec->r.key.lid = dirrec.recnum;
2071 rec->recnum = tdbio_new_recnum();
2073 for(rec=keylist_head; rec; rec = rec->next )
2074 rec->r.key.next = rec->next? rec->next->recnum : 0;
2075 dirrec.r.dir.keylist = keylist_head->recnum;
2076 /* (list of user ids) */
2077 for(rec=uidlist_head; rec; rec = rec->next ) {
2078 rec->r.uid.lid = dirrec.recnum;
2079 rec->recnum = tdbio_new_recnum();
2080 /* (preference records) */
2081 if( rec->help_pref ) {
2082 for( rec2 = rec->help_pref; rec2; rec2 = rec2->next ) {
2083 rec2->r.pref.lid = dirrec.recnum;
2084 rec2->recnum = tdbio_new_recnum();
2086 for( rec2 = rec->help_pref; rec2->next; rec2 = rec2->next )
2087 rec2->next->r.pref.next = rec2->recnum;
2088 rec->r.uid.prefrec = rec2->recnum;
2091 for(rec=uidlist_head; rec; rec = rec->next )
2092 rec->r.uid.next = rec->next? rec->next->recnum : 0;
2093 dirrec.r.dir.uidlist = uidlist_head->recnum;
2095 /* write all records */
2096 for(rec=keylist_head; rec; rec = rec->next ) {
2097 assert( rec->rectype == RECTYPE_KEY );
2098 if( tdbio_write_record( rec ) ) {
2099 log_error("writing key record failed\n");
2100 rc = G10ERR_TRUSTDB;
2104 for(rec=uidlist_head; rec; rec = rec->next ) {
2105 assert( rec->rectype == RECTYPE_UID );
2106 if( tdbio_write_record( rec ) ) {
2107 log_error("writing uid record failed\n");
2108 rc = G10ERR_TRUSTDB;
2111 for( rec2=rec->help_pref; rec2; rec2 = rec2->next ) {
2112 assert( rec2->rectype == RECTYPE_PREF );
2113 if( tdbio_write_record( rec2 ) ) {
2114 log_error("writing pref record failed\n");
2115 rc = G10ERR_TRUSTDB;
2120 if( tdbio_write_record( &dirrec ) ) {
2121 log_error("writing dir record failed\n");
2122 return G10ERR_TRUSTDB;
2125 /* and store the LID */
2126 orig_pk->local_id = dirrec.r.dir.lid;
2127 for( node=keyblock; node; node = node->next ) {
2128 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2129 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2130 PKT_public_key *pk = node->pkt->pkt.public_key;
2131 pk->local_id = dirrec.r.dir.lid;
2133 else if( node->pkt->pkttype == PKT_SIGNATURE ) {
2134 PKT_signature *sig = node->pkt->pkt.signature;
2135 sig->local_id = dirrec.r.dir.lid;
2141 for(rec=uidlist_head; rec; rec = rec->next ) {
2143 rel_mem_uidnode(NULL, 0, rec );
2145 for(rec=keylist_head; rec; rec = rec->next ) {
2155 update_ownertrust( ulong lid, unsigned new_trust )
2159 if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
2160 log_error("update_ownertrust: read dir failed\n");
2161 return G10ERR_TRUSTDB;
2163 rec.r.dir.ownertrust = new_trust;
2164 if( tdbio_write_record( &rec ) ) {
2165 log_error("update_ownertrust: write failed\n");
2166 return G10ERR_TRUSTDB;