2 * Copyright (C) 1998, 1999 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
51 struct keyid_list *next;
55 struct local_id_item {
56 struct local_id_item *next;
61 struct local_id_table {
62 struct local_id_table *next; /* only used to keep a list of unused tables */
63 struct local_id_item *items[16];
67 typedef struct local_id_table *LOCAL_ID_TABLE;
70 struct enum_cert_paths_ctx {
76 struct recno_list_struct {
77 struct recno_list_struct *next;
81 typedef struct recno_list_struct *RECNO_LIST;
85 typedef struct trust_node *TN;
88 TN list; /* list of other node (should all be of the same type)*/
89 TN next; /* used to build the list */
90 int is_uid; /* set if this is an uid node */
91 ulong lid; /* key or uid recordnumber */
109 static int alloced_tns;
110 static int max_alloced_tns;
114 static LOCAL_ID_TABLE new_lid_table(void);
115 static int ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag );
116 static int qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag );
119 static int propagate_validity( TN root, TN node,
120 int (*add_fnc)(ulong), unsigned *retflgs );
122 static void print_user_id( FILE *fp, const char *text, u32 *keyid );
123 static int do_check( TRUSTREC *drec, unsigned *trustlevel,
124 const char *nhash, int (*add_fnc)(ulong),
126 static int get_dir_record( PKT_public_key *pk, TRUSTREC *rec );
128 static void upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig );
129 static void upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
130 TRUSTREC *drec, RECNO_LIST *recno_list, int recheck,
131 TRUSTREC *urec, const byte *uidhash, int revoked,
132 int *mod_up, int *mod_down );
134 /* a table used to keep track of ultimately trusted keys
135 * which are the ones from our secrings and the trusted keys */
136 static LOCAL_ID_TABLE ultikey_table;
138 /* list of unused lid items and tables */
139 static LOCAL_ID_TABLE unused_lid_tables;
140 static struct local_id_item *unused_lid_items;
149 /**********************************************
150 *********** record read write **************
151 **********************************************/
155 * Read a record but die if it does not exist
158 read_record( ulong recno, TRUSTREC *rec, int rectype )
160 int rc = tdbio_read_record( recno, rec, rectype );
163 log_error(_("trust record %lu, req type %d: read failed: %s\n"),
164 recno, rectype, g10_errstr(rc) );
170 * Wirte a record but die on error
173 write_record( TRUSTREC *rec )
175 int rc = tdbio_write_record( rec );
178 log_error(_("trust record %lu, type %d: write failed: %s\n"),
179 rec->recnum, rec->rectype, g10_errstr(rc) );
184 * Delete a record but die on error
187 delete_record( ulong recno )
189 int rc = tdbio_delete_record( recno );
192 log_error(_("trust record %lu: delete failed: %s\n"),
193 recno, g10_errstr(rc) );
203 int rc = tdbio_sync();
206 log_error(_("trustdb: sync failed: %s\n"), g10_errstr(rc) );
212 /**********************************************
213 ***************** helpers ******************
214 **********************************************/
217 * Insert a new item into a recno list
220 ins_recno_list( RECNO_LIST *head, ulong recno, int type )
222 RECNO_LIST item = m_alloc( sizeof *item );
231 qry_recno_list( RECNO_LIST list, ulong recno, int type )
233 for( ; list; list = list->next ) {
234 if( list->recno == recno && (!type || list->type == type) )
242 rel_recno_list( RECNO_LIST *head )
246 for(r = *head; r; r = r2 ) {
253 static LOCAL_ID_TABLE
258 a = unused_lid_tables;
260 unused_lid_tables = a->next;
261 memset( a, 0, sizeof *a );
264 a = m_alloc_clear( sizeof *a );
270 release_lid_table( LOCAL_ID_TABLE tbl )
272 struct local_id_item *a, *a2;
275 for(i=0; i < 16; i++ ) {
276 for(a=tbl->items[i]; a; a = a2 ) {
278 a->next = unused_lid_items;
279 unused_lid_items = a;
282 tbl->next = unused_lid_tables;
283 unused_lid_tables = tbl;
288 * Add a new item to the table or return 1 if we already have this item
291 ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag )
293 struct local_id_item *a;
295 for( a = tbl->items[lid & 0x0f]; a; a = a->next )
298 a = unused_lid_items;
300 unused_lid_items = a->next;
302 a = m_alloc( sizeof *a );
305 a->next = tbl->items[lid & 0x0f];
306 tbl->items[lid & 0x0f] = a;
311 qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag )
313 struct local_id_item *a;
315 for( a = tbl->items[lid & 0x0f]; a; a = a->next )
316 if( a->lid == lid ) {
333 memset( t, 0, sizeof *t );
336 t = m_alloc_clear( sizeof *t );
337 if( ++alloced_tns > max_alloced_tns )
338 max_alloced_tns = alloced_tns;
355 release_tn_tree( TN kr )
359 for( ; kr; kr = kr2 ) {
360 release_tn_tree( kr->list );
369 /**********************************************
370 ****** access by LID and other helpers *******
371 **********************************************/
374 * Return the keyid from the primary key identified by LID.
377 keyid_from_lid( ulong lid, u32 *keyid )
383 keyid[0] = keyid[1] = 0;
384 rc = tdbio_read_record( lid, &rec, 0 );
386 log_error(_("error reading dir record for LID %lu: %s\n"),
387 lid, g10_errstr(rc));
388 return G10ERR_TRUSTDB;
390 if( rec.rectype == RECTYPE_SDIR )
392 if( rec.rectype != RECTYPE_DIR ) {
393 log_error(_("lid %lu: expected dir record, got type %d\n"),
395 return G10ERR_TRUSTDB;
397 if( !rec.r.dir.keylist ) {
398 log_error(_("no primary key for LID %lu\n"), lid );
399 return G10ERR_TRUSTDB;
401 rc = tdbio_read_record( rec.r.dir.keylist, &rec, RECTYPE_KEY );
403 log_error(_("error reading primary key for LID %lu: %s\n"),
404 lid, g10_errstr(rc));
405 return G10ERR_TRUSTDB;
407 keyid_from_fingerprint( rec.r.key.fingerprint, rec.r.key.fingerprint_len,
415 lid_from_keyblock( KBNODE keyblock )
417 KBNODE node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
421 pk = node->pkt->pkt.public_key;
422 if( !pk->local_id ) {
426 get_dir_record( pk, &rec );
433 get_dir_record( PKT_public_key *pk, TRUSTREC *rec )
438 read_record( pk->local_id, rec, RECTYPE_DIR );
440 else { /* no local_id: scan the trustdb */
441 if( (rc=tdbio_search_dir_bypk( pk, rec )) && rc != -1 )
442 log_error(_("get_dir_record: search_record failed: %s\n"),
449 * Get the LID of a public key.
450 * Returns: The LID of the key (note, that this may be a shadow dir)
451 * or 0 if not available.
454 lid_from_keyid( u32 *keyid )
456 PKT_public_key *pk = m_alloc_clear( sizeof *pk );
461 rc = get_pubkey( pk, keyid );
466 rc = tdbio_search_dir_bypk( pk, &rec );
469 else if( rc == -1 ) { /* see whether there is a sdir instead */
472 keyid_from_pk( pk, akid );
473 rc = tdbio_search_sdir( akid, pk->pubkey_algo, &rec );
479 free_public_key( pk );
485 /***********************************************
486 ************* Initialization ****************
487 ***********************************************/
490 * Verify that all our public keys are in the trustdb.
493 verify_own_keys(void)
496 void *enum_context = NULL;
497 PKT_secret_key *sk = m_alloc_clear( sizeof *sk );
498 PKT_public_key *pk = m_alloc_clear( sizeof *pk );
501 while( !(rc=enum_secret_keys( &enum_context, sk, 0 ) ) ) {
504 keyid_from_sk( sk, keyid );
507 log_debug("key %08lX: checking secret key\n", (ulong)keyid[1] );
509 if( is_secret_key_protected( sk ) < 1 )
510 log_info(_("NOTE: secret key %08lX is NOT protected.\n"),
514 /* see whether we can access the public key of this secret key */
515 memset( pk, 0, sizeof *pk );
516 rc = get_pubkey( pk, keyid );
518 log_info(_("key %08lX: secret key without public key - skipped\n"),
524 if( cmp_public_secret_key( pk, sk ) ) {
525 log_info(_("key %08lX: secret and public key don't match\n"),
530 /* make sure that the pubkey is in the trustdb */
531 rc = query_trust_record( pk );
532 if( rc == -1 ) { /* put it into the trustdb */
533 rc = insert_trust_record( pk );
535 log_error(_("key %08lX: can't put it into the trustdb\n"),
541 log_error(_("key %08lX: query record failed\n"), (ulong)keyid[1] );
547 log_debug("key %08lX.%lu: stored into ultikey_table\n",
548 (ulong)keyid[1], pk->local_id );
549 if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
550 log_error(_("key %08lX: already in trusted key table\n"),
552 else if( opt.verbose > 1 )
553 log_info(_("key %08lX: accepted as trusted key.\n"),
556 release_secret_key_parts( sk );
558 release_public_key_parts( pk );
561 log_error(_("enumerate secret keys failed: %s\n"), g10_errstr(rc) );
565 enum_secret_keys( &enum_context, NULL, 0 ); /* free context */
566 free_secret_key( sk );
567 free_public_key( pk );
573 * Perform some checks over the trustdb
574 * level 0: only open the db
575 * 1: used for initial program startup
578 setup_trustdb( int level, const char *dbname )
580 /* just store the args */
581 if( trustdb_args.init )
583 trustdb_args.level = level;
584 trustdb_args.dbname = dbname? m_strdup(dbname): NULL;
592 int level = trustdb_args.level;
593 const char* dbname = trustdb_args.dbname;
595 if( trustdb_args.init )
598 trustdb_args.init = 1;
601 ultikey_table = new_lid_table();
603 if( !level || level==1 ) {
604 rc = tdbio_set_dbname( dbname, !!level );
609 /* verify that our own keys are in the trustDB
610 * or move them to the trustdb. */
611 rc = verify_own_keys();
613 /* should we check whether there is no other ultimately trusted
614 * key in the database? */
620 log_fatal("can't init trustdb: %s\n", g10_errstr(rc) );
627 /***********************************************
628 ************* Print helpers ****************
629 ***********************************************/
631 print_user_id( FILE *fp, const char *text, u32 *keyid )
636 p = get_user_id( keyid, &n );
638 fprintf( fp, "%s \"", text );
639 print_string( fp, p, n, 0 );
644 tty_printf( "%s \"", text );
645 tty_print_string( p, n );
646 tty_printf( "\"\n" );
654 trust_letter( unsigned value )
657 case TRUST_UNKNOWN: return '-';
658 case TRUST_EXPIRED: return 'e';
659 case TRUST_UNDEFINED: return 'q';
660 case TRUST_NEVER: return 'n';
661 case TRUST_MARGINAL: return 'm';
662 case TRUST_FULLY: return 'f';
663 case TRUST_ULTIMATE: return 'u';
671 print_path( int pathlen, TN ME .........., FILE *fp, ulong highlight )
678 for( i = 0; i < pathlen; i++ ) {
680 fputs(highlight == path[i].lid? "* ":" ", fp );
681 rc = keyid_from_lid( path[i].lid, keyid );
683 fprintf(fp, "????????.%lu:", path[i].lid );
685 fprintf(fp,"%08lX.%lu:", (ulong)keyid[1], path[i].lid );
686 c = trust_letter(path[i].otrust);
690 fprintf( fp, "%02x", path[i].otrust );
692 c = trust_letter(path[i].trust);
696 fprintf( fp, "%02x", path[i].trust );
698 p = get_user_id( keyid, &n );
701 print_string( fp, p, n > 40? 40:n, 0 );
711 print_default_uid( FILE *fp, ulong lid )
715 if( !keyid_from_lid( lid, keyid ) )
716 print_user_id( fp, "", keyid );
721 print_uid_from_keyblock( FILE *fp, KBNODE keyblock, ulong urecno )
727 read_record( urecno, &urec, RECTYPE_UID );
728 for( node=keyblock; node; node = node->next ) {
729 if( node->pkt->pkttype == PKT_USER_ID ) {
730 PKT_user_id *uidpkt = node->pkt->pkt.user_id;
732 rmd160_hash_buffer( uhash, uidpkt->name, uidpkt->len );
733 if( !memcmp( uhash, urec.r.uid.namehash, 20 ) ) {
734 print_string( fp, uidpkt->name, uidpkt->len, ':' );
746 dump_tn_tree( FILE *fp, int level, TN tree )
750 for( kr=tree; kr; kr = kr->next ) {
752 fprintf( fp, "%*s", level*4, "" );
753 fprintf( fp, "K%lu(ot=%d,val=%d) ", kr->lid,
758 tty_printf("%*s", level*4, "" );
759 tty_printf("K%lu(ot=%d,val=%d) ", kr->lid,
763 print_default_uid( fp, kr->lid );
764 for( ur=kr->list; ur; ur = ur->next ) {
766 fprintf(fp, "%*s ", level*4, "" );
767 fprintf(fp, "U%lu(mc=%d,fc=%d,val=%d)\n", ur->lid,
768 ur->n.u.marginal_count,
774 tty_printf("%*s ", level*4, "" );
775 tty_printf("U%lu(mc=%d,fc=%d,val=%d)\n", ur->lid,
776 ur->n.u.marginal_count,
781 dump_tn_tree( fp, level+1, ur->list );
787 * Special version of dump_tn_tree, which prints it colon delimited.
789 * level:keyid:type:recno:ot:val:mc:cc:name:
790 * With TYPE = U for a user ID
792 * The RECNO is either the one of the dir record or the one of the uid record.
793 * OT is the the usual trust letter and only availabel on K lines.
794 * VAL is the calcualted validity
795 * MC is the marginal trust counter and only available on U lines
796 * CC is the same for the complete count
797 * NAME ist the username and only printed on U lines
800 dump_tn_tree_with_colons( int level, TN tree )
804 for( kr=tree; kr; kr = kr->next ) {
808 keyid_from_lid( kr->lid, kid );
809 get_keyblock_bylid( &kb, kr->lid );
811 printf( "%d:%08lX%08lX:K:%lu:%c:%c::::\n",
812 level, (ulong)kid[0], (ulong)kid[1], kr->lid,
813 trust_letter( kr->n.k.ownertrust ),
814 trust_letter( kr->n.k.validity ) );
815 for( ur=kr->list; ur; ur = ur->next ) {
816 printf( "%d:%08lX%08lX:U:%lu::%c:%d:%d:",
817 level, (ulong)kid[0], (ulong)kid[1], ur->lid,
818 trust_letter( kr->n.u.validity ),
819 ur->n.u.marginal_count,
820 ur->n.u.fully_count );
821 print_uid_from_keyblock( stdout, kb, ur->lid );
824 dump_tn_tree_with_colons( level+1, ur->list );
826 release_kbnode( kb );
832 /***********************************************
833 ************* trustdb maintenance ***********
834 ***********************************************/
838 check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
839 TRUSTREC *sigrec, int sigidx, ulong hint_owner )
845 PKT_signature *sigpkt = NULL;
850 if( sigrec->r.sig.sig[sigidx].flag & SIGF_CHECKED )
851 log_info(_("NOTE: sig rec %lu[%d] in hintlist "
852 "of %lu but marked as checked\n"),
853 sigrec->recnum, sigidx, hint_owner );
854 if( !(sigrec->r.sig.sig[sigidx].flag & SIGF_NOPUBKEY) )
855 log_info(_("NOTE: sig rec %lu[%d] in hintlist "
856 "of %lu but not marked\n"),
857 sigrec->recnum, sigidx, hint_owner );
859 read_record( sigrec->r.sig.sig[sigidx].lid, &tmp, 0 );
860 if( tmp.rectype != RECTYPE_DIR ) {
861 /* we need the dir record */
862 log_error(_("sig rec %lu[%d] in hintlist "
863 "of %lu does not point to a dir record\n"),
864 sigrec->recnum, sigidx, hint_owner );
867 if( !tmp.r.dir.keylist ) {
868 log_error(_("lid %lu: no primary key\n"), tmp.r.dir.lid );
871 read_record(tmp.r.dir.keylist, &tmp, RECTYPE_KEY );
872 keyid_from_fingerprint( tmp.r.key.fingerprint,
873 tmp.r.key.fingerprint_len, sigkid );
876 /* find the correct signature packet */
878 for( node=keyblock; node; node = node->next ) {
879 if( node->pkt->pkttype == PKT_USER_ID ) {
880 PKT_user_id *uidpkt = node->pkt->pkt.user_id;
884 rmd160_hash_buffer( uhash, uidpkt->name, uidpkt->len );
885 if( !memcmp( uhash, uidrec_hash, 20 ) )
888 else if( state && node->pkt->pkttype == PKT_SIGNATURE ) {
889 sigpkt = node->pkt->pkt.signature;
890 if( sigpkt->keyid[0] == sigkid[0]
891 && sigpkt->keyid[1] == sigkid[1]
892 && ( (sigpkt->sig_class&~3) == 0x10
893 || ( revoked = (sigpkt->sig_class == 0x30)) ) ) {
901 log_info(_("lid %lu: user id not found in keyblock\n"), lid );
905 log_info(_("lid %lu: user id without signature\n"), lid );
909 /* and check the sig */
910 rc = check_key_signature( keyblock, node, &is_selfsig );
912 log_error(_("lid %lu: self-signature in hintlist\n"), lid );
916 /* FiXME: handling fo SIGF_REVOKED is not correct! */
918 if( !rc ) { /* valid signature */
920 log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
921 (ulong)keyid[1], lid, uhash[18], uhash[19],
922 (ulong)sigpkt->keyid[1],
923 revoked? _("Valid certificate revocation")
924 : _("Good certificate") );
925 sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED | SIGF_VALID;
927 sigrec->r.sig.sig[sigidx].flag |= SIGF_REVOKED;
929 else if( rc == G10ERR_NO_PUBKEY ) {
930 log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
931 (ulong)keyid[1], lid, uhash[18], uhash[19],
932 (ulong)sigpkt->keyid[1],
933 _("very strange: no public key\n") );
934 sigrec->r.sig.sig[sigidx].flag = SIGF_NOPUBKEY;
937 log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
938 (ulong)keyid[1], lid, uhash[18], uhash[19],
939 (ulong)sigpkt->keyid[1], g10_errstr(rc) );
940 sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED;
947 * Process a hintlist.
948 * Fixme: this list is not anymore anchored to another
949 * record, so it should be put elsewehere in case of an error
950 * FIXME: add mod_up/down handling
953 process_hintlist( ulong hintlist, ulong hint_owner )
958 for( hlst_rn = hintlist; hlst_rn; ) {
962 read_record( hlst_rn, &hlstrec, RECTYPE_HLST );
964 for( hlst_idx=0; hlst_idx < ITEMS_PER_HLST_RECORD; hlst_idx++ ) {
968 KBNODE keyblock = NULL;
973 lid = hlstrec.r.hlst.rnum[hlst_idx];
977 read_record( lid, &dirrec, 0 );
978 /* make sure it points to a dir record:
979 * this should be true because it only makes sense to
980 * call this function if the dir record is available */
981 if( dirrec.rectype != RECTYPE_DIR ) {
982 log_error(_("hintlist %lu[%d] of %lu "
983 "does not point to a dir record\n"),
984 hlst_rn, hlst_idx, hint_owner );
987 if( !dirrec.r.dir.keylist ) {
988 log_error(_("lid %lu does not have a key\n"), lid );
992 /* get the keyblock */
993 read_record( dirrec.r.dir.keylist, &tmprec, RECTYPE_KEY );
994 rc = get_keyblock_byfprint( &keyblock,
995 tmprec.r.key.fingerprint,
996 tmprec.r.key.fingerprint_len );
998 log_error(_("lid %lu: can't get keyblock: %s\n"),
999 lid, g10_errstr(rc) );
1002 keyid_from_fingerprint( tmprec.r.key.fingerprint,
1003 tmprec.r.key.fingerprint_len, keyid );
1005 /* Walk over all user ids and their signatures and check all
1006 * the signature which are created by hint_owner */
1007 for( r1 = dirrec.r.dir.uidlist; r1; r1 = uidrec.r.uid.next ) {
1010 read_record( r1, &uidrec, RECTYPE_UID );
1011 for( r2 = uidrec.r.uid.siglist; r2; r2 = sigrec.r.sig.next ) {
1014 read_record( r2, &sigrec, RECTYPE_SIG );
1016 for(i=0; i < SIGS_PER_RECORD; i++ ) {
1017 if( !sigrec.r.sig.sig[i].lid )
1018 continue; /* skip deleted sigs */
1019 if( sigrec.r.sig.sig[i].lid != hint_owner )
1020 continue; /* not for us */
1021 /* some diagnostic messages */
1022 /* and do the signature check */
1023 check_hint_sig( lid, keyblock, keyid,
1024 uidrec.r.uid.namehash,
1025 &sigrec, i, hint_owner );
1028 write_record( &sigrec );
1031 release_kbnode( keyblock );
1032 } /* loop over hlst entries */
1034 /* delete this hlst record */
1035 hlst_rn = hlstrec.r.hlst.next;
1036 delete_record( hlstrec.recnum );
1037 } /* loop over hintlist */
1042 * Create or update shadow dir record and return the LID of the record
1045 create_shadow_dir( PKT_signature *sig, ulong lid )
1047 TRUSTREC sdir, hlst, tmphlst;
1048 ulong recno, newlid;
1049 int tmpidx=0; /* avoids gcc warnign - this is controlled by tmphlst */
1052 /* first see whether we already have such a record */
1053 rc = tdbio_search_sdir( sig->keyid, sig->pubkey_algo, &sdir );
1054 if( rc && rc != -1 ) {
1055 log_error(_("tdbio_search_dir failed: %s\n"), g10_errstr(rc));
1058 if( rc == -1 ) { /* not found: create */
1059 memset( &sdir, 0, sizeof sdir );
1060 sdir.recnum = tdbio_new_recnum();
1061 sdir.rectype= RECTYPE_SDIR;
1062 sdir.r.sdir.lid = sdir.recnum;
1063 sdir.r.sdir.keyid[0] = sig->keyid[0];
1064 sdir.r.sdir.keyid[1] = sig->keyid[1];
1065 sdir.r.sdir.pubkey_algo = sig->pubkey_algo;
1066 sdir.r.sdir.hintlist = 0;
1067 write_record( &sdir );
1069 newlid = sdir.recnum;
1070 /* Put the record number into the hintlist.
1071 * (It is easier to use the lid and not the record number of the
1072 * key to save some space (assuming that a signator has
1073 * signed more than one user id - and it is easier to implement.)
1076 for( recno=sdir.r.sdir.hintlist; recno; recno = hlst.r.hlst.next) {
1078 read_record( recno, &hlst, RECTYPE_HLST );
1079 for( i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
1080 if( !hlst.r.hlst.rnum[i] ) {
1081 if( !tmphlst.recnum ) {
1086 else if( hlst.r.hlst.rnum[i] == lid )
1087 return newlid; /* the signature is already in the hintlist */
1090 /* not yet in the hint list, write it */
1091 if( tmphlst.recnum ) { /* we have an empty slot */
1092 tmphlst.r.hlst.rnum[tmpidx] = lid;
1093 write_record( &tmphlst );
1095 else { /* must append a new hlst record */
1096 memset( &hlst, 0, sizeof hlst );
1097 hlst.recnum = tdbio_new_recnum();
1098 hlst.rectype = RECTYPE_HLST;
1099 hlst.r.hlst.next = sdir.r.sdir.hintlist;
1100 hlst.r.hlst.rnum[0] = lid;
1101 write_record( &hlst );
1102 sdir.r.sdir.hintlist = hlst.recnum;
1103 write_record( &sdir );
1111 * This function checks the given public key and inserts or updates
1112 * the keyrecord from the trustdb. Revocation certificates
1113 * are handled here and the keybinding of subkeys is checked.
1114 * Hmmm: Should we check here, that the key has at least one valid
1115 * user ID or do we allow keys w/o user ID?
1117 * keyblock points to the first node in the keyblock,
1118 * keynode is the node with the public key to check
1119 * (either primary or secondary), keyid is the keyid of
1120 * the primary key, drec is the directory record and recno_list
1121 * is a list used to keep track of visited records.
1122 * Existing keyflags are recalculated if recheck is true.
1125 upd_key_record( KBNODE keyblock, KBNODE keynode, u32 *keyid,
1126 TRUSTREC *drec, RECNO_LIST *recno_list, int recheck )
1130 PKT_public_key *pk = keynode->pkt->pkt.public_key;
1131 ulong lid = drec->recnum;
1132 byte fpr[MAX_FINGERPRINT_LEN];
1134 ulong recno, newrecno;
1135 int keybind_seen = 0;
1136 int revoke_seen = 0;
1139 fingerprint_from_pk( pk, fpr, &fprlen );
1140 /* do we already have this key? */
1141 for( recno=drec->r.dir.keylist; recno; recno = krec.r.key.next ) {
1142 read_record( recno, &krec, RECTYPE_KEY );
1143 if( krec.r.key.fingerprint_len == fprlen
1144 && !memcmp( krec.r.key.fingerprint, fpr, fprlen ) )
1147 if( recno ) { /* yes */
1148 ins_recno_list( recno_list, recno, RECTYPE_KEY );
1150 else { /* no: insert this new key */
1151 recheck = 1; /* same as recheck */
1152 memset( &krec, 0, sizeof(krec) );
1153 krec.rectype = RECTYPE_KEY;
1154 krec.r.key.lid = lid;
1155 krec.r.key.pubkey_algo = pk->pubkey_algo;
1156 krec.r.key.fingerprint_len = fprlen;
1157 memcpy(krec.r.key.fingerprint, fpr, fprlen );
1158 krec.recnum = newrecno = tdbio_new_recnum();
1159 write_record( &krec );
1160 ins_recno_list( recno_list, newrecno, RECTYPE_KEY );
1161 /* and put this new record at the end of the keylist */
1162 if( !(recno=drec->r.dir.keylist) ) {
1163 /* this is the first key */
1164 drec->r.dir.keylist = newrecno;
1167 else { /* we already have a key, append the new one */
1168 TRUSTREC save = krec;
1169 for( ; recno; recno = krec.r.key.next )
1170 read_record( recno, &krec, RECTYPE_KEY );
1171 krec.r.key.next = newrecno;
1172 write_record( &krec );
1177 if( !recheck && (krec.r.key.keyflags & KEYF_CHECKED) )
1180 /* check keybindings and revocations */
1181 krec.r.key.keyflags = 0;
1182 if( keynode->pkt->pkttype == PKT_PUBLIC_KEY ) {
1183 /* we assume that a primary key is always valid
1184 * and check later whether we have a revocation */
1185 krec.r.key.keyflags |= KEYF_CHECKED | KEYF_VALID;
1188 for( node=keynode->next; node; node = node->next ) {
1191 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
1192 break; /* ready (we check only one key at a time) */
1193 else if( node->pkt->pkttype != PKT_SIGNATURE )
1196 sig = node->pkt->pkt.signature;
1198 if( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
1199 continue; /* here we only care about a self-signatures */
1201 if( sig->sig_class == 0x18 && !keybind_seen ) { /* a keybinding */
1202 if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
1203 continue; /* oops, ignore subkey binding on main key */
1205 /* we check until we find a valid keybinding */
1206 rc = check_key_signature( keyblock, node, NULL );
1210 "key %08lX.%lu: Good subkey binding\n"),
1211 (ulong)keyid_from_pk(pk,NULL), lid );
1212 krec.r.key.keyflags |= KEYF_CHECKED | KEYF_VALID;
1216 "key %08lX.%lu: Invalid subkey binding: %s\n"),
1217 (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
1218 krec.r.key.keyflags |= KEYF_CHECKED;
1219 krec.r.key.keyflags &= ~KEYF_VALID;
1223 else if( sig->sig_class == 0x20 && !revoke_seen ) {
1224 if( keynode->pkt->pkttype == PKT_PUBLIC_SUBKEY )
1225 continue; /* a subkey is not expected here */
1227 /* This is a key revocation certificate: check it */
1228 rc = check_key_signature( keyblock, node, NULL );
1232 "key %08lX.%lu: Valid key revocation\n"),
1233 (ulong)keyid_from_pk(pk,NULL), lid );
1234 krec.r.key.keyflags |= KEYF_REVOKED;
1238 "key %08lX.%lu: Invalid key revocation: %s\n"),
1239 (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
1243 else if( sig->sig_class == 0x28 && !revoke_seen ) {
1244 if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
1245 continue; /* a mainkey is not expected here */
1246 /* This is a subkey revocation certificate: check it */
1247 /* fixme: we should also check the revocation
1248 * is newer than the key (OpenPGP) */
1249 rc = check_key_signature( keyblock, node, NULL );
1253 "key %08lX.%lu: Valid subkey revocation\n"),
1254 (ulong)keyid_from_pk(pk,NULL), lid );
1255 krec.r.key.keyflags |= KEYF_REVOKED;
1259 "key %08lX.%lu: Invalid subkey binding: %s\n"),
1260 (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
1266 write_record( &krec );
1271 * This function checks the given user ID and inserts or updates
1272 * the uid record of the trustdb. Revocation certificates
1275 * keyblock points to the first node in the keyblock,
1276 * uidnode is the node with the user id to check
1277 * keyid is the keyid of
1278 * the primary key, drec is the directory record and recno_list
1279 * is a list used to keep track of visited records.
1280 * Existing uidflags are recalculated if recheck is true.
1283 upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
1284 TRUSTREC *drec, RECNO_LIST *recno_list,
1285 int recheck, int *mod_up, int *mod_down )
1287 ulong lid = drec->recnum;
1288 PKT_user_id *uid = uidnode->pkt->pkt.user_id;
1290 PKT_signature *selfsig = NULL;
1293 ulong recno, newrecno;
1297 log_debug("upd_uid_record for %08lX/%02X%02X\n",
1298 (ulong)keyid[1], uidhash[18], uidhash[19]);
1300 /* see whether we already have an uid record */
1301 rmd160_hash_buffer( uidhash, uid->name, uid->len );
1302 for( recno=drec->r.dir.uidlist; recno; recno = urec.r.uid.next ) {
1303 read_record( recno, &urec, RECTYPE_UID );
1304 if( !memcmp( uidhash, urec.r.uid.namehash, 20 ) )
1307 if( recno ) { /* we already have this record */
1308 ins_recno_list( recno_list, recno, RECTYPE_UID );
1310 else { /* new user id */
1311 recheck = 1; /* insert is the same as a recheck */
1312 memset( &urec, 0 , sizeof(urec) );
1313 urec.rectype = RECTYPE_UID;
1314 urec.r.uid.lid = drec->recnum;
1315 memcpy(urec.r.uid.namehash, uidhash, 20 );
1316 urec.recnum = newrecno = tdbio_new_recnum();
1317 write_record( &urec );
1318 ins_recno_list( recno_list, newrecno, RECTYPE_UID );
1319 /* and put this new record at the end of the uidlist */
1320 if( !(recno=drec->r.dir.uidlist) ) { /* this is the first uid */
1321 drec->r.dir.uidlist = newrecno;
1324 else { /* we already have an uid, append it to the list */
1325 TRUSTREC save = urec;
1326 for( ; recno; recno = urec.r.key.next )
1327 read_record( recno, &urec, RECTYPE_UID );
1328 urec.r.uid.next = newrecno;
1329 write_record( &urec );
1334 if( recheck || !(urec.r.uid.uidflags & UIDF_CHECKED) ) {
1335 unsigned orig_uidflags = urec.r.uid.uidflags;
1337 urec.r.uid.uidflags = 0;
1338 /* first check regular self signatures */
1339 for( node=uidnode->next; node; node = node->next ) {
1342 if( node->pkt->pkttype == PKT_USER_ID )
1344 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
1346 if( node->pkt->pkttype != PKT_SIGNATURE )
1349 sig = node->pkt->pkt.signature;
1351 if( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
1352 continue; /* not a self signature */
1354 if( (sig->sig_class&~3) == 0x10 ) { /* regular self signature */
1355 rc = check_key_signature( keyblock, node, NULL );
1358 log_info( "uid %08lX.%lu/%02X%02X: %s\n",
1359 (ulong)keyid[1], lid, uidhash[18], uidhash[19],
1360 _("Good self-signature") );
1361 urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID;
1363 selfsig = sig; /* use the first valid sig */
1364 else if( sig->timestamp > selfsig->timestamp
1365 && sig->sig_class >= selfsig->sig_class )
1366 selfsig = sig; /* but this one is newer */
1369 log_info( "uid %08lX/%02X%02X: %s: %s\n",
1370 (ulong)keyid[1], uidhash[18], uidhash[19],
1371 _("Invalid self-signature"),
1373 urec.r.uid.uidflags |= UIDF_CHECKED;
1378 /* and now check for revocations- we must do this after the
1379 * self signature check because a selfsignature which is newer
1380 * than a revocation makes the revocation invalid.
1381 * Fixme: Is this correct - check with rfc2440
1383 for( node=uidnode->next; node; node = node->next ) {
1386 if( node->pkt->pkttype == PKT_USER_ID )
1388 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
1390 if( node->pkt->pkttype != PKT_SIGNATURE )
1393 sig = node->pkt->pkt.signature;
1395 if( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
1396 continue; /* not a self signature */
1398 if( sig->sig_class == 0x30 ) { /* cert revocation */
1399 rc = check_key_signature( keyblock, node, NULL );
1400 if( !rc && selfsig && selfsig->timestamp > sig->timestamp ) {
1401 log_info( "uid %08lX.%lu/%02X%02X: %s\n",
1402 (ulong)keyid[1], lid, uidhash[18], uidhash[19],
1403 _("Valid user ID revocation skipped "
1404 "due to a newer self signature\n") );
1408 log_info( "uid %08lX.%lu/%02X%02X: %s\n",
1409 (ulong)keyid[1], lid, uidhash[18], uidhash[19],
1410 _("Valid user ID revocation\n") );
1411 urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID;
1412 urec.r.uid.uidflags |= UIDF_REVOKED;
1415 log_info("uid %08lX/%02X%02X: %s: %s\n",
1416 (ulong)keyid[1], uidhash[18], uidhash[19],
1417 _("Invalid user ID revocation"),
1424 if( orig_uidflags != urec.r.uid.uidflags ) {
1425 write_record( &urec );
1426 if( !( urec.r.uid.uidflags & UIDF_VALID )
1427 || ( urec.r.uid.uidflags & UIDF_REVOKED ) )
1430 *mod_up=1; /*(maybe a new user id)*/
1431 /* Hmmm, did we catch changed expiration dates? */
1434 } /* end check self-signatures */
1437 if( (urec.r.uid.uidflags & (UIDF_CHECKED|UIDF_VALID))
1438 != (UIDF_CHECKED|UIDF_VALID) )
1439 return; /* user ID is not valid, so no need to check more things */
1441 /* check the preferences */
1443 upd_pref_record( &urec, keyid, selfsig );
1445 /* Now we va check the certication signatures */
1446 for( node=uidnode->next; node; node = node->next ) {
1449 if( node->pkt->pkttype == PKT_USER_ID )
1451 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
1453 if( node->pkt->pkttype != PKT_SIGNATURE )
1456 sig = node->pkt->pkt.signature;
1458 if( keyid[0] == sig->keyid[0] || keyid[1] == sig->keyid[1] )
1459 continue; /* here we skip the self-signatures */
1461 if( (sig->sig_class&~3) == 0x10 ) { /* regular certification */
1462 upd_cert_record( keyblock, node, keyid, drec, recno_list,
1463 recheck, &urec, uidhash, 0, mod_up, mod_down );
1465 else if( sig->sig_class == 0x30 ) { /* cert revocation */
1466 upd_cert_record( keyblock, node, keyid, drec, recno_list,
1467 recheck, &urec, uidhash, 1, mod_up, mod_down );
1469 } /* end check certificates */
1471 write_record( &urec );
1476 upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig )
1479 sigsubpkttype_t subpkttype;
1482 { SIGSUBPKT_PREF_SYM, PREFTYPE_SYM },
1483 { SIGSUBPKT_PREF_HASH, PREFTYPE_HASH },
1484 { SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR },
1488 ulong lid = urec->r.uid.lid ;
1489 const byte *uidhash = urec->r.uid.namehash;
1494 byte prefs_sig[200];
1495 int n_prefs_sig = 0;
1496 byte prefs_rec[200];
1497 int n_prefs_rec = 0;
1500 log_debug("upd_pref_record for %08lX.%lu/%02X%02X\n",
1501 (ulong)keyid[1], lid, uidhash[18], uidhash[19] );
1504 /* check for changed preferences */
1505 for(k=0; ptable[k].subpkttype; k++ ) {
1506 s = parse_sig_subpkt2( sig, ptable[k].subpkttype, &n );
1508 for( ; n; n--, s++ ) {
1509 if( n_prefs_sig >= DIM(prefs_sig)-1 ) {
1510 log_info("uid %08lX.%lu/%02X%02X: %s\n",
1511 (ulong)keyid[1], lid, uidhash[18], uidhash[19],
1512 _("Too many preferences") );
1515 prefs_sig[n_prefs_sig++] = ptable[k].preftype;
1516 prefs_sig[n_prefs_sig++] = *s;
1520 for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
1521 read_record( recno, &prec, RECTYPE_PREF );
1522 for(i = 0; i < ITEMS_PER_PREF_RECORD; i +=2 ) {
1523 if( n_prefs_rec >= DIM(prefs_rec)-1 ) {
1524 log_info("uid %08lX.%lu/%02X%02X: %s\n",
1525 (ulong)keyid[1], lid, uidhash[18], uidhash[19],
1526 _("Too many preference items") );
1529 if( prec.r.pref.data[i] ) {
1530 prefs_rec[n_prefs_rec++] = prec.r.pref.data[i];
1531 prefs_rec[n_prefs_rec++] = prec.r.pref.data[i+1];
1535 if( n_prefs_sig == n_prefs_rec
1536 && !memcmp( prefs_sig, prefs_rec, n_prefs_sig ) )
1537 return; /* not changed */
1539 /* Preferences have changed: Delete all pref records
1540 * This is much simpler than checking whether we have to
1541 * do update the record at all - the record cache may care about it
1543 for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
1544 read_record( recno, &prec, RECTYPE_PREF );
1545 delete_record( recno );
1548 if( n_prefs_sig > ITEMS_PER_PREF_RECORD )
1549 log_info(_("WARNING: can't yet handle long pref records\n"));
1551 memset( &prec, 0, sizeof prec );
1552 prec.recnum = tdbio_new_recnum();
1553 prec.rectype = RECTYPE_PREF;
1554 prec.r.pref.lid = lid;
1555 if( n_prefs_sig <= ITEMS_PER_PREF_RECORD )
1556 memcpy( prec.r.pref.data, prefs_sig, n_prefs_sig );
1557 else { /* need more than one pref record */
1560 byte *pp = prefs_sig;
1563 memcpy( prec.r.pref.data, pp, ITEMS_PER_PREF_RECORD );
1564 n -= ITEMS_PER_PREF_RECORD;
1565 pp += ITEMS_PER_PREF_RECORD;
1566 nextrn = prec.r.pref.next = tdbio_new_recnum();
1568 memset( &tmp, 0, sizeof tmp );
1569 tmp.recnum = nextrn;
1570 tmp.rectype = RECTYPE_PREF;
1571 tmp.r.pref.lid = lid;
1572 if( n <= ITEMS_PER_PREF_RECORD ) {
1573 memcpy( tmp.r.pref.data, pp, n );
1577 memcpy( tmp.r.pref.data, pp, ITEMS_PER_PREF_RECORD );
1578 n -= ITEMS_PER_PREF_RECORD;
1579 pp += ITEMS_PER_PREF_RECORD;
1580 nextrn = tmp.r.pref.next = tdbio_new_recnum();
1582 write_record( &tmp );
1585 write_record( &prec );
1586 urec->r.uid.prefrec = prec.recnum;
1592 upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
1593 TRUSTREC *drec, RECNO_LIST *recno_list, int recheck,
1594 TRUSTREC *urec, const byte *uidhash, int revoked,
1595 int *mod_up, int *mod_down )
1597 /* We simply insert the signature into the sig records but
1598 * avoid duplicate ones. We do not check them here because
1599 * there is a big chance, that we import required public keys
1600 * later. The problem with this is that we must somewhere store
1601 * the information about this signature (we need a record id).
1602 * We do this by using the record type shadow dir, which will
1603 * be converted to a dir record as when the missing public key
1604 * gets inserted into the trustdb.
1606 ulong lid = drec->recnum;
1607 PKT_signature *sig = signode->pkt->pkt.signature;
1616 int found_delrec = 0;
1621 log_debug("upd_cert_record for %08lX.?/%02X%02X/%08lX\n",
1622 (ulong)keyid[1], uidhash[18],
1623 uidhash[19], (ulong)sig->keyid[1] );
1627 /* get the LID of the pubkey of the signature under verification */
1628 pk_lid = lid_from_keyid( sig->keyid );
1630 /* Loop over all signatures just in case one is not correctly
1631 * marked. If we see the correct signature, set a flag.
1632 * delete duplicate signatures (should not happen but...) */
1633 for( recno = urec->r.uid.siglist; recno; recno = rec.r.sig.next ) {
1636 read_record( recno, &rec, RECTYPE_SIG );
1637 for(i=0; i < SIGS_PER_RECORD; i++ ) {
1639 if( !rec.r.sig.sig[i].lid ) {
1640 /* (remember this unused slot) */
1641 if( !found_delrec && !delrec.recnum ) {
1646 continue; /* skip unused slots */
1649 if( rec.r.sig.sig[i].lid == pk_lid ) {
1651 log_info( "sig %08lX.%lu/%02X%02X/%08lX: %s\n",
1652 (ulong)keyid[1], lid, uidhash[18],
1653 uidhash[19], (ulong)sig->keyid[1],
1654 _("duplicated certificate - deleted") );
1655 rec.r.sig.sig[i].lid = 0;
1661 if( !recheck && !revoked && (rec.r.sig.sig[i].flag & SIGF_CHECKED))
1662 continue; /* we already checked this signature */
1663 if( !recheck && (rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
1664 continue; /* we do not have the public key */
1666 read_record( rec.r.sig.sig[i].lid, &tmp, 0 );
1667 if( tmp.rectype == RECTYPE_DIR ) {
1668 /* the public key is in the trustdb: check sig */
1669 rc = check_key_signature( keyblock, signode, NULL );
1670 if( !rc ) { /* valid signature */
1672 log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
1673 (ulong)keyid[1], lid, uidhash[18],
1674 uidhash[19], (ulong)sig->keyid[1],
1675 revoked? _("Valid certificate revocation")
1676 : _("Good certificate") );
1677 rec.r.sig.sig[i].flag = SIGF_CHECKED | SIGF_VALID;
1678 if( revoked ) { /* we are investigating revocations */
1679 rec.r.sig.sig[i].flag |= SIGF_REVOKED;
1685 else if( rc == G10ERR_NO_PUBKEY ) {
1686 /* This may happen if the key is still in the trustdb
1687 * but not available in the keystorage */
1688 if( (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
1689 log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
1690 (ulong)keyid[1], lid, uidhash[18],
1691 uidhash[19], (ulong)sig->keyid[1],
1692 _("public key not anymore available") );
1693 rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
1696 rec.r.sig.sig[i].flag |= SIGF_REVOKED;
1699 log_info("sig %08lX.%lu/%02X%02X/%08lX: %s: %s\n",
1700 (ulong)keyid[1], lid, uidhash[18],
1701 uidhash[19], (ulong)sig->keyid[1],
1702 revoked? _("Invalid certificate revocation")
1703 : _("Invalid certificate"),
1705 rec.r.sig.sig[i].flag = SIGF_CHECKED;
1707 rec.r.sig.sig[i].flag |= SIGF_REVOKED;
1713 else if( tmp.rectype == RECTYPE_SDIR ) {
1714 /* must check that it is the right one */
1715 if( tmp.r.sdir.keyid[0] == sig->keyid[0]
1716 && tmp.r.sdir.keyid[1] == sig->keyid[1]
1717 && (!tmp.r.sdir.pubkey_algo
1718 || tmp.r.sdir.pubkey_algo == sig->pubkey_algo )) {
1719 if( !(rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
1720 log_info(_("uid %08lX.%lu/%02X%02X: "
1721 "has shadow dir %lu but is not yet marked.\n"),
1722 (ulong)keyid[1], lid,
1723 uidhash[18], uidhash[19], tmp.recnum );
1724 rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
1726 rec.r.sig.sig[i].flag |= SIGF_REVOKED;
1728 /* fixme: should we verify that the record is
1729 * in the hintlist? - This case here should anyway
1734 log_error(_("sig record %lu[%d] points to wrong record.\n"),
1735 rec.r.sig.sig[i].lid, i );
1739 if( found_delrec && delrec.recnum ) {
1741 found_delrec = 0; /* we only want the first one */
1744 write_record( &rec );
1752 /* at this point, we have verified, that the signature is not in
1753 * our list of signatures. Add a new record with that signature
1754 * and if the public key is there, check the signature. */
1756 if( !pk_lid ) /* we have already seen that there is no pubkey */
1757 rc = G10ERR_NO_PUBKEY;
1759 rc = check_key_signature( keyblock, signode, NULL );
1761 if( !rc ) { /* valid signature */
1763 log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
1764 (ulong)keyid[1], lid, uidhash[18],
1765 uidhash[19], (ulong)sig->keyid[1],
1766 revoked? _("Valid certificate revocation")
1767 : _("Good certificate") );
1768 newlid = pk_lid; /* this is the pk of the signature */
1769 newflag = SIGF_CHECKED | SIGF_VALID;
1771 newflag |= SIGF_REVOKED;
1777 else if( rc == G10ERR_NO_PUBKEY ) {
1778 if( opt.verbose > 1 || DBG_TRUST )
1779 log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
1780 (ulong)keyid[1], lid, uidhash[18],
1781 uidhash[19], (ulong)sig->keyid[1], g10_errstr(rc) );
1782 newlid = create_shadow_dir( sig, lid );
1783 newflag = SIGF_NOPUBKEY;
1785 newflag |= SIGF_REVOKED;
1788 log_info( "sig %08lX.%lu/%02X%02X/%08lX: %s: %s\n",
1789 (ulong)keyid[1], lid, uidhash[18], uidhash[19],
1790 (ulong)sig->keyid[1],
1791 revoked? _("Invalid certificate revocation")
1792 : _("Invalid certificate"),
1794 newlid = create_shadow_dir( sig, lid );
1795 newflag = SIGF_CHECKED;
1797 newflag |= SIGF_REVOKED;
1801 if( delrec.recnum ) { /* we can reuse an unused slot */
1802 delrec.r.sig.sig[delrecidx].lid = newlid;
1803 delrec.r.sig.sig[delrecidx].flag= newflag;
1804 write_record( &delrec );
1806 else { /* we must insert a new sig record */
1809 memset( &tmp, 0, sizeof tmp );
1810 tmp.recnum = tdbio_new_recnum();
1811 tmp.rectype = RECTYPE_SIG;
1812 tmp.r.sig.lid = lid;
1813 tmp.r.sig.next = urec->r.uid.siglist;
1814 tmp.r.sig.sig[0].lid = newlid;
1815 tmp.r.sig.sig[0].flag= newflag;
1816 write_record( &tmp );
1817 urec->r.uid.siglist = tmp.recnum;
1824 * Update all the info from the public keyblock.
1825 * The key must already exist in the keydb.
1826 * This function is responsible for checking the signatures in cases
1827 * where the public key is already available. If we do not have the public
1828 * key, the check is done by some special code in insert_trust_record().
1831 update_trust_record( KBNODE keyblock, int recheck, int *modified )
1833 PKT_public_key *primary_pk;
1841 u32 keyid[2]; /* keyid of primary key */
1842 ulong recno, lastrecno;
1845 RECNO_LIST recno_list = NULL; /* list of verified records */
1846 /* fixme: replace recno_list by a lookup on node->recno */
1855 node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
1856 primary_pk = node->pkt->pkt.public_key;
1857 rc = get_dir_record( primary_pk, &drec );
1860 if( !primary_pk->local_id )
1861 primary_pk->local_id = drec.recnum;
1863 keyid_from_pk( primary_pk, keyid );
1865 /* fixme: check that the keyblock has a valid structure */
1867 rc = tdbio_begin_transaction();
1871 /* update the keys */
1872 for( node=keyblock; node; node = node->next ) {
1873 if( node->pkt->pkttype == PKT_PUBLIC_KEY
1874 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
1875 upd_key_record( keyblock, node, keyid,
1876 &drec, &recno_list, recheck );
1878 /* update the user IDs */
1879 for( node=keyblock; node; node = node->next ) {
1880 if( node->pkt->pkttype == PKT_USER_ID )
1881 upd_uid_record( keyblock, node, keyid,
1882 &drec, &recno_list, recheck, &mod_up, &mod_down );
1885 /* delete keyrecords from the trustdb which are not anymore used */
1886 /* should we really do this, or is it better to keep them and */
1887 /* mark as unused? */
1888 /* And set the revocation flag into the dir record */
1889 drec.r.dir.dirflags &= ~DIRF_REVOKED;
1891 for( recno=drec.r.dir.keylist; recno; recno = krec.r.key.next ) {
1892 read_record( recno, &krec, RECTYPE_KEY );
1893 if( recno == drec.r.dir.keylist ) { /* this is the primary key */
1894 if( (krec.r.key.keyflags & KEYF_REVOKED) ) {
1895 drec.r.dir.dirflags |= DIRF_REVOKED;
1900 if( !qry_recno_list( recno_list, recno, RECTYPE_KEY ) ) {
1901 /* delete this one */
1903 drec.r.dir.keylist = krec.r.key.next;
1907 read_record( lastrecno, &helprec, RECTYPE_KEY );
1908 helprec.r.key.next = krec.r.key.next;
1909 write_record( &helprec );
1911 delete_record( recno );
1916 /* delete uid records and sig and their pref records from the
1917 * trustdb which are not anymore used */
1919 for( recno=drec.r.dir.uidlist; recno; recno = urec.r.uid.next ) {
1920 read_record( recno, &urec, RECTYPE_UID );
1921 if( !qry_recno_list( recno_list, recno, RECTYPE_UID ) ) {
1923 /* delete this one */
1925 drec.r.dir.uidlist = urec.r.uid.next;
1929 read_record( lastrecno, &helprec, RECTYPE_UID );
1930 helprec.r.uid.next = urec.r.uid.next;
1931 write_record( &helprec );
1933 for(r2=urec.r.uid.prefrec ; r2; r2 = prec.r.pref.next ) {
1934 read_record( r2, &prec, RECTYPE_PREF );
1935 delete_record( r2 );
1937 for(r2=urec.r.uid.siglist ; r2; r2 = helprec.r.sig.next ) {
1938 read_record( r2, &helprec, RECTYPE_SIG );
1939 delete_record( r2 );
1941 delete_record( recno );
1950 rc = tdbio_cancel_transaction();
1952 if( modified && tdbio_is_dirty() )
1954 drec.r.dir.dirflags |= DIRF_CHECKED;
1955 drec.r.dir.valcheck = 0;
1956 write_record( &drec );
1957 tdbio_write_modify_stamp( mod_up, mod_down );
1958 rc = tdbio_end_transaction();
1960 rel_recno_list( &recno_list );
1966 * Insert a trust record into the TrustDB
1967 * This function assumes that the record does not yet exist.
1970 insert_trust_record( PKT_public_key *orig_pk )
1974 KBNODE keyblock = NULL;
1976 byte fingerprint[MAX_FINGERPRINT_LEN];
1988 fingerprint_from_pk( orig_pk, fingerprint, &fingerlen );
1990 /* fixme: assert that we do not have this record.
1991 * we can do this by searching for the primary keyid
1993 * fixme: If there is no such key we should look whether one
1994 * of the subkeys has been used to sign another key and in this case
1995 * we got the key anyway - this is because a secondary key can't be used
1996 * without a primary key (it is needed to bind the secondary one
1997 * to the primary one which has the user ids etc.)
2000 if( orig_pk->local_id )
2001 log_debug("insert_trust_record with pk->local_id=%lu (1)\n",
2002 orig_pk->local_id );
2004 /* get the keyblock which has the key */
2005 rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
2006 if( rc ) { /* that should never happen */
2007 log_error( _("insert_trust_record: keyblock not found: %s\n"),
2012 /* make sure that we use the primary key */
2013 pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )->pkt->pkt.public_key;
2015 if( pk->local_id ) {
2016 orig_pk->local_id = pk->local_id;
2017 log_debug("insert_trust_record with pk->local_id=%lu (2)\n",
2019 rc = update_trust_record( keyblock, 1, NULL );
2020 release_kbnode( keyblock );
2024 /* We have to look for a shadow dir record which must be reused
2025 * as the dir record. And: check all signatures which are listed
2026 * in the hintlist of the shadow dir record.
2028 rc = tdbio_search_sdir( pk->keyid, pk->pubkey_algo, &shadow );
2029 if( rc && rc != -1 ) {
2030 log_error(_("tdbio_search_dir failed: %s\n"), g10_errstr(rc));
2033 memset( &dirrec, 0, sizeof dirrec );
2034 dirrec.rectype = RECTYPE_DIR;
2036 /* hey, great: this key has already signed other keys
2037 * convert this to a real directory entry */
2038 hintlist = shadow.r.sdir.hintlist;
2039 dirrec.recnum = shadow.recnum;
2042 dirrec.recnum = tdbio_new_recnum();
2044 dirrec.r.dir.lid = dirrec.recnum;
2045 write_record( &dirrec );
2047 /* out the LID into the keyblock */
2048 pk->local_id = dirrec.r.dir.lid;
2049 orig_pk->local_id = dirrec.r.dir.lid;
2050 for( node=keyblock; node; node = node->next ) {
2051 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2052 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2053 PKT_public_key *a_pk = node->pkt->pkt.public_key;
2054 a_pk->local_id = dirrec.r.dir.lid;
2056 else if( node->pkt->pkttype == PKT_SIGNATURE ) {
2057 PKT_signature *a_sig = node->pkt->pkt.signature;
2058 a_sig->local_id = dirrec.r.dir.lid;
2062 /* mark tdb as modified upwards */
2063 tdbio_write_modify_stamp( 1, 0 );
2065 /* and put all the other stuff into the keydb */
2066 rc = update_trust_record( keyblock, 1, NULL );
2068 process_hintlist( hintlist, dirrec.r.dir.lid );
2071 if( rc && hintlist )
2072 ; /* fixme: the hintlist is not anymore anchored */
2073 release_kbnode( keyblock );
2081 /***********************************************
2082 ********* Trust calculation *****************
2083 ***********************************************/
2086 * Find all certification paths of a given LID.
2087 * Limit the search to MAX_DEPTH. stack is a helper variable which
2088 * should have been allocated with size max_depth, stack[0] should
2089 * be setup to the key we are investigating, so the minimal depth
2090 * we should ever see in this function is 1.
2091 * Returns: a new tree
2092 * certchain_set must be a valid set or point to NULL; this function
2095 * Fixme: add a fastscan mode which stops ad valid validity nodes.
2098 build_cert_tree( ulong lid, int depth, int max_depth, TN helproot )
2105 if( depth >= max_depth )
2112 if( !qry_lid_table_flag( ultikey_table, lid, NULL ) ) {
2113 /* this is an ultimately trusted key;
2114 * which means that we have found the end of the chain:
2115 * We do this here prior to reading the dir record
2116 * because we don't really need the info from that record */
2117 keynode->n.k.ownertrust = TRUST_ULTIMATE;
2118 keynode->n.k.buckstop = 1;
2121 read_record( lid, &dirrec, 0 );
2122 if( dirrec.rectype != RECTYPE_DIR ) {
2123 if( dirrec.rectype != RECTYPE_SDIR )
2124 log_debug("lid %lu, has rectype %d"
2125 " - skipped\n", lid, dirrec.rectype );
2129 keynode->n.k.ownertrust = dirrec.r.dir.ownertrust;
2131 /* loop over all user ids */
2132 for( uidrno = dirrec.r.dir.uidlist; uidrno; uidrno = uidrec.r.uid.next ) {
2137 read_record( uidrno, &uidrec, RECTYPE_UID );
2139 if( !(uidrec.r.uid.uidflags & UIDF_CHECKED) )
2140 continue; /* user id has not been checked */
2141 if( !(uidrec.r.uid.uidflags & UIDF_VALID) )
2142 continue; /* user id is not valid */
2143 if( (uidrec.r.uid.uidflags & UIDF_REVOKED) )
2144 continue; /* user id has been revoked */
2146 /* loop over all signature records */
2147 for(sigrno=uidrec.r.uid.siglist; sigrno; sigrno = sigrec.r.sig.next ) {
2151 read_record( sigrno, &sigrec, RECTYPE_SIG );
2153 for(i=0; i < SIGS_PER_RECORD; i++ ) {
2154 if( !sigrec.r.sig.sig[i].lid )
2155 continue; /* skip deleted sigs */
2156 if( !(sigrec.r.sig.sig[i].flag & SIGF_CHECKED) )
2157 continue; /* skip unchecked signatures */
2158 if( !(sigrec.r.sig.sig[i].flag & SIGF_VALID) )
2159 continue; /* skip invalid signatures */
2160 if( (sigrec.r.sig.sig[i].flag & SIGF_EXPIRED) )
2161 continue; /* skip expired signatures */
2162 if( (sigrec.r.sig.sig[i].flag & SIGF_REVOKED) )
2163 continue; /* skip revoked signatures */
2164 /* check for cycles */
2165 for( tn=keynode; tn && tn->lid != sigrec.r.sig.sig[i].lid;
2169 continue; /* cycle found */
2171 tn = build_cert_tree( sigrec.r.sig.sig[i].lid,
2172 depth+1, max_depth, helproot );
2174 continue; /* cert chain too deep or error */
2178 uidnode->back = keynode;
2179 uidnode->lid = uidrno;
2180 uidnode->is_uid = 1;
2181 uidnode->next = keynode->list;
2182 keynode->list = uidnode;
2186 tn->next = uidnode->list;
2188 #if 0 /* optimazation - fixme: reenable this later */
2189 if( tn->n.k.buckstop ) {
2190 /* ultimately trusted key found:
2191 * no need to check more signatures of this uid */
2192 sigrec.r.sig.next = 0;
2197 } /* end loop over sig recs */
2198 } /* end loop over user ids */
2200 if( !keynode->list ) {
2201 release_tn_tree( keynode );
2210 upd_one_ownertrust( ulong lid, unsigned new_trust, unsigned *retflgs )
2214 read_record( lid, &rec, RECTYPE_DIR );
2216 log_debug("upd_one_ownertrust of %lu from %u to %u\n",
2217 lid, (unsigned)rec.r.dir.ownertrust, new_trust );
2219 if( new_trust > rec.r.dir.ownertrust )
2220 *retflgs |= 16; /* modified up */
2222 *retflgs |= 32; /* modified down */
2224 rec.r.dir.ownertrust = new_trust;
2225 write_record( &rec );
2229 * Update the ownertrust in the complete tree.
2232 propagate_ownertrust( TN kr, ulong lid, unsigned trust )
2236 for( ; kr; kr = kr->next ) {
2237 if( kr->lid == lid )
2238 kr->n.k.ownertrust = trust;
2239 for( ur=kr->list; ur; ur = ur->next )
2240 propagate_ownertrust( ur->list, lid, trust );
2245 * Calculate the validity of all keys in the tree and especially
2246 * the one of the top key. If add_fnc is not NULL, it is used to
2247 * ask for missing ownertrust values (but only if this will help
2248 * us to increase the validity.
2249 * add_fnc is expected to take the LID of the key under question
2250 * and return a ownertrust value or an error: positive values
2251 * are assumed to be the new ownertrust value; a 0 does mean no change,
2252 * a -1 is a request to cancel this validation procedure, a -2 requests
2253 * a listing of the sub-tree using the tty functions.
2259 propagate_validity( TN root, TN node, int (*add_fnc)(ulong), unsigned *retflgs )
2262 int max_validity = 0;
2264 assert( !node->is_uid );
2265 if( node->n.k.ownertrust == TRUST_ULTIMATE ) {
2266 /* this is one of our keys */
2267 assert( !node->list ); /* it should be a leaf */
2268 node->n.k.validity = TRUST_ULTIMATE;
2270 *retflgs |= 1; /* found a path to an ultimately trusted key */
2274 /* loop over all user ids */
2275 for( ur=node->list; ur; ur = ur->next ) {
2276 assert( ur->is_uid );
2277 /* loop over all signators */
2278 for(kr=ur->list; kr; kr = kr->next ) {
2279 if( propagate_validity( root, kr, add_fnc, retflgs ) )
2280 return -1; /* quit */
2281 if( kr->n.k.validity == TRUST_ULTIMATE ) {
2282 ur->n.u.fully_count = opt.completes_needed;
2284 else if( kr->n.k.validity == TRUST_FULLY ) {
2285 if( add_fnc && !kr->n.k.ownertrust ) {
2289 *retflgs |= 2; /* found key with undefined ownertrust*/
2291 rc = add_fnc( kr->lid );
2294 case TRUST_MARGINAL:
2296 propagate_ownertrust( root, kr->lid, rc );
2297 upd_one_ownertrust( kr->lid, rc, retflgs );
2299 *retflgs |= 4; /* changed */
2302 return -1; /* cancel */
2304 dump_tn_tree( NULL, 0, kr );
2310 } while( rc == -2 );
2312 if( kr->n.k.ownertrust == TRUST_FULLY )
2313 ur->n.u.fully_count++;
2314 else if( kr->n.k.ownertrust == TRUST_MARGINAL )
2315 ur->n.u.marginal_count++;
2318 /* fixme: We can move this test into the loop to stop as soon as
2319 * we have a level of FULLY and return from this function
2320 * We dont do this now to get better debug output */
2321 if( ur->n.u.fully_count >= opt.completes_needed
2322 || ur->n.u.marginal_count >= opt.marginals_needed )
2323 ur->n.u.validity = TRUST_FULLY;
2324 else if( ur->n.u.fully_count || ur->n.u.marginal_count )
2325 ur->n.u.validity = TRUST_MARGINAL;
2327 if( ur->n.u.validity >= max_validity )
2328 max_validity = ur->n.u.validity;
2331 node->n.k.validity = max_validity;
2338 * Given the directory record of a key, check whether we can
2339 * find a path to an ultimately trusted key. We do this by
2340 * checking all key signatures up to a some depth.
2343 verify_key( int max_depth, TRUSTREC *drec, const char *namehash,
2344 int (*add_fnc)(ulong), unsigned *retflgs )
2350 tree = build_cert_tree( drec->r.dir.lid, 0, opt.max_cert_depth, NULL );
2352 return TRUST_UNDEFINED;
2353 pv_result = propagate_validity( tree, tree, add_fnc, retflgs );
2355 /* find the matching user id.
2356 * fixme: the way we handle this is too inefficient */
2361 for( ur=tree->list; ur; ur = ur->next ) {
2362 read_record( ur->lid, &rec, RECTYPE_UID );
2363 if( !memcmp( namehash, rec.r.uid.namehash, 20 ) ) {
2364 keytrust = ur->n.u.validity;
2370 keytrust = tree->n.k.validity;
2372 /* update the cached validity values */
2374 && keytrust >= TRUST_UNDEFINED
2375 && tdbio_db_matches_options()
2376 && ( !drec->r.dir.valcheck || drec->r.dir.validity != keytrust ) ) {
2380 for( ur=tree->list; ur; ur = ur->next ) {
2381 read_record( ur->lid, &rec, RECTYPE_UID );
2382 if( rec.r.uid.validity != ur->n.u.validity ) {
2383 rec.r.uid.validity = ur->n.u.validity;
2384 write_record( &rec );
2388 drec->r.dir.validity = tree->n.k.validity;
2389 drec->r.dir.valcheck = make_timestamp();
2390 write_record( drec );
2394 release_tn_tree( tree );
2400 * we have the pubkey record and all needed informations are in the trustdb
2401 * but nothing more is known.
2404 do_check( TRUSTREC *dr, unsigned *validity,
2405 const char *namehash, int (*add_fnc)(ulong), unsigned *retflgs )
2407 if( !dr->r.dir.keylist ) {
2408 log_error(_("Ooops, no keys\n"));
2409 return G10ERR_TRUSTDB;
2411 if( !dr->r.dir.uidlist ) {
2412 log_error(_("Ooops, no user ids\n"));
2413 return G10ERR_TRUSTDB;
2417 *retflgs &= ~(16|32); /* reset the 2 special flags */
2421 /* Fixme: use the cache */
2422 *validity = verify_key( opt.max_cert_depth, dr, namehash,
2426 && tdbio_db_matches_options()
2427 && dr->r.dir.valcheck
2428 > tdbio_read_modify_stamp( (dr->r.dir.validity < TRUST_FULLY) )
2429 && dr->r.dir.validity )
2430 *validity = dr->r.dir.validity;
2432 *validity = verify_key( opt.max_cert_depth, dr, NULL,
2435 if( !(*validity & TRUST_MASK) )
2436 *validity = TRUST_UNDEFINED;
2438 if( dr->r.dir.dirflags & DIRF_REVOKED )
2439 *validity |= TRUST_FLAG_REVOKED;
2441 /* If we have changed some ownertrusts, set the trustdb timestamps
2443 if( retflgs && (*retflgs & (16|32)) ) {
2444 tdbio_write_modify_stamp( (*retflgs & 16), (*retflgs & 32) );
2454 /***********************************************
2455 ********* Change trustdb values **************
2456 ***********************************************/
2459 update_ownertrust( ulong lid, unsigned new_trust )
2464 read_record( lid, &rec, RECTYPE_DIR );
2466 log_debug("update_ownertrust of %lu from %u to %u\n",
2467 lid, (unsigned)rec.r.dir.ownertrust, new_trust );
2468 rec.r.dir.ownertrust = new_trust;
2469 write_record( &rec );
2476 clear_trust_checked_flag( PKT_public_key *pk )
2485 rc = get_dir_record( pk, &rec );
2489 /* check whether they are already reset */
2490 if( !(rec.r.dir.dirflags & DIRF_CHECKED) && !rec.r.dir.valcheck )
2493 /* reset the flag */
2494 rec.r.dir.dirflags &= ~DIRF_CHECKED;
2495 rec.r.dir.valcheck = 0;
2496 write_record( &rec );
2503 * Put new entries from the pubrings into the trustdb.
2504 * This function honors the sig flags to speed up the check.
2509 KBNODE keyblock = NULL;
2517 rc = enum_keyblocks( 0, &kbpos, &keyblock );
2519 ulong count=0, upd_count=0, err_count=0, new_count=0;
2521 while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
2524 rc = update_trust_record( keyblock, 1, &modified );
2525 if( rc == -1 ) { /* not yet in trustdb: insert */
2526 PKT_public_key *pk = keyblock->pkt->pkt.public_key;
2527 rc = insert_trust_record( pk );
2528 if( rc && !pk->local_id ) {
2529 log_error(_("lid ?: insert failed: %s\n"),
2534 log_error(_("lid %lu: insert failed: %s\n"),
2535 pk->local_id, g10_errstr(rc) );
2540 log_info(_("lid %lu: inserted\n"), pk->local_id );
2545 log_error(_("lid %lu: update failed: %s\n"),
2546 lid_from_keyblock(keyblock), g10_errstr(rc) );
2549 else if( modified ) {
2551 log_info(_("lid %lu: updated\n"),
2552 lid_from_keyblock(keyblock));
2555 else if( opt.verbose > 1 )
2556 log_info(_("lid %lu: okay\n"), lid_from_keyblock(keyblock) );
2558 release_kbnode( keyblock ); keyblock = NULL;
2559 if( !(++count % 100) )
2560 log_info(_("%lu keys so far processed\n"), count);
2562 log_info(_("%lu keys processed\n"), count);
2564 log_info(_("\t%lu keys with errors\n"), err_count);
2566 log_info(_("\t%lu keys updated\n"), upd_count);
2568 log_info(_("\t%lu keys inserted\n"), new_count);
2570 if( rc && rc != -1 )
2571 log_error(_("enumerate keyblocks failed: %s\n"), g10_errstr(rc));
2573 enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
2574 release_kbnode( keyblock );
2578 * Check the complete trustdb or only the entries for the given username.
2579 * We check the complete database. If a username is given or the special
2580 * username "*" is used, a complete recheck is done. With no user ID
2581 * only the records which are not yet checkd are now checked.
2584 check_trustdb( const char *username )
2587 KBNODE keyblock = NULL;
2590 int recheck = username && *username == '*' && !username[1];
2593 if( username && !recheck ) {
2594 rc = find_keyblock_byname( &kbpos, username );
2596 rc = read_keyblock( &kbpos, &keyblock );
2598 log_error(_("%s: keyblock read problem: %s\n"),
2599 username, g10_errstr(rc));
2604 rc = update_trust_record( keyblock, 1, &modified );
2605 if( rc == -1 ) { /* not yet in trustdb: insert */
2606 rc = insert_trust_record(
2607 find_kbnode( keyblock, PKT_PUBLIC_KEY
2608 ) ->pkt->pkt.public_key );
2612 log_error(_("%s: update failed: %s\n"),
2613 username, g10_errstr(rc) );
2615 log_info(_("%s: updated\n"), username );
2617 log_info(_("%s: okay\n"), username );
2620 release_kbnode( keyblock ); keyblock = NULL;
2624 ulong count=0, upd_count=0, err_count=0, skip_count=0;
2626 for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
2627 if( rec.rectype == RECTYPE_DIR ) {
2631 if( !rec.r.dir.keylist ) {
2632 log_info(_("lid %lu: dir record w/o key - skipped\n"),
2639 read_record( rec.r.dir.keylist, &tmp, RECTYPE_KEY );
2641 rc = get_keyblock_byfprint( &keyblock,
2642 tmp.r.key.fingerprint,
2643 tmp.r.key.fingerprint_len );
2645 log_error(_("lid %lu: keyblock not found: %s\n"),
2646 recnum, g10_errstr(rc) );
2652 rc = update_trust_record( keyblock, recheck, &modified );
2654 log_error(_("lid %lu: update failed: %s\n"),
2655 recnum, g10_errstr(rc) );
2658 else if( modified ) {
2660 log_info(_("lid %lu: updated\n"), recnum );
2663 else if( opt.verbose > 1 )
2664 log_info(_("lid %lu: okay\n"), recnum );
2666 release_kbnode( keyblock ); keyblock = NULL;
2667 if( !(++count % 100) )
2668 log_info(_("%lu keys so far processed\n"), count);
2671 log_info(_("%lu keys processed\n"), count);
2673 log_info(_("\t%lu keys skipped\n"), skip_count);
2675 log_info(_("\t%lu keys with errors\n"), err_count);
2677 log_info(_("\t%lu keys updated\n"), upd_count);
2683 /***********************************************
2684 ********* Query trustdb values **************
2685 ***********************************************/
2689 * This function simply looks for the key in the trustdb
2690 * and makes sure that pk->local_id is set to the correct value.
2696 query_trust_record( PKT_public_key *pk )
2700 return get_dir_record( pk, &rec );
2705 * Get the trustlevel for this PK.
2706 * Note: This does not ask any questions
2707 * Returns: 0 okay of an errorcode
2709 * It operates this way:
2710 * locate the pk in the trustdb
2712 * Do we have a valid cache record for it?
2713 * yes: return trustlevel from cache
2714 * no: make a cache record and all the other stuff
2716 * try to insert the pubkey into the trustdb and check again
2718 * Problems: How do we get the complete keyblock to check that the
2719 * cache record is actually valid? Think we need a clever
2720 * cache in getkey.c to keep track of this stuff. Maybe it
2721 * is not necessary to check this if we use a local pubring. Hmmmm.
2724 check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
2725 const byte *namehash, int (*add_fnc)(ulong), unsigned *retflgs )
2728 unsigned trustlevel = TRUST_UNKNOWN;
2735 keyid_from_pk( pk, keyid );
2737 /* get the pubkey record */
2738 if( pk->local_id ) {
2739 read_record( pk->local_id, &rec, RECTYPE_DIR );
2741 else { /* no local_id: scan the trustdb */
2742 if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) {
2743 log_error(_("check_trust: search dir record failed: %s\n"),
2747 else if( rc == -1 ) { /* not found - insert */
2748 rc = insert_trust_record( pk );
2750 log_error(_("key %08lX: insert trust record failed: %s\n"),
2751 (ulong)keyid[1], g10_errstr(rc));
2754 log_info(_("key %08lX.%lu: inserted into trustdb\n"),
2755 (ulong)keyid[1], pk->local_id );
2756 /* and re-read the dir record */
2757 read_record( pk->local_id, &rec, RECTYPE_DIR );
2760 cur_time = make_timestamp();
2761 if( pk->timestamp > cur_time ) {
2762 log_info(_("key %08lX.%lu: created in future "
2763 "(time warp or clock problem)\n"),
2764 (ulong)keyid[1], pk->local_id );
2765 return G10ERR_TIME_CONFLICT;
2768 if( pk->expiredate && pk->expiredate <= cur_time ) {
2769 log_info(_("key %08lX.%lu: expired at %s\n"),
2770 (ulong)keyid[1], pk->local_id,
2771 asctimestamp( pk->expiredate) );
2772 trustlevel = TRUST_EXPIRED;
2775 rc = do_check( &rec, &trustlevel, namehash, add_fnc, retflgs );
2777 log_error(_("key %08lX.%lu: trust check failed: %s\n"),
2778 (ulong)keyid[1], pk->local_id, g10_errstr(rc));
2786 log_debug("check_trust() returns trustlevel %04x.\n", trustlevel);
2787 *r_trustlevel = trustlevel;
2793 query_trust_info( PKT_public_key *pk, const byte *namehash )
2795 unsigned trustlevel;
2799 if( check_trust( pk, &trustlevel, namehash, NULL, NULL ) )
2801 if( trustlevel & TRUST_FLAG_REVOKED )
2803 c = trust_letter( (trustlevel & TRUST_MASK) );
2812 * Return the assigned ownertrust value for the given LID
2815 get_ownertrust( ulong lid )
2820 read_record( lid, &rec, RECTYPE_DIR );
2821 return rec.r.dir.ownertrust;
2825 get_ownertrust_info( ulong lid )
2831 otrust = get_ownertrust( lid );
2832 c = trust_letter( (otrust & TRUST_MASK) );
2841 list_trust_path( const char *username )
2847 PKT_public_key *pk = m_alloc_clear( sizeof *pk );
2850 if( (rc = get_pubkey_byname(NULL, pk, username, NULL )) )
2851 log_error(_("user '%s' not found: %s\n"), username, g10_errstr(rc) );
2852 else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
2853 log_error(_("problem finding '%s' in trustdb: %s\n"),
2854 username, g10_errstr(rc));
2855 else if( rc == -1 ) {
2856 log_info(_("user '%s' not in trustdb - inserting\n"), username);
2857 rc = insert_trust_record( pk );
2859 log_error(_("failed to put '%s' into trustdb: %s\n"),
2860 username, g10_errstr(rc));
2862 assert( pk->local_id );
2867 tree = build_cert_tree( lid, 0, opt.max_cert_depth, NULL );
2869 propagate_validity( tree, tree, NULL, NULL );
2870 if( opt.with_colons )
2871 dump_tn_tree_with_colons( 0, tree );
2873 dump_tn_tree( stdout, 0, tree );
2874 /*printf("(alloced tns=%d max=%d)\n", alloced_tns, max_alloced_tns );*/
2875 release_tn_tree( tree );
2876 /*printf("Ownertrust=%c Validity=%c\n", get_ownertrust_info( lid ),
2877 query_trust_info( pk, NULL ) ); */
2879 free_public_key( pk );
2887 * Enumerate all keys, which are needed to build all trust paths for
2888 * the given key. This function does not return the key itself or
2889 * the ultimate key (the last point in cerificate chain). Only
2890 * certificate chains which ends up at an ultimately trusted key
2891 * are listed. If ownertrust or validity is not NULL, the corresponding
2892 * value for the returned LID is also returned in these variable(s).
2894 * 1) create a void pointer and initialize it to NULL
2895 * 2) pass this void pointer by reference to this function.
2896 * Set lid to the key you want to enumerate and pass it by reference.
2897 * 3) call this function as long as it does not return -1
2898 * to indicate EOF. LID does contain the next key used to build the web
2899 * 4) Always call this function a last time with LID set to NULL,
2900 * so that it can free its context.
2902 * Returns: -1 on EOF or the level of the returned LID
2905 enum_cert_paths( void **context, ulong *lid,
2906 unsigned *ownertrust, unsigned *validity )
2910 struct enum_cert_paths_ctx *ctx;
2914 if( !lid ) { /* release the context */
2916 FIXME: ........tsl2;
2919 for(tsl = ctx->tsl_head; tsl; tsl = tsl2 ) {
2929 FIXME .... *tmppath;
2935 ctx = m_alloc_clear( sizeof *ctx );
2937 /* collect the paths */
2939 read_record( *lid, &rec, RECTYPE_DIR );
2940 tmppath = m_alloc_clear( (opt.max_cert_depth+1)* sizeof *tmppath );
2942 collect_paths( 0, opt.max_cert_depth, 1, &rec, tmppath, &tsl );
2944 sort_tsl_list( &tsl );
2946 /* setup the context */
2947 ctx->tsl_head = tsl;
2948 ctx->tsl = ctx->tsl_head;
2954 while( ctx->tsl && ctx->idx >= ctx->tsl->pathlen ) {
2955 ctx->tsl = ctx->tsl->next;
2960 return -1; /* eof */
2963 *ownertrust = tsl->path[ctx->idx].otrust;
2965 *validity = tsl->path[ctx->idx].trust;
2966 *lid = tsl->path[ctx->idx].lid;
2974 * Print the current path
2977 enum_cert_paths_print( void **context, FILE *fp,
2978 int refresh, ulong selected_lid )
2982 struct enum_cert_paths_ctx *ctx;
2996 if( refresh ) { /* update the ownertrust and if possible the validity */
2998 int match = tdbio_db_matches_options();
3000 for( i = 0; i < tsl->pathlen; i++ ) {
3003 read_record( tsl->path[i].lid, &rec, RECTYPE_DIR );
3004 tsl->path[i].otrust = rec.r.dir.ownertrust;
3005 /* update validity only if we have it in the cache
3006 * calculation is too time consuming */
3007 if( match && rec.r.dir.valcheck && rec.r.dir.validity ) {
3008 tsl->path[i].trust = rec.r.dir.validity;
3009 if( rec.r.dir.dirflags & DIRF_REVOKED )
3010 tsl->path[i].trust = TRUST_FLAG_REVOKED;
3015 print_path( tsl->pathlen, tsl->path, fp, selected_lid );
3021 * Return an allocated buffer with the preference values for
3022 * the key with LID and the userid which is identified by the
3023 * HAMEHASH or the firstone if namehash is NULL. ret_n receives
3024 * the length of the allocated buffer. Structure of the buffer is
3025 * a repeated sequences of 2 bytes; where the first byte describes the
3026 * type of the preference and the second one the value. The constants
3027 * PREFTYPE_xxxx should be used to reference a type.
3030 get_pref_data( ulong lid, const byte *namehash, size_t *ret_n )
3036 read_record( lid, &rec, RECTYPE_DIR );
3037 for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
3038 read_record( recno, &rec, RECTYPE_UID );
3039 if( rec.r.uid.prefrec
3040 && ( !namehash || !memcmp(namehash, rec.r.uid.namehash, 20) )) {
3042 /* found the correct one or the first one */
3043 read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
3044 if( rec.r.pref.next )
3045 log_info(_("WARNING: can't yet handle long pref records\n"));
3046 buf = m_alloc( ITEMS_PER_PREF_RECORD );
3047 memcpy( buf, rec.r.pref.data, ITEMS_PER_PREF_RECORD );
3048 *ret_n = ITEMS_PER_PREF_RECORD;
3058 * Check whether the algorithm is in one of the pref records
3061 is_algo_in_prefs( ulong lid, int preftype, int algo )
3069 read_record( lid, &rec, RECTYPE_DIR );
3070 for( recno=rec.r.dir.uidlist; recno; recno = rec.r.uid.next ) {
3071 read_record( recno, &rec, RECTYPE_UID );
3072 if( rec.r.uid.prefrec ) {
3073 read_record( rec.r.uid.prefrec, &rec, RECTYPE_PREF );
3074 if( rec.r.pref.next )
3075 log_info(_("WARNING: can't yet handle long pref records\n"));
3076 pref = rec.r.pref.data;
3077 for(i=0; i+1 < ITEMS_PER_PREF_RECORD; i+=2 ) {
3078 if( pref[i] == preftype && pref[i+1] == algo )