aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog28
-rw-r--r--g10/armor.c4
-rw-r--r--g10/encode.c20
-rw-r--r--g10/g10.c1
-rw-r--r--g10/getkey.c29
-rw-r--r--g10/keydb.h1
-rw-r--r--g10/mainproc.c14
-rw-r--r--g10/passphrase.c19
-rw-r--r--g10/pkclist.c138
-rw-r--r--g10/seckey-cert.c9
-rw-r--r--g10/status.c5
-rw-r--r--g10/status.h5
-rw-r--r--g10/tdbio.c7
-rw-r--r--g10/tdbio.h2
-rw-r--r--g10/trustdb.c375
-rw-r--r--g10/trustdb.h3
16 files changed, 487 insertions, 173 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 2e682f353..ea1133cc1 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,31 @@
+Wed Mar 17 13:09:03 CET 1999 Werner Koch <[email protected]>
+
+ * trustdb.c (check_trust): add new arg add_fnc and changed all callers.
+ (do_check): Ditto.
+ (verify_key): Ditto.
+ (propagate_validity): Use the new add_fnc arg.
+ (print_user_id): Add the FILE arg.
+ (propagate_ownertrust): New.
+ * pkclist.c (add_ownertrust_cb): New and changed the add_ownertrust
+ logic.
+
+ * getkey.c (get_keyblock_bylid): New.
+ * trustdb.c (print_uid_from_keyblock): New.
+ (dump_tn_tree_with_colons): New.
+ (list_trust_path): Add colon print mode.
+
+ * trustdb.c (insert_trust_record): Always use the primary key.
+
+ * encode.c (encode_simple): Added text_mode filter (R�mi Guyomarch)
+ (encode_crypt): Ditto.
+
+ * mainproc.c (proc_pubkey_enc): Added status ENC_TO.
+ * armor.c (armor_filter): Added status NODATA.
+ * passphrase.c (passphrase_to_dek): Always print NEED_PASSPHRASE
+ * seckey_cert.c (check_secret_key): Added BAD_PASS status.
+
+ * g10.c (main): Set g10_opt_homedir.
+
Sun Mar 14 19:34:36 CET 1999 Werner Koch <[email protected]>
* keygen.c (do_create): Changed wording of the note (Hugh Daniel)
diff --git a/g10/armor.c b/g10/armor.c
index 1a3e6e5ba..a6daf7110 100644
--- a/g10/armor.c
+++ b/g10/armor.c
@@ -989,8 +989,10 @@ armor_filter( void *opaque, int control,
iobuf_writestr(a, tail_strings[afx->what] );
iobuf_writestr(a, "-----\n");
}
- else if( !afx->any_data && !afx->inp_bypass )
+ else if( !afx->any_data && !afx->inp_bypass ) {
log_error(_("no valid OpenPGP data found.\n"));
+ write_status_text( STATUS_NODATA, "1" );
+ }
if( afx->truncated )
log_info(_("invalid armor: line longer than %d characters\n"),
MAX_LINELEN );
diff --git a/g10/encode.c b/g10/encode.c
index aba251a20..825a4c98a 100644
--- a/g10/encode.c
+++ b/g10/encode.c
@@ -76,11 +76,13 @@ encode_simple( const char *filename, int mode )
cipher_filter_context_t cfx;
armor_filter_context_t afx;
compress_filter_context_t zfx;
+ text_filter_context_t tfx;
int do_compress = opt.compress && !opt.rfc1991;
memset( &cfx, 0, sizeof cfx);
memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx);
+ memset( &tfx, 0, sizeof tfx);
init_packet(&pkt);
/* prepare iobufs */
@@ -90,6 +92,9 @@ encode_simple( const char *filename, int mode )
return G10ERR_OPEN_FILE;
}
+ if( opt.textmode )
+ iobuf_push_filter( inp, text_filter, &tfx );
+
cfx.dek = NULL;
if( mode ) {
s2k = m_alloc_clear( sizeof *s2k );
@@ -151,19 +156,19 @@ encode_simple( const char *filename, int mode )
pt->namelen = 0;
}
/* pgp5 has problems to decrypt symmetrically encrypted data from
- * GnuPOG if the filelength is in the inner packet. It works
+ * GnuPG if the filelength is in the inner packet. It works
* when only partial length headers are use. Until we have
* tracked this problem down. We use this temporary fix
* (fixme: remove the && !mode )
*/
- if( filename && !mode ) {
+ if( filename && !opt.textmode && !mode ) {
if( !(filesize = iobuf_get_filelength(inp)) )
log_info(_("%s: WARNING: empty file\n"), filename );
}
else
filesize = 0; /* stdin */
pt->timestamp = make_timestamp();
- pt->mode = 'b';
+ pt->mode = opt.textmode? 't' : 'b';
pt->len = filesize;
pt->buf = inp;
pkt.pkttype = PKT_PLAINTEXT;
@@ -206,12 +211,14 @@ encode_crypt( const char *filename, STRLIST remusr )
cipher_filter_context_t cfx;
armor_filter_context_t afx;
compress_filter_context_t zfx;
+ text_filter_context_t tfx;
PK_LIST pk_list;
int do_compress = opt.compress && !opt.rfc1991;
memset( &cfx, 0, sizeof cfx);
memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx);
+ memset( &tfx, 0, sizeof tfx);
init_packet(&pkt);
if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
@@ -227,6 +234,9 @@ encode_crypt( const char *filename, STRLIST remusr )
else if( opt.verbose )
log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");
+ if( opt.textmode )
+ iobuf_push_filter( inp, text_filter, &tfx );
+
if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
goto leave;
@@ -270,14 +280,14 @@ encode_crypt( const char *filename, STRLIST remusr )
pt = m_alloc( sizeof *pt - 1 );
pt->namelen = 0;
}
- if( filename ) {
+ if( filename && !opt.textmode ) {
if( !(filesize = iobuf_get_filelength(inp)) )
log_info(_("%s: WARNING: empty file\n"), filename );
}
else
filesize = 0; /* stdin */
pt->timestamp = make_timestamp();
- pt->mode = 'b';
+ pt->mode = opt.textmode ? 't' : 'b';
pt->len = filesize;
pt->new_ctb = !pt->len && !opt.rfc1991;
pt->buf = inp;
diff --git a/g10/g10.c b/g10/g10.c
index 06d660e7b..c78cb34e9 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -824,6 +824,7 @@ main( int argc, char **argv )
secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
set_debug();
+ g10_opt_homedir = opt.homedir;
/* must do this after dropping setuid, because string_to...
* may try to load an module */
diff --git a/g10/getkey.c b/g10/getkey.c
index 424590ed2..4d16ecd84 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -31,6 +31,7 @@
#include "keydb.h"
#include "options.h"
#include "main.h"
+#include "trustdb.h"
#include "i18n.h"
#define MAX_UNK_CACHE_ENTRIES 1000 /* we use a linked list - so I guess
@@ -832,6 +833,34 @@ get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
+/****************
+ * Search for a key with the given lid and return the complete keyblock
+ */
+int
+get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid )
+{
+ int rc;
+ PKT_public_key *pk = m_alloc_clear( sizeof *pk );
+ struct getkey_ctx_s ctx;
+ u32 kid[2];
+
+ if( keyid_from_lid( lid, kid ) )
+ kid[0] = kid[1] = 0;
+ memset( &ctx, 0, sizeof ctx );
+ ctx.not_allocated = 1;
+ ctx.nitems = 1;
+ ctx.items[0].mode = 12;
+ ctx.items[0].keyid[0] = kid[0];
+ ctx.items[0].keyid[1] = kid[1];
+ rc = lookup_pk( &ctx, pk, ret_keyblock );
+ get_pubkey_end( &ctx );
+
+ free_public_key( pk );
+ return rc;
+}
+
+
+
/****************
diff --git a/g10/keydb.h b/g10/keydb.h
index 43862d2cb..88bdccf0d 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -144,6 +144,7 @@ int get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint,
size_t fprint_len );
int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
size_t fprint_len );
+int get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid );
int seckey_available( u32 *keyid );
int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock );
int get_seckey_bynames( GETKEY_CTX *rx, PKT_secret_key *sk,
diff --git a/g10/mainproc.c b/g10/mainproc.c
index c41e72352..dd91fcc5e 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -182,6 +182,14 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
* function to check it. */
if( opt.verbose )
log_info(_("public key is %08lX\n"), (ulong)enc->keyid[1] );
+
+ if( is_status_enabled() ) {
+ char buf[50];
+ sprintf(buf, "%08lX%08lX", (ulong)enc->keyid[0], (ulong)enc->keyid[1]);
+ write_status_text( STATUS_ENC_TO, buf );
+ }
+
+
if( is_ELGAMAL(enc->pubkey_algo)
|| enc->pubkey_algo == PUBKEY_ALGO_DSA
|| is_RSA(enc->pubkey_algo) ) {
@@ -914,7 +922,11 @@ check_sig_and_print( CTX c, KBNODE node )
g10_exit(1);
}
else {
- write_status( STATUS_ERRSIG );
+ char buf[50];
+ sprintf(buf, "%08lX%08lX %d",
+ (ulong)sig->keyid[0], (ulong)sig->keyid[1],
+ sig->pubkey_algo );
+ write_status_text( STATUS_ERRSIG, buf );
log_error(_("Can't check signature: %s\n"), g10_errstr(rc) );
}
return rc;
diff --git a/g10/passphrase.c b/g10/passphrase.c
index 785d21df5..6da528015 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -133,6 +133,16 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
:DEFAULT_DIGEST_ALGO;
}
+ if( keyid && !next_pw && is_status_enabled() ) {
+ char buf[50];
+ sprintf( buf, "%08lX%08lX", (ulong)keyid[0], (ulong)keyid[1] );
+ if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
+ && keyid[1] != keyid[3] )
+ sprintf( buf+strlen(buf), " %08lX%08lX",
+ (ulong)keyid[2], (ulong)keyid[3] );
+ write_status_text( STATUS_NEED_PASSPHRASE, buf );
+ }
+
if( keyid && !opt.batch && !next_pw ) {
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
size_t n;
@@ -159,15 +169,6 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
tty_printf("\n");
free_public_key( pk );
}
- else if( keyid && !next_pw ) {
- char buf[50];
- sprintf( buf, "%08lX%08lX", (ulong)keyid[0], (ulong)keyid[1] );
- if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
- && keyid[1] != keyid[3] )
- sprintf( buf+strlen(buf), " %08lX%08lX",
- (ulong)keyid[2], (ulong)keyid[3] );
- write_status_text( STATUS_NEED_PASSPHRASE, buf );
- }
if( next_pw ) {
pw = next_pw;
diff --git a/g10/pkclist.c b/g10/pkclist.c
index fffaef821..57c36cee2 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -107,8 +107,8 @@ show_paths( ulong lid, int only_first )
/****************
* Returns true if an ownertrust has changed.
*/
-int
-edit_ownertrust( ulong lid, int mode )
+static int
+do_edit_ownertrust( ulong lid, int mode, unsigned *new_trust )
{
char *p;
int rc;
@@ -117,6 +117,7 @@ edit_ownertrust( ulong lid, int mode )
PKT_public_key *pk ;
int changed=0;
int quit=0;
+ int show=0;
rc = keyid_from_lid( lid, keyid );
if( rc ) {
@@ -177,14 +178,15 @@ edit_ownertrust( ulong lid, int mode )
case '4': trust = TRUST_FULLY ; break;
default: BUG();
}
- if( !update_ownertrust( lid, trust ) )
- changed++;
+ *new_trust = trust;
+ changed = 1;
break;
}
else if( *p == ans[0] || *p == ans[1] ) {
tty_printf(_(
"Certificates leading to an ultimately trusted key:\n"));
- show_paths( lid, 1 );
+ show = 1;
+ break;
}
else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) {
break ; /* back to the menu */
@@ -197,73 +199,71 @@ edit_ownertrust( ulong lid, int mode )
}
m_free(p);
m_free(pk);
- return quit? -1 : changed;
+ return show? -2: quit? -1 : changed;
+}
+
+
+int
+edit_ownertrust( ulong lid, int mode )
+{
+ unsigned trust;
+
+ for(;;) {
+ switch( do_edit_ownertrust( lid, mode, &trust ) ) {
+ case -1:
+ return 0;
+ case -2:
+ show_paths( lid, 1 );
+ break;
+ case 1:
+ if( !update_ownertrust( lid, trust ) )
+ return 1;
+ return 0;
+ default:
+ return 0;
+ }
+ }
}
+static int
+add_ownertrust_cb( ulong lid )
+{
+ unsigned trust;
+ int rc = do_edit_ownertrust( lid, 0, &trust );
+
+ if( rc == 1 )
+ return trust & TRUST_MASK;
+ return rc > 0? 0 : rc;
+}
/****************
* Try to add some more owner trusts (interactive)
* This function presents all the signator in a certificate
- * chain who have no trust value assigned.
+ * chain who have no ownertrust value assigned.
* Returns: -1 if no ownertrust were added.
*/
static int
-add_ownertrust( PKT_public_key *pk, int *quit )
+add_ownertrust( PKT_public_key *pk, int *quit, unsigned *trustlevel )
{
int rc;
- void *context = NULL;
- ulong lid;
- unsigned otrust, validity;
- int any=0, changed=0, any_undefined=0;
+ unsigned flags = 0;
*quit = 0;
+ *trustlevel = 0;
tty_printf(
_("Could not find a valid trust path to the key. Let's see whether we\n"
"can assign some missing owner trust values.\n\n"));
- rc = query_trust_record( pk );
- if( rc ) {
- log_error("Ooops: not in trustdb\n");
- return -1;
- }
-
- lid = pk->local_id;
- while( enum_cert_paths( &context, &lid, &otrust, &validity ) != -1 ) {
- if( lid == pk->local_id )
- continue;
- any=1;
- if( changed ) {
- /* because enum_cert_paths() makes a snapshop of the
- * trust paths, the otrust and validity are not anymore
- * valid after changing an entry - we have to reread
- * those values from then on
- */
- otrust = get_ownertrust( lid );
- /* fixme: and the validity? */
- }
- if( otrust == TRUST_UNDEFINED ) {
- any_undefined=1;
- enum_cert_paths_print( &context, NULL, changed, lid );
- tty_printf("\n");
- rc = edit_ownertrust( lid, 0 );
- if( rc == -1 ) {
- *quit = 1;
- break;
- }
- else if( rc > 0 )
- changed = 1;
- }
- }
- enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */
+ rc = check_trust( pk, trustlevel, NULL, add_ownertrust_cb, &flags );
- if( !any )
+ if( !(flags & 1) )
tty_printf(_("No path leading to one of our keys found.\n\n") );
- else if( !any_undefined )
+ else if( !(flags & 2) )
tty_printf(_("No certificates with undefined trust found.\n\n") );
- else if( !changed )
+ else if( !(flags & 4) )
tty_printf(_("No trust values changed.\n\n") );
- return changed? 0:-1;
+ return (flags & 4)? 0:-1;
}
/****************
@@ -274,7 +274,9 @@ static int
do_we_trust( PKT_public_key *pk, int trustlevel )
{
int rc;
+ int did_add = 0;
+ retry:
if( (trustlevel & TRUST_FLAG_REVOKED) ) {
log_info(_("key %08lX: key has been revoked!\n"),
(ulong)keyid_from_pk( pk, NULL) );
@@ -295,7 +297,7 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
g10_errstr(rc) );
return 0; /* no */
}
- rc = check_trust( pk, &trustlevel, NULL );
+ rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
if( rc )
log_fatal("trust check after insert failed: %s\n",
g10_errstr(rc) );
@@ -317,14 +319,10 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
else {
int quit;
- rc = add_ownertrust( pk, &quit );
- if( !rc && !quit ) {
- rc = check_trust( pk, &trustlevel, NULL );
- if( rc )
- log_fatal("trust check after add_ownertrust failed: %s\n",
- g10_errstr(rc) );
- /* fixme: this is recursive; we should unroll it */
- return do_we_trust( pk, trustlevel );
+ rc = add_ownertrust( pk, &quit, &trustlevel );
+ if( !rc && !did_add && !quit ) {
+ did_add = 1;
+ goto retry;
}
}
return 0;
@@ -353,10 +351,6 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
default: BUG();
}
-
- /* Eventuell fragen falls der trustlevel nicht ausreichend ist */
-
-
return 1; /* yes */
}
@@ -419,7 +413,7 @@ check_signatures_trust( PKT_signature *sig )
{
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
int trustlevel;
- int dont_try = 0;
+ int did_add = 0;
int rc=0;
rc = get_pubkey( pk, sig->keyid );
@@ -429,13 +423,13 @@ check_signatures_trust( PKT_signature *sig )
goto leave;
}
- retry:
- rc = check_trust( pk, &trustlevel, NULL );
+ rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
if( rc ) {
log_error("check trust failed: %s\n", g10_errstr(rc));
goto leave;
}
+ retry:
if( (trustlevel & TRUST_FLAG_REVOKED) ) {
write_status( STATUS_KEYREVOKED );
log_info(_("WARNING: This key has been revoked by its owner!\n"));
@@ -451,7 +445,7 @@ check_signatures_trust( PKT_signature *sig )
g10_errstr(rc) );
goto leave;
}
- rc = check_trust( pk, &trustlevel, NULL );
+ rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
if( rc )
log_fatal("trust check after insert failed: %s\n",
g10_errstr(rc) );
@@ -464,7 +458,7 @@ check_signatures_trust( PKT_signature *sig )
break;
case TRUST_UNDEFINED:
- if( dont_try || opt.batch || opt.answer_no ) {
+ if( did_add || opt.batch || opt.answer_no ) {
write_status( STATUS_TRUST_UNDEFINED );
log_info(_(
"WARNING: This key is not certified with a trusted signature!\n"));
@@ -474,9 +468,9 @@ check_signatures_trust( PKT_signature *sig )
}
else {
int quit;
- rc = add_ownertrust( pk, &quit );
+ rc = add_ownertrust( pk, &quit, &trustlevel );
if( rc || quit ) {
- dont_try = 1;
+ did_add = 1;
rc = 0;
}
goto retry;
@@ -591,7 +585,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) {
int trustlevel;
- rc = check_trust( pk, &trustlevel, NULL );
+ rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
if( rc ) {
log_error("error checking pk of `%s': %s\n",
answer, g10_errstr(rc) );
@@ -630,7 +624,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
int trustlevel;
- rc = check_trust( pk, &trustlevel, NULL );
+ rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
if( rc ) {
free_public_key( pk ); pk = NULL;
log_error(_("%s: error checking key: %s\n"),
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 661f1da43..7f0d41e33 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -32,6 +32,7 @@
#include "main.h"
#include "options.h"
#include "i18n.h"
+#include "status.h"
static int
@@ -175,6 +176,14 @@ check_secret_key( PKT_secret_key *sk, int n )
if( i )
log_info(_("Invalid passphrase; please try again ...\n"));
rc = do_check( sk );
+ if( rc == G10ERR_BAD_PASS && is_status_enabled() ) {
+ u32 kid[2];
+ char buf[50];
+
+ keyid_from_sk( sk, kid );
+ sprintf(buf, "%08lX%08lX", (ulong)kid[0], (ulong)kid[1]);
+ write_status_text( STATUS_BAD_PASSPHRASE, buf );
+ }
if( have_static_passphrase() )
break;
}
diff --git a/g10/status.c b/g10/status.c
index e34dda3d9..1b6dc1095 100644
--- a/g10/status.c
+++ b/g10/status.c
@@ -99,6 +99,11 @@ write_status_text ( int no, const char *text)
case STATUS_NEED_PASSPHRASE: s = "NEED_PASSPHRASE\n"; break;
case STATUS_VALIDSIG : s = "VALIDSIG\n"; break;
case STATUS_SIG_ID : s = "SIG_ID\n"; break;
+ case STATUS_ENC_TO : s = "ENC_TO\n"; break;
+ case STATUS_NODATA : s = "NODATA\n"; break;
+ case STATUS_BAD_PASSPHRASE : s = "BAD_PASSPHRASE\n"; break;
+ case STATUS_NO_PUBKEY : s = "NO_PUBKEY\n"; break;
+ case STATUS_NO_SECKEY : s = "NO_SECKEY\n"; break;
default: s = "?\n"; break;
}
diff --git a/g10/status.h b/g10/status.h
index 734c29983..7beb32123 100644
--- a/g10/status.h
+++ b/g10/status.h
@@ -50,6 +50,11 @@
#define STATUS_NEED_PASSPHRASE 20
#define STATUS_VALIDSIG 21
#define STATUS_SIG_ID 22
+#define STATUS_ENC_TO 23
+#define STATUS_NODATA 24
+#define STATUS_BAD_PASSPHRASE 25
+#define STATUS_NO_PUBKEY 26
+#define STATUS_NO_SECKEY 27
/*-- status.c --*/
void set_status_fd ( int fd );
diff --git a/g10/tdbio.c b/g10/tdbio.c
index 22592ae93..9bcb6aa14 100644
--- a/g10/tdbio.c
+++ b/g10/tdbio.c
@@ -633,12 +633,15 @@ tdbio_read_modify_stamp( int modify_down )
}
void
-tdbio_write_modify_stamp( int down, int up )
+tdbio_write_modify_stamp( int up, int down )
{
TRUSTREC vr;
int rc;
ulong stamp;
+ if( !(up || down) )
+ return;
+
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
if( rc )
log_fatal( _("%s: error reading version record: %s\n"),
@@ -651,7 +654,7 @@ tdbio_write_modify_stamp( int down, int up )
vr.r.ver.mod_up = stamp;
rc = tdbio_write_record( &vr );
- if( !rc )
+ if( rc )
log_fatal( _("%s: error writing version record: %s\n"),
db_name, g10_errstr(rc) );
}
diff --git a/g10/tdbio.h b/g10/tdbio.h
index 9c97dd108..ca9d23e8b 100644
--- a/g10/tdbio.h
+++ b/g10/tdbio.h
@@ -176,7 +176,7 @@ int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected );
int tdbio_write_record( TRUSTREC *rec );
int tdbio_db_matches_options(void);
ulong tdbio_read_modify_stamp( int modify_down );
-void tdbio_write_modify_stamp( int down, int up );
+void tdbio_write_modify_stamp( int up, int down );
int tdbio_is_dirty(void);
int tdbio_sync(void);
int tdbio_begin_transaction(void);
diff --git a/g10/trustdb.c b/g10/trustdb.c
index 557b4cc51..88e06c315 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -41,6 +41,7 @@
#include "main.h"
#include "i18n.h"
#include "tdbio.h"
+#include "ttyio.h"
#if MAX_FINGERPRINT_LEN > 20
#error Must change structure of trustdb
@@ -115,16 +116,20 @@ static int ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag );
static int qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag );
-static void propagate_validity( TN node );
+static int propagate_validity( TN root, TN node,
+ int (*add_fnc)(ulong), unsigned *retflgs );
-static void print_user_id( const char *text, u32 *keyid );
-static int do_check( TRUSTREC *drec, unsigned *trustlevel, const char *nhash);
+static void print_user_id( FILE *fp, const char *text, u32 *keyid );
+static int do_check( TRUSTREC *drec, unsigned *trustlevel,
+ const char *nhash, int (*add_fnc)(ulong),
+ unsigned *retflgs);
static int get_dir_record( PKT_public_key *pk, TRUSTREC *rec );
static void upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig );
static void upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
TRUSTREC *drec, RECNO_LIST *recno_list, int recheck,
- TRUSTREC *urec, const byte *uidhash, int revoked );
+ TRUSTREC *urec, const byte *uidhash, int revoked,
+ int *mod_up, int *mod_down );
/* a table used to keep track of ultimately trusted keys
* which are the ones from our secrings and the trusted keys */
@@ -375,6 +380,7 @@ keyid_from_lid( ulong lid, u32 *keyid )
int rc;
init_trustdb();
+ keyid[0] = keyid[1] = 0;
rc = tdbio_read_record( lid, &rec, 0 );
if( rc ) {
log_error(_("error reading dir record for LID %lu: %s\n"),
@@ -622,20 +628,23 @@ init_trustdb()
************* Print helpers ****************
***********************************************/
static void
-print_user_id( const char *text, u32 *keyid )
+print_user_id( FILE *fp, const char *text, u32 *keyid )
{
char *p;
size_t n;
p = get_user_id( keyid, &n );
- if( *text ) {
- fputs( text, stdout);
- putchar(' ');
- }
- putchar('\"');
- print_string( stdout, p, n, 0 );
- putchar('\"');
- putchar('\n');
+ if( fp ) {
+ fprintf( fp, "%s \"", text );
+ print_string( fp, p, n, 0 );
+ putc('\"', fp);
+ putc('\n', fp);
+ }
+ else {
+ tty_printf( "%s \"", text );
+ tty_print_string( p, n );
+ tty_printf( "\"\n" );
+ }
m_free(p);
}
@@ -699,35 +708,122 @@ print_path( int pathlen, TN ME .........., FILE *fp, ulong highlight )
static void
-print_default_uid( ulong lid )
+print_default_uid( FILE *fp, ulong lid )
{
u32 keyid[2];
if( !keyid_from_lid( lid, keyid ) )
- print_user_id( "", keyid );
+ print_user_id( fp, "", keyid );
}
static void
-dump_tn_tree( int indent, TN tree )
+print_uid_from_keyblock( FILE *fp, KBNODE keyblock, ulong urecno )
+{
+ TRUSTREC urec;
+ KBNODE node;
+ byte uhash[20];
+
+ read_record( urecno, &urec, RECTYPE_UID );
+ for( node=keyblock; node; node = node->next ) {
+ if( node->pkt->pkttype == PKT_USER_ID ) {
+ PKT_user_id *uidpkt = node->pkt->pkt.user_id;
+
+ rmd160_hash_buffer( uhash, uidpkt->name, uidpkt->len );
+ if( !memcmp( uhash, urec.r.uid.namehash, 20 ) ) {
+ print_string( fp, uidpkt->name, uidpkt->len, ':' );
+ return;
+ }
+ }
+ }
+
+ fputs("[?]", fp );
+}
+
+
+
+static void
+dump_tn_tree( FILE *fp, int level, TN tree )
{
TN kr, ur;
for( kr=tree; kr; kr = kr->next ) {
- printf("%*s", indent*4, "" );
- printf("K%lu(ot=%d,val=%d) ", kr->lid,
- kr->n.k.ownertrust,
- kr->n.k.validity );
- print_default_uid( kr->lid );
+ if( fp ) {
+ fprintf( fp, "%*s", level*4, "" );
+ fprintf( fp, "K%lu(ot=%d,val=%d) ", kr->lid,
+ kr->n.k.ownertrust,
+ kr->n.k.validity );
+ }
+ else {
+ tty_printf("%*s", level*4, "" );
+ tty_printf("K%lu(ot=%d,val=%d) ", kr->lid,
+ kr->n.k.ownertrust,
+ kr->n.k.validity );
+ }
+ print_default_uid( fp, kr->lid );
+ for( ur=kr->list; ur; ur = ur->next ) {
+ if( fp ) {
+ fprintf(fp, "%*s ", level*4, "" );
+ fprintf(fp, "U%lu(mc=%d,fc=%d,val=%d)\n", ur->lid,
+ ur->n.u.marginal_count,
+ ur->n.u.fully_count,
+ ur->n.u.validity
+ );
+ }
+ else {
+ tty_printf("%*s ", level*4, "" );
+ tty_printf("U%lu(mc=%d,fc=%d,val=%d)\n", ur->lid,
+ ur->n.u.marginal_count,
+ ur->n.u.fully_count,
+ ur->n.u.validity
+ );
+ }
+ dump_tn_tree( fp, level+1, ur->list );
+ }
+ }
+}
+
+/****************
+ * Special version of dump_tn_tree, which prints it colon delimited.
+ * Format:
+ * level:keyid:type:recno:ot:val:mc:cc:name:
+ * With TYPE = U for a user ID
+ * K for a key
+ * The RECNO is either the one of the dir record or the one of the uid record.
+ * OT is the the usual trust letter and only availabel on K lines.
+ * VAL is the calcualted validity
+ * MC is the marginal trust counter and only available on U lines
+ * CC is the same for the complete count
+ * NAME ist the username and only printed on U lines
+ */
+static void
+dump_tn_tree_with_colons( int level, TN tree )
+{
+ TN kr, ur;
+
+ for( kr=tree; kr; kr = kr->next ) {
+ KBNODE kb = NULL;
+ u32 kid[2];
+
+ keyid_from_lid( kr->lid, kid );
+ get_keyblock_bylid( &kb, kr->lid );
+
+ printf( "%d:%08lX%08lX:K:%lu:%c:%c::::\n",
+ level, (ulong)kid[0], (ulong)kid[1], kr->lid,
+ trust_letter( kr->n.k.ownertrust ),
+ trust_letter( kr->n.k.validity ) );
for( ur=kr->list; ur; ur = ur->next ) {
- printf("%*s ", indent*4, "" );
- printf("U%lu(mc=%d,fc=%d,val=%d)\n", ur->lid,
- ur->n.u.marginal_count,
- ur->n.u.fully_count,
- ur->n.u.validity
- );
- dump_tn_tree( indent+1, ur->list );
+ printf( "%d:%08lX%08lX:U:%lu::%c:%d:%d:",
+ level, (ulong)kid[0], (ulong)kid[1], ur->lid,
+ trust_letter( kr->n.u.validity ),
+ ur->n.u.marginal_count,
+ ur->n.u.fully_count );
+ print_uid_from_keyblock( stdout, kb, ur->lid );
+ putchar(':');
+ putchar('\n');
+ dump_tn_tree_with_colons( level+1, ur->list );
}
+ release_kbnode( kb );
}
}
@@ -851,6 +947,7 @@ check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
* Process a hintlist.
* Fixme: this list is not anymore anchored to another
* record, so it should be put elsewehere in case of an error
+ * FIXME: add mod_up/down handling
*/
static void
process_hintlist( ulong hintlist, ulong hint_owner )
@@ -1184,7 +1281,8 @@ upd_key_record( KBNODE keyblock, KBNODE keynode, u32 *keyid,
*/
static void
upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
- TRUSTREC *drec, RECNO_LIST *recno_list, int recheck )
+ TRUSTREC *drec, RECNO_LIST *recno_list,
+ int recheck, int *mod_up, int *mod_down )
{
ulong lid = drec->recnum;
PKT_user_id *uid = uidnode->pkt->pkt.user_id;
@@ -1327,10 +1425,10 @@ upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
write_record( &urec );
if( !( urec.r.uid.uidflags & UIDF_VALID )
|| ( urec.r.uid.uidflags & UIDF_REVOKED ) )
- ; /*FIXME: mark as modified down */
+ *mod_down=1;
else
- ; /*FIXME: mark as modified up (maybe a new uuser id)*/
-
+ *mod_up=1; /*(maybe a new user id)*/
+ /* Hmmm, did we catch changed expiration dates? */
}
} /* end check self-signatures */
@@ -1362,11 +1460,11 @@ upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
if( (sig->sig_class&~3) == 0x10 ) { /* regular certification */
upd_cert_record( keyblock, node, keyid, drec, recno_list,
- recheck, &urec, uidhash, 0 );
+ recheck, &urec, uidhash, 0, mod_up, mod_down );
}
else if( sig->sig_class == 0x30 ) { /* cert revocation */
upd_cert_record( keyblock, node, keyid, drec, recno_list,
- recheck, &urec, uidhash, 1 );
+ recheck, &urec, uidhash, 1, mod_up, mod_down );
}
} /* end check certificates */
@@ -1490,11 +1588,11 @@ upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig )
}
-/* FIXME: add logic to set the modify_{down,up} */
static void
upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
TRUSTREC *drec, RECNO_LIST *recno_list, int recheck,
- TRUSTREC *urec, const byte *uidhash, int revoked )
+ TRUSTREC *urec, const byte *uidhash, int revoked,
+ int *mod_up, int *mod_down )
{
/* We simply insert the signature into the sig records but
* avoid duplicate ones. We do not check them here because
@@ -1577,8 +1675,12 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
revoked? _("Valid certificate revocation")
: _("Good certificate") );
rec.r.sig.sig[i].flag = SIGF_CHECKED | SIGF_VALID;
- if( revoked ) /* we are investigating revocations */
+ if( revoked ) { /* we are investigating revocations */
rec.r.sig.sig[i].flag |= SIGF_REVOKED;
+ *mod_down = 1;
+ }
+ else
+ *mod_up = 1;
}
else if( rc == G10ERR_NO_PUBKEY ) {
/* This may happen if the key is still in the trustdb
@@ -1589,6 +1691,7 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
uidhash[19], (ulong)sig->keyid[1],
_("public key not anymore available") );
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
+ *mod_down = 1;
if( revoked )
rec.r.sig.sig[i].flag |= SIGF_REVOKED;
}
@@ -1600,8 +1703,10 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
: _("Invalid certificate"),
g10_errstr(rc));
rec.r.sig.sig[i].flag = SIGF_CHECKED;
- if( revoked )
+ if( revoked ) {
rec.r.sig.sig[i].flag |= SIGF_REVOKED;
+ *mod_down = 1;
+ }
}
rec.dirty = 1;
}
@@ -1662,8 +1767,12 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
: _("Good certificate") );
newlid = pk_lid; /* this is the pk of the signature */
newflag = SIGF_CHECKED | SIGF_VALID;
- if( revoked )
+ if( revoked ) {
newflag |= SIGF_REVOKED;
+ *mod_down = 1;
+ }
+ else
+ *mod_up = 1;
}
else if( rc == G10ERR_NO_PUBKEY ) {
if( opt.verbose > 1 || DBG_TRUST )
@@ -1686,6 +1795,7 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
newflag = SIGF_CHECKED;
if( revoked )
newflag |= SIGF_REVOKED;
+ *mod_down = 1;
}
if( delrec.recnum ) { /* we can reuse an unused slot */
@@ -1730,6 +1840,8 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
int rc = 0;
u32 keyid[2]; /* keyid of primary key */
ulong recno, lastrecno;
+ int mod_up = 0;
+ int mod_down = 0;
RECNO_LIST recno_list = NULL; /* list of verified records */
/* fixme: replace recno_list by a lookup on node->recno */
@@ -1767,7 +1879,7 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
for( node=keyblock; node; node = node->next ) {
if( node->pkt->pkttype == PKT_USER_ID )
upd_uid_record( keyblock, node, keyid,
- &drec, &recno_list, recheck );
+ &drec, &recno_list, recheck, &mod_up, &mod_down );
}
/* delete keyrecords from the trustdb which are not anymore used */
@@ -1842,6 +1954,7 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
drec.r.dir.dirflags |= DIRF_CHECKED;
drec.r.dir.valcheck = 0;
write_record( &drec );
+ tdbio_write_modify_stamp( mod_up, mod_down );
rc = tdbio_end_transaction();
}
rel_recno_list( &recno_list );
@@ -1854,7 +1967,7 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
* This function assumes that the record does not yet exist.
*/
int
-insert_trust_record( PKT_public_key *pk )
+insert_trust_record( PKT_public_key *orig_pk )
{
TRUSTREC dirrec;
TRUSTREC shadow;
@@ -1864,6 +1977,7 @@ insert_trust_record( PKT_public_key *pk )
size_t fingerlen;
int rc = 0;
ulong hintlist = 0;
+ PKT_public_key *pk;
if( opt.dry_run )
@@ -1871,7 +1985,7 @@ insert_trust_record( PKT_public_key *pk )
init_trustdb();
- fingerprint_from_pk( pk, fingerprint, &fingerlen );
+ fingerprint_from_pk( orig_pk, fingerprint, &fingerlen );
/* fixme: assert that we do not have this record.
* we can do this by searching for the primary keyid
@@ -1883,6 +1997,10 @@ insert_trust_record( PKT_public_key *pk )
* to the primary one which has the user ids etc.)
*/
+ if( orig_pk->local_id )
+ log_debug("insert_trust_record with pk->local_id=%lu (1)\n",
+ orig_pk->local_id );
+
/* get the keyblock which has the key */
rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
if( rc ) { /* that should never happen */
@@ -1891,32 +2009,18 @@ insert_trust_record( PKT_public_key *pk )
goto leave;
}
+ /* make sure that we use the primary key */
+ pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )->pkt->pkt.public_key;
+
if( pk->local_id ) {
- log_debug("insert_trust_reord with pk->local_id=%lu\n", pk->local_id );
+ orig_pk->local_id = pk->local_id;
+ log_debug("insert_trust_record with pk->local_id=%lu (2)\n",
+ pk->local_id );
rc = update_trust_record( keyblock, 1, NULL );
release_kbnode( keyblock );
return rc;
}
- /* check that we used the primary key (we are little bit paranoid) */
- { PKT_public_key *a_pk;
- u32 akid[2], bkid[2];
-
- node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
- a_pk = node->pkt->pkt.public_key;
-
- /* we can't use cmp_public_keys here because some parts (expiredate)
- * might not be set in pk <--- but why (fixme) */
- keyid_from_pk( a_pk, akid );
- keyid_from_pk( pk, bkid );
-
- if( akid[0] != bkid[0] || akid[1] != bkid[1] ) {
- log_error(_("did not use primary key for insert_trust_record()\n"));
- rc = G10ERR_GENERAL;
- goto leave;
- }
- }
-
/* We have to look for a shadow dir record which must be reused
* as the dir record. And: check all signatures which are listed
* in the hintlist of the shadow dir record.
@@ -1942,6 +2046,7 @@ insert_trust_record( PKT_public_key *pk )
/* out the LID into the keyblock */
pk->local_id = dirrec.r.dir.lid;
+ orig_pk->local_id = dirrec.r.dir.lid;
for( node=keyblock; node; node = node->next ) {
if( node->pkt->pkttype == PKT_PUBLIC_KEY
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
@@ -1954,7 +2059,8 @@ insert_trust_record( PKT_public_key *pk )
}
}
- /* FIXME: mark tdb as modified upwards */
+ /* mark tdb as modified upwards */
+ tdbio_write_modify_stamp( 1, 0 );
/* and put all the other stuff into the keydb */
rc = update_trust_record( keyblock, 1, NULL );
@@ -2100,9 +2206,57 @@ build_cert_tree( ulong lid, int depth, int max_depth, TN helproot )
}
+static void
+upd_one_ownertrust( ulong lid, unsigned new_trust, unsigned *retflgs )
+{
+ TRUSTREC rec;
+
+ read_record( lid, &rec, RECTYPE_DIR );
+ if( DBG_TRUST )
+ log_debug("upd_one_ownertrust of %lu from %u to %u\n",
+ lid, (unsigned)rec.r.dir.ownertrust, new_trust );
+ if( retflgs ) {
+ if( new_trust > rec.r.dir.ownertrust )
+ *retflgs |= 16; /* modified up */
+ else
+ *retflgs |= 32; /* modified down */
+ }
+ rec.r.dir.ownertrust = new_trust;
+ write_record( &rec );
+}
+/****************
+ * Update the ownertrust in the complete tree.
+ */
static void
-propagate_validity( TN node )
+propagate_ownertrust( TN kr, ulong lid, unsigned trust )
+{
+ TN ur;
+
+ for( ; kr; kr = kr->next ) {
+ if( kr->lid == lid )
+ kr->n.k.ownertrust = trust;
+ for( ur=kr->list; ur; ur = ur->next )
+ propagate_ownertrust( ur->list, lid, trust );
+ }
+}
+
+/****************
+ * Calculate the validity of all keys in the tree and especially
+ * the one of the top key. If add_fnc is not NULL, it is used to
+ * ask for missing ownertrust values (but only if this will help
+ * us to increase the validity.
+ * add_fnc is expected to take the LID of the key under question
+ * and return a ownertrust value or an error: positive values
+ * are assumed to be the new ownertrust value; a 0 does mean no change,
+ * a -1 is a request to cancel this validation procedure, a -2 requests
+ * a listing of the sub-tree using the tty functions.
+ *
+ *
+ * Returns: 0 = okay
+ */
+static int
+propagate_validity( TN root, TN node, int (*add_fnc)(ulong), unsigned *retflgs )
{
TN kr, ur;
int max_validity = 0;
@@ -2112,7 +2266,9 @@ propagate_validity( TN node )
/* this is one of our keys */
assert( !node->list ); /* it should be a leaf */
node->n.k.validity = TRUST_ULTIMATE;
- return;
+ if( retflgs )
+ *retflgs |= 1; /* found a path to an ultimately trusted key */
+ return 0;
}
/* loop over all user ids */
@@ -2120,11 +2276,39 @@ propagate_validity( TN node )
assert( ur->is_uid );
/* loop over all signators */
for(kr=ur->list; kr; kr = kr->next ) {
- propagate_validity( kr );
+ if( propagate_validity( root, kr, add_fnc, retflgs ) )
+ return -1; /* quit */
if( kr->n.k.validity == TRUST_ULTIMATE ) {
ur->n.u.fully_count = opt.completes_needed;
}
else if( kr->n.k.validity == TRUST_FULLY ) {
+ if( add_fnc && !kr->n.k.ownertrust ) {
+ int rc;
+
+ if( retflgs )
+ *retflgs |= 2; /* found key with undefined ownertrust*/
+ do {
+ rc = add_fnc( kr->lid );
+ switch( rc ) {
+ case TRUST_NEVER:
+ case TRUST_MARGINAL:
+ case TRUST_FULLY:
+ propagate_ownertrust( root, kr->lid, rc );
+ upd_one_ownertrust( kr->lid, rc, retflgs );
+ if( retflgs )
+ *retflgs |= 4; /* changed */
+ break;
+ case -1:
+ return -1; /* cancel */
+ case -2:
+ dump_tn_tree( NULL, 0, kr );
+ tty_printf("\n");
+ break;
+ default:
+ break;
+ }
+ } while( rc == -2 );
+ }
if( kr->n.k.ownertrust == TRUST_FULLY )
ur->n.u.fully_count++;
else if( kr->n.k.ownertrust == TRUST_MARGINAL )
@@ -2145,6 +2329,7 @@ propagate_validity( TN node )
}
node->n.k.validity = max_validity;
+ return 0;
}
@@ -2155,15 +2340,17 @@ propagate_validity( TN node )
* checking all key signatures up to a some depth.
*/
static int
-verify_key( int max_depth, TRUSTREC *drec, const char *namehash )
+verify_key( int max_depth, TRUSTREC *drec, const char *namehash,
+ int (*add_fnc)(ulong), unsigned *retflgs )
{
TN tree;
int keytrust;
+ int pv_result;
tree = build_cert_tree( drec->r.dir.lid, 0, opt.max_cert_depth, NULL );
if( !tree )
return TRUST_UNDEFINED;
- propagate_validity( tree );
+ pv_result = propagate_validity( tree, tree, add_fnc, retflgs );
if( namehash ) {
/* find the matching user id.
* fixme: the way we handle this is too inefficient */
@@ -2183,7 +2370,8 @@ verify_key( int max_depth, TRUSTREC *drec, const char *namehash )
keytrust = tree->n.k.validity;
/* update the cached validity values */
- if( keytrust >= TRUST_UNDEFINED
+ if( !pv_result
+ && keytrust >= TRUST_UNDEFINED
&& tdbio_db_matches_options()
&& ( !drec->r.dir.valcheck || drec->r.dir.validity != keytrust ) ) {
TN ur;
@@ -2213,7 +2401,8 @@ verify_key( int max_depth, TRUSTREC *drec, const char *namehash )
* but nothing more is known.
*/
static int
-do_check( TRUSTREC *dr, unsigned *validity, const char *namehash )
+do_check( TRUSTREC *dr, unsigned *validity,
+ const char *namehash, int (*add_fnc)(ulong), unsigned *retflgs )
{
if( !dr->r.dir.keylist ) {
log_error(_("Ooops, no keys\n"));
@@ -2224,22 +2413,39 @@ do_check( TRUSTREC *dr, unsigned *validity, const char *namehash )
return G10ERR_TRUSTDB;
}
+ if( retflgs )
+ *retflgs &= ~(16|32); /* reset the 2 special flags */
+
if( namehash ) {
/* Fixme: use the cache */
- *validity = verify_key( opt.max_cert_depth, dr, namehash );
+ *validity = verify_key( opt.max_cert_depth, dr, namehash,
+ add_fnc, retflgs );
}
- else if( tdbio_db_matches_options()
+ else if( !add_fnc
+ && tdbio_db_matches_options()
&& dr->r.dir.valcheck
> tdbio_read_modify_stamp( (dr->r.dir.validity < TRUST_FULLY) )
&& dr->r.dir.validity )
*validity = dr->r.dir.validity;
else
- *validity = verify_key( opt.max_cert_depth, dr, NULL );
+ *validity = verify_key( opt.max_cert_depth, dr, NULL,
+ add_fnc, retflgs );
+
+ if( !(*validity & TRUST_MASK) )
+ *validity = TRUST_UNDEFINED;
if( dr->r.dir.dirflags & DIRF_REVOKED )
*validity |= TRUST_FLAG_REVOKED;
+ /* If we have changed some ownertrusts, set the trustdb timestamps
+ * and do a sync */
+ if( retflgs && (*retflgs & (16|32)) ) {
+ tdbio_write_modify_stamp( (*retflgs & 16), (*retflgs & 32) );
+ do_sync();
+ }
+
+
return 0;
}
@@ -2256,6 +2462,9 @@ update_ownertrust( ulong lid, unsigned new_trust )
init_trustdb();
read_record( lid, &rec, RECTYPE_DIR );
+ if( DBG_TRUST )
+ log_debug("update_ownertrust of %lu from %u to %u\n",
+ lid, (unsigned)rec.r.dir.ownertrust, new_trust );
rec.r.dir.ownertrust = new_trust;
write_record( &rec );
do_sync();
@@ -2512,7 +2721,8 @@ query_trust_record( PKT_public_key *pk )
* is not necessary to check this if we use a local pubring. Hmmmm.
*/
int
-check_trust( PKT_public_key *pk, unsigned *r_trustlevel, const byte *namehash )
+check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
+ const byte *namehash, int (*add_fnc)(ulong), unsigned *retflgs )
{
TRUSTREC rec;
unsigned trustlevel = TRUST_UNKNOWN;
@@ -2562,7 +2772,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel, const byte *namehash )
trustlevel = TRUST_EXPIRED;
}
else {
- rc = do_check( &rec, &trustlevel, namehash );
+ rc = do_check( &rec, &trustlevel, namehash, add_fnc, retflgs );
if( rc ) {
log_error(_("key %08lX.%lu: trust check failed: %s\n"),
(ulong)keyid[1], pk->local_id, g10_errstr(rc));
@@ -2586,7 +2796,7 @@ query_trust_info( PKT_public_key *pk, const byte *namehash )
int c;
init_trustdb();
- if( check_trust( pk, &trustlevel, namehash ) )
+ if( check_trust( pk, &trustlevel, namehash, NULL, NULL ) )
return '?';
if( trustlevel & TRUST_FLAG_REVOKED )
return 'r';
@@ -2656,12 +2866,15 @@ list_trust_path( const char *username )
tree = build_cert_tree( lid, 0, opt.max_cert_depth, NULL );
if( tree )
- propagate_validity( tree );
- dump_tn_tree( 0, tree );
- printf("(alloced tns=%d max=%d)\n", alloced_tns, max_alloced_tns );
+ propagate_validity( tree, tree, NULL, NULL );
+ if( opt.with_colons )
+ dump_tn_tree_with_colons( 0, tree );
+ else
+ dump_tn_tree( stdout, 0, tree );
+ /*printf("(alloced tns=%d max=%d)\n", alloced_tns, max_alloced_tns );*/
release_tn_tree( tree );
- printf("Ownertrust=%c Validity=%c\n", get_ownertrust_info( lid ),
- query_trust_info( pk, NULL ) );
+ /*printf("Ownertrust=%c Validity=%c\n", get_ownertrust_info( lid ),
+ query_trust_info( pk, NULL ) ); */
free_public_key( pk );
diff --git a/g10/trustdb.h b/g10/trustdb.h
index dba9e5caf..64ccaae5d 100644
--- a/g10/trustdb.h
+++ b/g10/trustdb.h
@@ -47,7 +47,8 @@ void check_trustdb( const char *username );
void update_trustdb( void );
int setup_trustdb( int level, const char *dbname );
void init_trustdb( void );
-int check_trust( PKT_public_key *pk, unsigned *r_trustlevel, const byte* nh );
+int check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
+ const byte* nh, int (*add_fnc)(ulong), unsigned *retflgs );
int query_trust_info( PKT_public_key *pk, const byte *nh );
int enum_cert_paths( void **context, ulong *lid,
unsigned *ownertrust, unsigned *validity );