aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/ChangeLog25
-rw-r--r--g10/encode.c2
-rw-r--r--g10/g10.c24
-rw-r--r--g10/helptext.c7
-rw-r--r--g10/import.c11
-rw-r--r--g10/keydb.h3
-rw-r--r--g10/keyedit.c30
-rw-r--r--g10/keygen.c4
-rw-r--r--g10/main.h1
-rw-r--r--g10/mainproc.c7
-rw-r--r--g10/openfile.c38
-rw-r--r--g10/passphrase.c8
-rw-r--r--g10/pkclist.c16
-rw-r--r--g10/plaintext.c6
-rw-r--r--g10/seckey-cert.c2
-rw-r--r--g10/sig-check.c5
-rw-r--r--g10/tdbdump.c2
-rw-r--r--g10/trustdb.c120
-rw-r--r--g10/trustdb.h3
19 files changed, 222 insertions, 92 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 9db45bb4a..ca68a142a 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,28 @@
+Thu Jul 1 12:47:31 CEST 1999 Werner Koch <[email protected]>
+
+
+ * keyedit.c (show_key_with_all_names): Print a notice for disabled keys.
+ (enable_disable_keys): Add functionality
+ * pkclist.c (edit_ownertrust): preserve disabled state.
+ (build_pk_list): Skip disabled keys.
+ * trustdb.c (upd_one_ownertrust): Ditto.
+ (build_cert_tree): Mask the ownertrust.
+ (trust_letter): Mask the value.
+ (do_check): Take disabled flag into account.
+
+ * passphrase.c (passphrase_to_dek): Add a pubkey_alfo arg and changed
+ all callers.
+
+ * g10.c (utf8_strings): 2 new options.
+
+ * trustdb.c (insert_trust_record_by_pk): New, replaces the next one.
+ (insert_trust_record): Now takes a keyblock as arg. Changed all
+ callers to use the appropritae function.
+
+ * openfile.c (ask_outfile_name): New.
+ * plaintext.c (handle_plaintext): Ask for filename if there is
+ no valid syntax. Don't use fname varbatim but filter it.
+
Tue Jun 29 21:44:25 CEST 1999 Werner Koch <[email protected]>
diff --git a/g10/encode.c b/g10/encode.c
index 7daec6c64..147607b31 100644
--- a/g10/encode.c
+++ b/g10/encode.c
@@ -102,7 +102,7 @@ encode_simple( const char *filename, int mode )
s2k->mode = opt.rfc1991? 0:opt.s2k_mode;
s2k->hash_algo = opt.def_digest_algo ? opt.def_digest_algo
: opt.s2k_digest_algo;
- cfx.dek = passphrase_to_dek( NULL,
+ cfx.dek = passphrase_to_dek( NULL, 0,
opt.def_cipher_algo ? opt.def_cipher_algo
: opt.s2k_cipher_algo , s2k, 2 );
if( !cfx.dek || !cfx.dek->keylen ) {
diff --git a/g10/g10.c b/g10/g10.c
index 94aa2808f..66a91bf94 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -166,6 +166,8 @@ enum cmd_and_opt_values { aNull = 0,
oEncryptTo,
oNoEncryptTo,
oLoggerFD,
+ oUtf8Strings,
+ oNoUtf8Strings,
aTest };
@@ -315,13 +317,15 @@ static ARGPARSE_OPTS opts[] = {
{ oLockMultiple, "lock-multiple", 0, "@" },
{ oLoggerFD, "logger-fd",1, "@" },
{ oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
+ { oUtf8Strings, "utf8-strings", 0, "@" },
+ { oNoUtf8Strings, "no-utf8-strings", 0, "@" },
{0} };
int g10_errors_seen = 0;
-
+static int utf8_strings = 0;
static int maybe_setuid = 1;
static char *build_list( const char *text,
@@ -761,16 +765,16 @@ main( int argc, char **argv )
case oNoEncryptTo: opt.no_encrypt_to = 1; break;
case oEncryptTo: /* store the recipient in the second list */
- sl = add_to_strlist( &remusr, pargs.r.ret_str );
+ sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
sl->flags = 1;
break;
case oRecipient: /* store the recipient */
- add_to_strlist( &remusr, pargs.r.ret_str );
+ add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
break;
case oTextmodeShort: opt.textmode = 2; break;
case oTextmode: opt.textmode=1; break;
case oUser: /* store the local users */
- add_to_strlist( &locusr, pargs.r.ret_str );
+ add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
break;
case oCompress: opt.compress = pargs.r.ret_int; break;
case oPasswdFD: pwfd = pargs.r.ret_int; break;
@@ -788,6 +792,8 @@ main( int argc, char **argv )
case oLockMultiple: opt.lock_once = 0; break;
case oKeyServer: opt.keyserver_name = pargs.r.ret_str; break;
case oNotation: add_notation_data( pargs.r.ret_str ); break;
+ case oUtf8Strings: utf8_strings = 1; break;
+ case oNoUtf8Strings: utf8_strings = 0; break;
default : pargs.err = configfp? 1:2; break;
}
@@ -1025,7 +1031,7 @@ main( int argc, char **argv )
if( argc > 1 ) {
sl = NULL;
for( argc--, argv++ ; argc; argc--, argv++ )
- append_to_strlist( &sl, *argv );
+ append_to_strlist2( &sl, *argv, utf8_strings );
keyedit_menu( fname, locusr, sl );
free_strlist(sl);
}
@@ -1040,6 +1046,7 @@ main( int argc, char **argv )
if( argc != 1 )
wrong_args(_("--delete-key username"));
/* note: fname is the user id! */
+ /* fixme: do utf8 conversion */
if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
break;
@@ -1482,11 +1489,8 @@ add_notation_data( const char *string )
highbit = 1;
}
- if( highbit ) { /* must use UTF8 encoding */
- char *p = native_to_utf8( string );
- sl = add_to_strlist( &opt.notation_data, p );
- m_free( p );
- }
+ if( highbit ) /* must use UTF8 encoding */
+ sl = add_to_strlist2( &opt.notation_data, string, utf8_strings );
else
sl = add_to_strlist( &opt.notation_data, string );
diff --git a/g10/helptext.c b/g10/helptext.c
index 521df534d..5fb800784 100644
--- a/g10/helptext.c
+++ b/g10/helptext.c
@@ -208,10 +208,17 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
"Give the name fo the file to which the signature applies"
},
+/* openfile.c (overwrite_filep) */
{ N_("openfile.overwrite.okay"),
"Answer \"yes\" if it is okay to overwrite the file"
},
+/* openfile.c (ask_outfile_name) */
+{ N_("openfile.askoutname"),
+ "Please enter a new filename. If you just hit RETURN the default\n"
+ "file (which is shown in brackets) will be used."
+},
+
/* end of list */
{ NULL, NULL } };
diff --git a/g10/import.c b/g10/import.c
index 060990e36..a81c7edbf 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -376,10 +376,10 @@ import_one( const char *fname, KBNODE keyblock, int fast )
log_info( _("writing to `%s'\n"),
keyblock_resource_name(&kbpos) );
if( (rc=lock_keyblock( &kbpos )) )
- log_error(_("can't lock keyring `%s': %s\n"),
+ log_error(_("can't lock keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), g10_errstr(rc) );
else if( (rc=insert_keyblock( &kbpos, keyblock )) )
- log_error( _("error writing keyring `%s': %s\n"),
+ log_error( _("error writing keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), g10_errstr(rc) );
unlock_keyblock( &kbpos );
/* we are ready */
@@ -402,9 +402,6 @@ import_one( const char *fname, KBNODE keyblock, int fast )
goto leave;
}
- /* See whether we have only non-self-signature on one user id; if not
- * ask the user what to do. <--- fixme */
-
/* now read the original keyblock */
rc = find_keyblock_bypk( &kbpos, pk_orig );
if( rc ) {
@@ -432,7 +429,7 @@ import_one( const char *fname, KBNODE keyblock, int fast )
mod_key = 1;
/* keyblock_orig has been updated; write */
if( (rc=lock_keyblock( &kbpos )) )
- log_error( _("can't lock keyring `%s': %s\n"),
+ log_error( _("can't lock keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), g10_errstr(rc) );
else if( (rc=update_keyblock( &kbpos, keyblock_orig )) )
log_error( _("error writing keyring `%s': %s\n"),
@@ -475,7 +472,7 @@ import_one( const char *fname, KBNODE keyblock, int fast )
if( rc && rc != -1 )
log_error("trustdb error: %s\n", g10_errstr(rc) );
else if( rc == -1 ) { /* not found trustdb */
- rc = insert_trust_record( new_key? pk : pk_orig );
+ rc = insert_trust_record( new_key? keyblock : keyblock_orig );
if( rc )
log_error("key %08lX: trustdb insert failed: %s\n",
(ulong)keyid[1], g10_errstr(rc) );
diff --git a/g10/keydb.h b/g10/keydb.h
index 236967511..20a8a6325 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -125,7 +125,8 @@ int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
/*-- passphrase.h --*/
int have_static_passphrase(void);
void read_passphrase_from_fd( int fd );
-DEK *passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode);
+DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
+ int cipher_algo, STRING2KEY *s2k, int mode);
void set_next_passphrase( const char *s );
char *get_last_passphrase(void);
diff --git a/g10/keyedit.c b/g10/keyedit.c
index df14f13e1..e93634034 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -451,7 +451,7 @@ change_passphrase( KBNODE keyblock )
for(;;) {
s2k->mode = opt.s2k_mode;
s2k->hash_algo = opt.s2k_digest_algo;
- dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
+ dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2 );
if( !dek ) {
tty_printf(_("passphrase not correctly repeated; try again.\n"));
}
@@ -1033,6 +1033,12 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
expirestr_from_pk(pk) );
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
tty_printf(" trust: %c/%c", otrust, trust );
+ if( node->pkt->pkttype == PKT_PUBLIC_KEY
+ && (get_ownertrust( pk->local_id )&TRUST_FLAG_DISABLED)) {
+ tty_printf("\n*** ");
+ tty_printf(_("This key has been disabled"));
+ }
+
if( with_fpr ) {
tty_printf("\n");
show_fingerprint( pk );
@@ -1872,12 +1878,20 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
static int
enable_disable_key( KBNODE keyblock, int disable )
{
- int entire;
- int changed = 0;
-
-
- entire = !count_selected_keys( keyblock );
-
- return changed;
+ ulong lid = find_kbnode( keyblock, PKT_PUBLIC_KEY )
+ ->pkt->pkt.public_key->local_id;
+ unsigned int trust, newtrust;
+
+ /* Note: Because the keys have beed displayed, we have
+ * ensured that local_id has been set */
+ trust = newtrust = get_ownertrust( lid );
+ newtrust &= ~TRUST_FLAG_DISABLED;
+ if( disable )
+ newtrust |= TRUST_FLAG_DISABLED;
+ if( trust == newtrust )
+ return 0; /* already in that state */
+ if( !update_ownertrust( lid, newtrust ) )
+ return 1;
+ return 0;
}
diff --git a/g10/keygen.c b/g10/keygen.c
index 1621d9445..74840e8c6 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -743,7 +743,7 @@ ask_passphrase( STRING2KEY **ret_s2k )
for(;;) {
s2k->mode = opt.s2k_mode;
s2k->hash_algo = opt.s2k_digest_algo;
- dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
+ dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2 );
if( !dek ) {
tty_printf(_("passphrase not correctly repeated; try again.\n"));
}
@@ -1045,7 +1045,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
s2k->mode = opt.s2k_mode;
s2k->hash_algo = opt.s2k_digest_algo;
set_next_passphrase( passphrase );
- dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
+ dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2 );
}
rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
diff --git a/g10/main.h b/g10/main.h
index 5889ccf71..f2c059b33 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -97,6 +97,7 @@ int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
/*-- openfile.c --*/
int overwrite_filep( const char *fname );
char *make_outfile_name( const char *iname );
+char *ask_outfile_name( const char *name, size_t namelen );
int open_outfile( const char *iname, int mode, IOBUF *a );
IOBUF open_sigfile( const char *iname );
void copy_options_file( const char *destdir );
diff --git a/g10/mainproc.c b/g10/mainproc.c
index cb2388f06..51d436127 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -163,7 +163,7 @@ proc_symkey_enc( CTX c, PACKET *pkt )
log_error( "symkey_enc packet with session keys are not supported!\n");
else {
c->last_was_session_key = 2;
- c->dek = passphrase_to_dek( NULL, enc->cipher_algo, &enc->s2k, 0 );
+ c->dek = passphrase_to_dek( NULL, 0, enc->cipher_algo, &enc->s2k, 0 );
}
free_packet(pkt);
}
@@ -185,7 +185,8 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
if( is_status_enabled() ) {
char buf[50];
- sprintf(buf, "%08lX%08lX", (ulong)enc->keyid[0], (ulong)enc->keyid[1]);
+ sprintf(buf, "%08lX%08lX %d 0",
+ (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo );
write_status_text( STATUS_ENC_TO, buf );
}
@@ -230,7 +231,7 @@ proc_encrypted( CTX c, PACKET *pkt )
/*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
if( !c->dek && !c->last_was_session_key ) {
/* assume this is old conventional encrypted data */
- c->dek = passphrase_to_dek( NULL,
+ c->dek = passphrase_to_dek( NULL, 0,
opt.def_cipher_algo ? opt.def_cipher_algo
: DEFAULT_CIPHER_ALGO, NULL, 0 );
}
diff --git a/g10/openfile.c b/g10/openfile.c
index af0ab3c1d..ebf954843 100644
--- a/g10/openfile.c
+++ b/g10/openfile.c
@@ -99,6 +99,44 @@ make_outfile_name( const char *iname )
}
+/****************
+ * Ask for a outputfilename and use the given one as default.
+ * Return NULL if no file has been given or it is not possible to
+ * ask the user.
+ */
+char *
+ask_outfile_name( const char *name, size_t namelen )
+{
+ size_t n;
+ const char *s;
+ char *prompt;
+ char *fname;
+ char *defname;
+
+ if( opt.batch )
+ return NULL;
+
+ s = _("Enter new filename");
+
+ n = strlen(s) + namelen + 10;
+ defname = name && namelen? make_printable_string( name, namelen, 0): NULL;
+ prompt = m_alloc(n);
+ if( defname )
+ sprintf(prompt, "%s [%s]: ", s, defname );
+ else
+ sprintf(prompt, "%s: ", s );
+ fname = cpr_get("openfile.askoutname", prompt );
+ cpr_kill_prompt();
+ m_free(prompt);
+ if( !*fname ) {
+ m_free( fname ); fname = NULL;
+ fname = defname; defname = NULL;
+ }
+ m_free(defname);
+ return fname;
+}
+
+
/****************
* Make an output filename for the inputfile INAME.
diff --git a/g10/passphrase.c b/g10/passphrase.c
index 9581246f2..80c6fa33f 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -114,9 +114,11 @@ read_passphrase_from_fd( int fd )
* (only for mode 2)
* a dek->keylen of 0 means: no passphrase entered.
* (only for mode 2)
+ * pubkey_algo is only informational.
*/
DEK *
-passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
+passphrase_to_dek( u32 *keyid, int pubkey_algo,
+ int cipher_algo, STRING2KEY *s2k, int mode )
{
char *pw = NULL;
DEK *dek;
@@ -139,8 +141,8 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
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] );
+ sprintf( buf+strlen(buf), " %08lX%08lX %d 0",
+ (ulong)keyid[2], (ulong)keyid[3], pubkey_algo );
write_status_text( STATUS_NEED_PASSPHRASE, buf );
}
else {
diff --git a/g10/pkclist.c b/g10/pkclist.c
index 39ed0e5f2..d8c25ebba 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -206,7 +206,7 @@ do_edit_ownertrust( ulong lid, int mode, unsigned *new_trust )
int
edit_ownertrust( ulong lid, int mode )
{
- unsigned trust;
+ unsigned int trust;
for(;;) {
switch( do_edit_ownertrust( lid, mode, &trust ) ) {
@@ -216,6 +216,8 @@ edit_ownertrust( ulong lid, int mode )
show_paths( lid, 1 );
break;
case 1:
+ trust &= ~TRUST_FLAG_DISABLED;
+ trust |= get_ownertrust( lid ) & TRUST_FLAG_DISABLED;
if( !update_ownertrust( lid, trust ) )
return 1;
return 0;
@@ -301,7 +303,7 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
switch( (trustlevel & TRUST_MASK) ) {
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
- rc = insert_trust_record( pk );
+ rc = insert_trust_record_by_pk( pk );
if( rc ) {
log_error("failed to insert it into the trustdb: %s\n",
g10_errstr(rc) );
@@ -462,7 +464,7 @@ check_signatures_trust( PKT_signature *sig )
switch( (trustlevel & TRUST_MASK) ) {
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
- rc = insert_trust_record( pk );
+ rc = insert_trust_record_by_pk( pk );
if( rc ) {
log_error("failed to insert it into the trustdb: %s\n",
g10_errstr(rc) );
@@ -633,6 +635,9 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
log_error("error checking pk of `%s': %s\n",
answer, g10_errstr(rc) );
}
+ else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
+ tty_printf(_("Public key is disabled.\n") );
+ }
else if( do_we_trust_pre( pk, trustlevel ) ) {
PK_LIST r;
@@ -673,6 +678,11 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
log_error(_("%s: error checking key: %s\n"),
remusr->d, g10_errstr(rc) );
}
+ else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
+ free_public_key(pk); pk = NULL;
+ log_info(_("%s: skipped: public key is disabled\n"),
+ remusr->d);
+ }
else if( do_we_trust_pre( pk, trustlevel ) ) {
/* note: do_we_trust may have changed the trustlevel */
diff --git a/g10/plaintext.c b/g10/plaintext.c
index 1edca16e5..878bdc46b 100644
--- a/g10/plaintext.c
+++ b/g10/plaintext.c
@@ -65,15 +65,15 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
}
else if( !opt.use_embedded_filename ) {
fname = make_outfile_name( iobuf_get_real_fname(pt->buf) );
+ if( !fname )
+ fname = ask_outfile_name( pt->name, pt->namelen );
if( !fname ) {
rc = G10ERR_CREATE_FILE;
goto leave;
}
}
else {
- fname = m_alloc( pt->namelen +1 );
- memcpy( fname, pt->name, pt->namelen );
- fname[pt->namelen] = 0;
+ fname = make_printable_string( pt->name, pt->namelen, 0 );
}
if( nooutput )
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 03cf3f2bf..95af40b78 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -64,7 +64,7 @@ do_check( PKT_secret_key *sk )
keyid_from_sk( sk2, keyid+2 );
free_secret_key( sk2 );
}
- dek = passphrase_to_dek( keyid, sk->protect.algo,
+ dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
&sk->protect.s2k, 0 );
cipher_hd = cipher_open( sk->protect.algo,
CIPHER_MODE_AUTO_CFB, 1);
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 48734370c..e57ae8019 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -412,6 +412,11 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
pk = root->pkt->pkt.public_key;
sig = node->pkt->pkt.signature;
algo = sig->digest_algo;
+
+ if( sig->flags.checked )
+ log_debug("check_key_signature: already checked: %s\n",
+ sig->flags.valid? "good":"bad" );
+
if( (rc=check_digest_algo(algo)) )
return rc;
diff --git a/g10/tdbdump.c b/g10/tdbdump.c
index 2d3502caf..799309e05 100644
--- a/g10/tdbdump.c
+++ b/g10/tdbdump.c
@@ -503,7 +503,7 @@ import_ownertrust( const char *fname )
if( rc != -1 )
log_error_f(fname, _("Oops: key is now in trustdb???\n"));
else {
- rc = insert_trust_record( pk );
+ rc = insert_trust_record_by_pk( pk );
if( !rc )
goto repeat; /* update the ownertrust */
log_error_f(fname, _("insert trust record failed: %s\n"),
diff --git a/g10/trustdb.c b/g10/trustdb.c
index 1e804d704..fa1e43a56 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -513,7 +513,7 @@ verify_own_keys(void)
/* make sure that the pubkey is in the trustdb */
rc = query_trust_record( pk );
if( rc == -1 ) { /* put it into the trustdb */
- rc = insert_trust_record( pk );
+ rc = insert_trust_record_by_pk( pk );
if( rc ) {
log_error(_("key %08lX: can't put it into the trustdb\n"),
(ulong)keyid[1] );
@@ -633,10 +633,14 @@ print_user_id( FILE *fp, const char *text, u32 *keyid )
+/****************
+ * This function returns a letter for a trustvalue Trust flags
+ * are ignore.
+ */
int
trust_letter( unsigned value )
{
- switch( value ) {
+ switch( (value & TRUST_MASK) ) {
case TRUST_UNKNOWN: return '-';
case TRUST_EXPIRED: return 'e';
case TRUST_UNDEFINED: return 'q';
@@ -994,6 +998,10 @@ check_keybinding( KBNODE keyblock, KBNODE keynode, u32 *mainkid,
int is_main = (keynode->pkt->pkttype == PKT_PUBLIC_KEY);
int rc;
+ if( DBG_TRUST )
+ log_debug("check_keybinding: %08lX.%lu\n",
+ (ulong)mainkid[1], lid );
+
if( is_main ) {
/* a primary key is always valid (user IDs are handled elsewhere)*/
keyflags = KEYF_CHECKED | KEYF_VALID;
@@ -1134,6 +1142,10 @@ check_uidsigs( KBNODE keyblock, KBNODE keynode, u32 *mainkid, ulong lid )
PKT_signature *selfsig = NULL; /* the latest valid self signature */
int rc;
+ if( DBG_TRUST )
+ log_debug("check_uidsigs: %08lX.%lu\n",
+ (ulong)mainkid[1], lid );
+
/* first we check only the selfsignatures */
for( node=keynode->next; node; node = node->next ) {
if( node->pkt->pkttype == PKT_USER_ID
@@ -1217,6 +1229,10 @@ check_sig_record( KBNODE keyblock, KBNODE signode,
TRUSTREC tmp;
int revocation=0, rc;
+ if( DBG_TRUST )
+ log_debug("check_sig_record: %08lX.%lu %lu[%d]\n",
+ (ulong)keyid[1], lid, siglid, sigidx );
+
if( (sig->sig_class&~3) == 0x10 ) /* regular certification */
;
else if( sig->sig_class == 0x30 ) /* cert revocation */
@@ -1447,6 +1463,8 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
primary_pk->local_id = drec.recnum;
keyid_from_pk( primary_pk, keyid );
+ if( DBG_TRUST )
+ log_debug("update_trust_record: %08lX.%lu\n", (ulong)keyid[1], drec.recnum );
rc = tdbio_begin_transaction();
if( rc )
@@ -1512,14 +1530,11 @@ 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 *orig_pk )
+insert_trust_record( KBNODE keyblock )
{
TRUSTREC dirrec;
TRUSTREC shadow;
- KBNODE keyblock = NULL;
KBNODE node;
- byte fingerprint[MAX_FINGERPRINT_LEN];
- size_t fingerlen;
int rc = 0;
PKT_public_key *pk;
@@ -1529,39 +1544,11 @@ insert_trust_record( PKT_public_key *orig_pk )
init_trustdb();
- 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
- *
- * fixme: If there is no such key we should look whether one
- * of the subkeys has been used to sign another key and in this case
- * we got the key anyway - this is because a secondary key can't be used
- * without a primary key (it is needed to bind the secondary one
- * 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 */
- log_error( _("insert_trust_record: keyblock not found: %s\n"),
- g10_errstr(rc) );
- 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 ) {
- 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;
}
@@ -1581,9 +1568,8 @@ insert_trust_record( PKT_public_key *orig_pk )
dirrec.r.dir.lid = dirrec.recnum;
write_record( &dirrec );
- /* put the LID into the in-memory copy of the keyblock */
+ /* put 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 ) {
@@ -1602,12 +1588,40 @@ insert_trust_record( PKT_public_key *orig_pk )
/* and put all the other stuff into the keydb */
rc = update_trust_record( keyblock, 1, NULL );
- leave:
- release_kbnode( keyblock );
do_sync();
return rc;
}
+/****************
+ * Insert a trust record indentified by a PK into the TrustDB
+ */
+int
+insert_trust_record_by_pk( PKT_public_key *pk )
+{
+ KBNODE keyblock = NULL;
+ byte fingerprint[MAX_FINGERPRINT_LEN];
+ size_t fingerlen;
+ int rc;
+
+ /* get the keyblock */
+ fingerprint_from_pk( pk, fingerprint, &fingerlen );
+ rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
+ if( rc ) { /* that should never happen */
+ log_debug( "insert_trust_record_by_pk: keyblock not found: %s\n",
+ g10_errstr(rc) );
+ }
+ else {
+ rc = insert_trust_record( keyblock );
+ if( !rc ) /* copy the LID into the PK */
+ pk->local_id = find_kbnode( keyblock, PKT_PUBLIC_KEY )
+ ->pkt->pkt.public_key->local_id;
+ }
+
+ release_kbnode( keyblock );
+ return rc;
+}
+
+
/****************
* Walk over the keyrings and create trustdb records for all keys
@@ -1633,8 +1647,9 @@ update_trustdb()
rc = update_trust_record( keyblock, 1, &modified );
if( rc == -1 ) { /* not yet in trustdb: insert */
- PKT_public_key *pk = keyblock->pkt->pkt.public_key;
- rc = insert_trust_record( pk );
+ PKT_public_key *pk;
+ rc = insert_trust_record( keyblock );
+ pk = keyblock->pkt->pkt.public_key;
if( rc && !pk->local_id ) {
log_error(_("lid ?: insert failed: %s\n"),
g10_errstr(rc) );
@@ -1782,7 +1797,7 @@ build_cert_tree( ulong lid, int depth, int max_depth, TN helproot )
m_free(keynode);
return NULL;
}
- keynode->n.k.ownertrust = dirrec.r.dir.ownertrust;
+ keynode->n.k.ownertrust = dirrec.r.dir.ownertrust & TRUST_MASK;
/* loop over all user ids */
for( uidrno = dirrec.r.dir.uidlist; uidrno; uidrno = uidrec.r.uid.next ) {
@@ -1872,12 +1887,17 @@ upd_one_ownertrust( ulong lid, unsigned new_trust, unsigned *retflgs )
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 )
+ if( (new_trust & TRUST_MASK) > (rec.r.dir.ownertrust & TRUST_MASK) )
*retflgs |= 16; /* modified up */
else
*retflgs |= 32; /* modified down */
}
- rec.r.dir.ownertrust = new_trust;
+
+ /* we preserve the disabled state here */
+ if( (rec.r.dir.ownertrust & TRUST_FLAG_DISABLED) )
+ rec.r.dir.ownertrust = new_trust | TRUST_FLAG_DISABLED;
+ else
+ rec.r.dir.ownertrust = new_trust & ~TRUST_FLAG_DISABLED;
write_record( &rec );
}
@@ -2072,8 +2092,9 @@ do_check( TRUSTREC *dr, unsigned *validity,
if( retflgs )
*retflgs &= ~(16|32); /* reset the 2 special flags */
-
- if( namehash ) {
+ if( (dr->r.dir.ownertrust & TRUST_FLAG_DISABLED) )
+ *validity = 0; /* no need to check further */
+ else if( namehash ) {
/* Fixme: use the cache */
*validity = verify_key( opt.max_cert_depth, dr, namehash,
add_fnc, retflgs );
@@ -2091,6 +2112,9 @@ do_check( TRUSTREC *dr, unsigned *validity,
if( !(*validity & TRUST_MASK) )
*validity = TRUST_UNDEFINED;
+ if( (dr->r.dir.ownertrust & TRUST_FLAG_DISABLED) )
+ *validity |= TRUST_FLAG_DISABLED;
+
if( dr->r.dir.dirflags & DIRF_REVOKED )
*validity |= TRUST_FLAG_REVOKED;
@@ -2223,7 +2247,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
return rc;
}
else if( rc == -1 ) { /* not found - insert */
- rc = insert_trust_record( pk );
+ rc = insert_trust_record_by_pk( pk );
if( rc ) {
log_error(_("key %08lX: insert trust record failed: %s\n"),
(ulong)keyid[1], g10_errstr(rc));
@@ -2247,7 +2271,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
log_info(_("key %08lX.%lu: expired at %s\n"),
(ulong)keyid[1], pk->local_id,
asctimestamp( pk->expiredate) );
- trustlevel = TRUST_EXPIRED;
+ trustlevel = TRUST_EXPIRED;
}
else {
rc = do_check( &rec, &trustlevel, namehash, add_fnc, retflgs );
@@ -2364,7 +2388,7 @@ list_trust_path( const char *username )
username, g10_errstr(rc));
else if( rc == -1 ) {
log_info(_("user '%s' not in trustdb - inserting\n"), username);
- rc = insert_trust_record( pk );
+ rc = insert_trust_record_by_pk( pk );
if( rc )
log_error(_("failed to put '%s' into trustdb: %s\n"),
username, g10_errstr(rc));
diff --git a/g10/trustdb.h b/g10/trustdb.h
index 9f3e4c35f..6396fde45 100644
--- a/g10/trustdb.h
+++ b/g10/trustdb.h
@@ -64,8 +64,9 @@ int keyid_from_lid( ulong lid, u32 *keyid );
ulong lid_from_keyblock( KBNODE keyblock );
int query_trust_record( PKT_public_key *pk );
int clear_trust_checked_flag( PKT_public_key *pk );
-int insert_trust_record( PKT_public_key *pk );
int update_trust_record( KBNODE keyblock, int fast, int *modified );
+int insert_trust_record( KBNODE keyblock );
+int insert_trust_record_by_pk( PKT_public_key *pk );
int update_ownertrust( ulong lid, unsigned new_trust );
int trust_letter( unsigned value );