aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2001-09-27 16:22:23 +0000
committerWerner Koch <[email protected]>2001-09-27 16:22:23 +0000
commit531f3953d89acb3dfb730eb3d7e3bd66da1f6483 (patch)
tree8c9c6b81150cadfa274012a9edceafbb640dbbfb
parentcompleted the new key validation code (diff)
downloadgnupg-531f3953d89acb3dfb730eb3d7e3bd66da1f6483.tar.gz
gnupg-531f3953d89acb3dfb730eb3d7e3bd66da1f6483.zip
Encryption should work again
-rw-r--r--g10/ChangeLog19
-rw-r--r--g10/helptext.c15
-rw-r--r--g10/keyedit.c13
-rw-r--r--g10/pkclist.c331
-rw-r--r--g10/trustdb.c91
-rw-r--r--g10/trustdb.h2
6 files changed, 242 insertions, 229 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 9d11f1c6b..cb40e3e75 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,5 +1,20 @@
+2001-09-27 Werner Koch <[email protected]>
+
+ * pkclist.c (do_edit_ownertrust): Allow settin of ultimate trust.
+
+ * trustdb.c (mark_keyblock_seen): New.
+ (make_key_array): Use it to mark the subkeys too.
+ (validate_keys): Store validity for ultimatly trusted keys.
+
2001-09-26 Werner Koch <[email protected]>
+ * pkclist.c (check_signatures_trust, do_we_trust): Removed the
+ invocation of add_ownertrust. Minor changes to the wording.
+ (add_ownertrust, add_ownertrust_cb): Removed.
+
+ * trustdb.c (get_validity): Allow to lookup the validity using a
+ subkey.
+
* trustdb.c (new_key_hash_table): Increased the table size to 1024
and changed the masks accordingly.
(validate): Changed stats printing.
@@ -121,7 +136,7 @@
2001-09-14 Werner Koch <[email protected]>
* parse-packet.c (dump_sig_subpkt): List key server preferences
- and show the revocable flag correctly. Contributed by Davod Shaw.
+ and show the revocable flag correctly. Contributed by David Shaw.
2001-09-09 Werner Koch <[email protected]>
@@ -653,7 +668,7 @@
* cipher.c (write_header): Set extralen.
* build-packet.c (do_encrypted): Use extralen instead of const 10.
(do_encrypted_mdc): Ditto.
- * parse-packet.c (parse_encrypted): Set extralen to 0 becuase we
+ * parse-packet.c (parse_encrypted): Set extralen to 0 because we
don't know it here.
2001-03-30 Werner Koch <[email protected]>
diff --git a/g10/helptext.c b/g10/helptext.c
index 77497b6ce..fb919dc44 100644
--- a/g10/helptext.c
+++ b/g10/helptext.c
@@ -49,6 +49,13 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
"to do with the (implicitly created) web-of-certificates."
)},
+{ "edit_ownertrust.set_ultimate.okay", N_(
+ "To build the Web-of-Trust, GnuPG needs to know which keys are\n"
+ "ultimately trusted - those are usually the keys for which you have\n"
+ "access to the secret key. Answer \"yes\" to set this key to\n"
+ "ultimately trusted\n"
+)},
+
{ "revoked_key.override", N_(
"If you want to use this revoked key anyway, answer \"yes\"."
)},
@@ -203,14 +210,6 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
"self-signatures fill be advanced by one second.\n"
)},
-{ "keyedit.trust.set_ultimate.okay", N_(
- "To build the Web-of-Trust, GnuPG needs to know which keys are\n"
- "ultimately trusted - those are usually the keys for which you have\n"
- "access to the secret key. Answer \"yes\" to set this key to\n"
- "ultimately trusted; if you choose not to do so, you will then be\n"
- "taken to the regular ownertrust menu.\n"
-)},
-
{ "passphrase.enter", N_(
""
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 9c55b555d..770b2cdfb 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -928,19 +928,6 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
case cmdTRUST:
show_key_with_all_names( keyblock, 0, 0, 1, 0 );
tty_printf("\n");
- if ( sec_keyblock
- && cpr_get_answer_is_yes(
- "keyedit.trust.set_ultimate.okay",
- _("Do you want to set this key to ultimately trusted? "))) {
- PKT_public_key *pk = keyblock->pkt->pkt.public_key;
-
- update_ownertrust (pk,
- ((get_ownertrust (pk) & ~TRUST_MASK)
- | TRUST_ULTIMATE ));
- redisplay = 1;
- break;
- }
-
if( edit_ownertrust( find_kbnode( keyblock,
PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) )
redisplay = 1;
diff --git a/g10/pkclist.c b/g10/pkclist.c
index af5813231..52310282c 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -219,11 +219,12 @@ show_paths (const PKT_public_key *pk, int only_first )
/****************
* mode: 0 = standard
* 1 = Without key info and additional menu option 'm'
+ * this does also add an option to set the key to ultimately trusted.
* Returns:
* -2 = nothing changed - caller should show some additional info
* -1 = quit operation
* 0 = nothing changed
- * 1 = new ownertrust now ion new_trust
+ * 1 = new ownertrust now in new_trust
*/
static int
do_edit_ownertrust (PKT_public_key *pk, int mode,
@@ -257,15 +258,17 @@ do_edit_ownertrust (PKT_public_key *pk, int mode,
print_fingerprint (pk, NULL, 2);
tty_printf("\n");
}
- tty_printf(_(
+ tty_printf (_(
"Please decide how far you trust this user to correctly\n"
"verify other users' keys (by looking at passports,\n"
- "checking fingerprints from different sources...)?\n\n"
- " 1 = Don't know\n"
- " 2 = I do NOT trust\n"
- " 3 = I trust marginally\n"
- " 4 = I trust fully\n"
- " s = please show me more information\n") );
+ "checking fingerprints from different sources...)?\n\n"));
+ tty_printf (_(" %d = Don't know\n"), 1);
+ tty_printf (_(" %d = I do NOT trust\n"), 2);
+ tty_printf (_(" %d = I trust marginally\n"), 3);
+ tty_printf (_(" %d = I trust fully\n"), 4);
+ if (mode)
+ tty_printf (_(" %d = I trust ultimately\n"), 5);
+ tty_printf (_(" s = please show me more information\n") );
if( mode )
tty_printf(_(" m = back to the main menu\n"));
else
@@ -282,20 +285,29 @@ do_edit_ownertrust (PKT_public_key *pk, int mode,
did_help = 0;
else if( *p && p[1] )
;
- else if( !p[1] && (*p >= '1' && *p <= '4') )
+ else if( !p[1] && (*p >= '1' && *p <= (mode?'5':'4')) )
{
- unsigned trust;
+ unsigned int trust;
switch( *p )
{
case '1': trust = TRUST_UNDEFINED; break;
case '2': trust = TRUST_NEVER ; break;
case '3': trust = TRUST_MARGINAL ; break;
case '4': trust = TRUST_FULLY ; break;
+ case '5': trust = TRUST_ULTIMATE ; break;
default: BUG();
}
- *new_trust = trust;
- changed = 1;
- break;
+ if (trust == TRUST_ULTIMATE
+ && !cpr_get_answer_is_yes ("edit_ownertrust.set_ultimate.okay",
+ _("Do you really want to set this key"
+ " to ultimate trust? ")))
+ ; /* no */
+ else
+ {
+ *new_trust = trust;
+ changed = 1;
+ break;
+ }
}
else if( *p == ans[0] || *p == ans[1] )
{
@@ -350,73 +362,37 @@ edit_ownertrust (PKT_public_key *pk, int mode )
}
}
-static int
-add_ownertrust_cb (PKT_public_key *pk )
-{
- unsigned int trust;
- int rc = do_edit_ownertrust (pk, 0, &trust, 0 );
-
- 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 ownertrust value assigned.
- * Returns: -1 if no ownertrust were added.
- */
-static int
-add_ownertrust( PKT_public_key *pk, int *quit, int *trustlevel )
-{
- int rc;
- unsigned flags = 0;
-
-#warning This function does not make sense anymore
- *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"));
-
- *trustlevel = get_validity ( pk, NULL);
-
- if( !(flags & 1) )
- tty_printf(_("No path leading to one of our keys found.\n\n") );
- else if( !(flags & 2) )
- tty_printf(_("No certificates with undefined trust found.\n\n") );
- else if( !(flags & 4) )
- tty_printf(_("No trust values changed.\n\n") );
-
- return (flags & 4)? 0:-1;
-}
/****************
* Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL
- * Returns: true if we trust. Might change the trustlevel
+ * Returns: true if we trust.
*/
static int
-do_we_trust( PKT_public_key *pk, int *trustlevel )
+do_we_trust( PKT_public_key *pk, unsigned int *trustlevel )
{
- int rc;
- int did_add = 0;
- int trustmask = 0;
-
- retry:
+ unsigned int trustmask = 0;
+
+ /* FIXME: get_pubkey_byname already checks the validity and won't
+ * return keys which are either expired or revoked - so these
+ * question here won't get triggered. We have to find a solution
+ * for this. It might make sense to have a function in getkey.c
+ * which does only the basic checks and returns even revoked and
+ * expired keys. This fnction could then also returhn a list of
+ * keys if the speicified name is ambiguous
+ */
if( (*trustlevel & TRUST_FLAG_REVOKED) ) {
log_info(_("key %08lX: key has been revoked!\n"),
(ulong)keyid_from_pk( pk, NULL) );
show_revocation_reason( pk );
if( opt.batch )
- return 0;
+ return 0; /* no */
if( !cpr_get_answer_is_yes("revoked_key.override",
_("Use this key anyway? ")) )
- return 0;
+ return 0; /* no */
trustmask |= TRUST_FLAG_REVOKED;
}
- else if( (*trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
+ if( (*trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
log_info(_("key %08lX: subkey has been revoked!\n"),
(ulong)keyid_from_pk( pk, NULL) );
show_revocation_reason( pk );
@@ -433,43 +409,25 @@ do_we_trust( PKT_public_key *pk, int *trustlevel )
if( opt.always_trust) {
if( opt.verbose )
log_info("No trust check due to --always-trust option\n");
- /* The problem with this, is that EXPIRE can't be checked as
- * this needs to insert a new key into the trustdb first and
- * we don't want that - IS this still true? */
return 1;
}
-
switch( (*trustlevel & TRUST_MASK) ) {
- case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
- *trustlevel = get_validity (pk, NULL);
- *trustlevel &= ~trustmask;
- if( *trustlevel == TRUST_UNKNOWN || *trustlevel == TRUST_EXPIRED ) {
- log_debug("do_we_trust: oops at %d\n", __LINE__ );
- return 0;
- }
- return do_we_trust( pk, trustlevel );
-
case TRUST_EXPIRED:
log_info(_("%08lX: key has expired\n"),
(ulong)keyid_from_pk( pk, NULL) );
return 0; /* no */
+ default:
+ log_error ("invalid trustlevel %u returned from validation layer\n",
+ *trustlevel);
+ /* fall thru */
+ case TRUST_UNKNOWN:
case TRUST_UNDEFINED:
- if( opt.batch || opt.answer_no )
- log_info(_("%08lX: no info to calculate a trust probability\n"),
- (ulong)keyid_from_pk( pk, NULL) );
- else {
- int quit;
-
- rc = add_ownertrust( pk, &quit, trustlevel );
- *trustlevel &= ~trustmask;
- if( !rc && !did_add && !quit ) {
- did_add = 1;
- goto retry;
- }
- }
- return 0;
+ log_info(_("%08lX: There is no indication that this key "
+ "really belongs to the owner\n"),
+ (ulong)keyid_from_pk( pk, NULL) );
+ return 0; /* no */
case TRUST_NEVER:
log_info(_("%08lX: We do NOT trust this key\n"),
@@ -491,8 +449,6 @@ do_we_trust( PKT_public_key *pk, int *trustlevel )
if( opt.verbose )
log_info(_("This key belongs to us\n"));
return 1; /* yes */
-
- default: BUG();
}
return 1; /* yes */
@@ -505,7 +461,7 @@ do_we_trust( PKT_public_key *pk, int *trustlevel )
* key anyway.
*/
static int
-do_we_trust_pre( PKT_public_key *pk, int trustlevel )
+do_we_trust_pre( PKT_public_key *pk, unsigned int trustlevel )
{
int rc;
@@ -515,7 +471,8 @@ do_we_trust_pre( PKT_public_key *pk, int trustlevel )
return 0;
if( (trustlevel & TRUST_FLAG_SUB_REVOKED) && !rc )
return 0;
- else if( !opt.batch && !rc ) {
+
+ if( !opt.batch && !rc ) {
char *p;
u32 keyid[2];
size_t n;
@@ -540,7 +497,7 @@ do_we_trust_pre( PKT_public_key *pk, int trustlevel )
_("Use this key anyway? ")) )
rc = 1;
- /* Hmmm: Should we set a flag to tell the user the user about
+ /* Hmmm: Should we set a flag to tell the user about
* his decision the next time he encrypts for this recipient?
*/
}
@@ -561,117 +518,105 @@ do_we_trust_pre( PKT_public_key *pk, int trustlevel )
int
check_signatures_trust( PKT_signature *sig )
{
- PKT_public_key *pk = m_alloc_clear( sizeof *pk );
- int trustlevel;
- int did_add = 0;
- int rc=0;
-
+ PKT_public_key *pk = m_alloc_clear( sizeof *pk );
+ unsigned int trustlevel;
+ int did_add = 0;
+ int rc=0;
- if( opt.always_trust ) {
- if( !opt.quiet )
- log_info(_("WARNING: Using untrusted key!\n"));
- if (opt.with_fingerprint)
- print_fingerprint (pk, NULL, 1);
- rc = 0;
- goto leave;
+ if ( opt.always_trust)
+ {
+ if( !opt.quiet )
+ log_info(_("WARNING: Using untrusted key!\n"));
+ if (opt.with_fingerprint)
+ print_fingerprint (pk, NULL, 1);
+ goto leave;
}
-
- rc = get_pubkey( pk, sig->keyid );
- if( rc ) { /* this should not happen */
- log_error("Ooops; the key vanished - can't check the trust\n");
- rc = G10ERR_NO_PUBKEY;
- goto leave;
+ rc = get_pubkey( pk, sig->keyid );
+ if (rc)
+ { /* this should not happen */
+ log_error("Ooops; the key vanished - can't check the trust\n");
+ rc = G10ERR_NO_PUBKEY;
+ goto leave;
}
- trustlevel = get_validity (pk, NULL);
+ trustlevel = get_validity (pk, NULL);
- retry:
- if( (trustlevel & TRUST_FLAG_REVOKED) ) {
- write_status( STATUS_KEYREVOKED );
- log_info(_("WARNING: This key has been revoked by its owner!\n"));
- log_info(_(" This could mean that the signature is forgery.\n"));
- show_revocation_reason( pk );
+ if ( (trustlevel & TRUST_FLAG_REVOKED) )
+ {
+ write_status( STATUS_KEYREVOKED );
+ log_info(_("WARNING: This key has been revoked by its owner!\n"));
+ log_info(_(" This could mean that the signature is forgery.\n"));
+ show_revocation_reason( pk );
}
- else if( (trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
- write_status( STATUS_KEYREVOKED );
- log_info(_("WARNING: This subkey has been revoked by its owner!\n"));
- show_revocation_reason( pk );
+ else if ((trustlevel & TRUST_FLAG_SUB_REVOKED) )
+ {
+ write_status( STATUS_KEYREVOKED );
+ log_info(_("WARNING: This subkey has been revoked by its owner!\n"));
+ show_revocation_reason( pk );
}
+
+ if ((trustlevel & TRUST_FLAG_DISABLED))
+ log_info (_("Note: This key has been disabled.\n"));
-
- switch( (trustlevel & TRUST_MASK) ) {
- case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
- trustlevel = get_validity (pk, NULL);
- if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED )
- BUG();
- goto retry;
-
- case TRUST_EXPIRED:
- log_info(_("Note: This key has expired!\n"));
+ switch ( (trustlevel & TRUST_MASK) )
+ {
+ case TRUST_EXPIRED:
+ log_info(_("Note: This key has expired!\n"));
+ print_fingerprint (pk, NULL, 1);
+ break;
+
+ default:
+ log_error ("invalid trustlevel %u returned from validation layer\n",
+ trustlevel);
+ /* fall thru */
+ case TRUST_UNKNOWN:
+ case TRUST_UNDEFINED:
+ 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"));
+ log_info(_(" There is no indication that the "
+ "signature belongs to the owner.\n" ));
print_fingerprint (pk, NULL, 1);
- break;
-
- case TRUST_UNDEFINED:
- 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"));
- log_info(_(
- " There is no indication that the "
- "signature belongs to the owner.\n" ));
- print_fingerprint (pk, NULL, 1);
- }
- else {
- int quit;
- rc = add_ownertrust( pk, &quit, &trustlevel );
- if( rc || quit ) {
- did_add = 1;
- rc = 0;
- }
- goto retry;
- }
- break;
-
- case TRUST_NEVER:
- write_status( STATUS_TRUST_NEVER );
- log_info(_("WARNING: We do NOT trust this key!\n"));
- log_info(_(" The signature is probably a FORGERY.\n"));
- if (opt.with_fingerprint)
- print_fingerprint (pk, NULL, 1);
- rc = G10ERR_BAD_SIGN;
- break;
-
- case TRUST_MARGINAL:
- write_status( STATUS_TRUST_MARGINAL );
- log_info(_(
- "WARNING: This key is not certified with sufficiently trusted signatures!\n"
- ));
- log_info(_(
- " It is not certain that the signature belongs to the owner.\n"
- ));
+ }
+ break;
+
+ case TRUST_NEVER:
+ /* currently we won't get that status */
+ write_status( STATUS_TRUST_NEVER );
+ log_info(_("WARNING: We do NOT trust this key!\n"));
+ log_info(_(" The signature is probably a FORGERY.\n"));
+ if (opt.with_fingerprint)
print_fingerprint (pk, NULL, 1);
- break;
-
- case TRUST_FULLY:
- write_status( STATUS_TRUST_FULLY );
- if (opt.with_fingerprint)
- print_fingerprint (pk, NULL, 1);
- break;
-
- case TRUST_ULTIMATE:
- write_status( STATUS_TRUST_ULTIMATE );
- if (opt.with_fingerprint)
- print_fingerprint (pk, NULL, 1);
- break;
+ rc = G10ERR_BAD_SIGN;
+ break;
+
+ case TRUST_MARGINAL:
+ write_status( STATUS_TRUST_MARGINAL );
+ log_info(_("WARNING: This key is not certified with"
+ " sufficiently trusted signatures!\n"));
+ log_info(_(" It is not certain that the"
+ " signature belongs to the owner.\n" ));
+ print_fingerprint (pk, NULL, 1);
+ break;
+
+ case TRUST_FULLY:
+ write_status( STATUS_TRUST_FULLY );
+ if (opt.with_fingerprint)
+ print_fingerprint (pk, NULL, 1);
+ break;
- default: BUG();
+ case TRUST_ULTIMATE:
+ write_status( STATUS_TRUST_ULTIMATE );
+ if (opt.with_fingerprint)
+ print_fingerprint (pk, NULL, 1);
+ break;
}
-
- leave:
- free_public_key( pk );
- return rc;
+ leave:
+ free_public_key( pk );
+ return rc;
}
diff --git a/g10/trustdb.c b/g10/trustdb.c
index 6f3de849d..9714bf938 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -165,7 +165,6 @@ add_key_hash_table (KeyHashTable tbl, u32 *kid)
tbl[(kid[1] & 0x03ff)] = kk;
}
-
/*
* Release a key_array
*/
@@ -671,6 +670,8 @@ get_validity (PKT_public_key *pk, const byte *namehash)
int rc;
ulong recno;
unsigned int validity;
+ u32 kid[2];
+ PKT_public_key *main_pk;
init_trustdb ();
if (!did_nextcheck)
@@ -690,14 +691,33 @@ get_validity (PKT_public_key *pk, const byte *namehash)
}
}
- rc = read_trust_record (pk, &trec);
+ keyid_from_pk (pk, kid);
+ if (pk->main_keyid[0] != kid[0] || pk->main_keyid[1] != kid[1])
+ { /* this is a subkey - get the mainkey */
+ main_pk = m_alloc_clear (sizeof *main_pk);
+ rc = get_pubkey (main_pk, pk->main_keyid);
+ if (rc)
+ {
+ log_error ("error getting main key %08lX of subkey %08lX: %s\n",
+ (ulong)pk->main_keyid[1], (ulong)kid[1], g10_errstr(rc));
+ validity = TRUST_UNKNOWN;
+ goto leave;
+ }
+ }
+ else
+ main_pk = pk;
+
+ rc = read_trust_record (main_pk, &trec);
if (rc && rc != -1)
{
tdbio_invalid ();
return 0;
}
if (rc == -1) /* no record found */
- return TRUST_UNKNOWN;
+ {
+ validity = TRUST_UNKNOWN;
+ goto leave;
+ }
/* loop over all user IDs */
recno = trec.r.trust.validlist;
@@ -719,13 +739,18 @@ get_validity (PKT_public_key *pk, const byte *namehash)
validity |= TRUST_FLAG_DISABLED;
/* set some flags direct from the key */
- if (pk->is_revoked)
+ if (main_pk->is_revoked)
validity |= TRUST_FLAG_REVOKED;
+ if (main_pk != pk && pk->is_revoked)
+ validity |= TRUST_FLAG_SUB_REVOKED;
/* Note: expiration is a trust value and not a flag - don't know why
* I initially designed it that way */
- if (pk->has_expired)
+ if (main_pk->has_expired || pk->has_expired)
validity = (validity & ~TRUST_MASK) | TRUST_EXPIRED;
+ leave:
+ if (main_pk != pk)
+ free_public_key (main_pk);
return validity;
}
@@ -825,10 +850,25 @@ ask_ownertrust (u32 *kid)
}
+static void
+mark_keyblock_seen (KeyHashTable tbl, KBNODE node)
+{
+ for ( ;node; node = node->next )
+ if (node->pkt->pkttype == PKT_PUBLIC_KEY
+ || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+ {
+ u32 aki[2];
+
+ keyid_from_pk (node->pkt->pkt.public_key, aki);
+ add_key_hash_table (tbl, aki);
+ }
+}
+
+
static int
search_skipfnc (void *opaque, u32 *kid)
{
- return test_key_hash_table ((KeyHashTable)opaque, kid);
+ return test_key_hash_table ((KeyHashTable)opaque, kid);
}
/*
@@ -882,7 +922,6 @@ make_key_array (KEYDB_HANDLE hd, KeyHashTable visited,
do
{
PKT_public_key *pk;
- u32 kid[2];
rc = keydb_get_keyblock (hd, &keyblock);
if (rc)
@@ -905,12 +944,10 @@ make_key_array (KEYDB_HANDLE hd, KeyHashTable visited,
merge_keys_and_selfsig (keyblock);
clear_kbnode_flags (keyblock);
pk = keyblock->pkt->pkt.public_key;
- keyid_from_pk (pk, kid); /*(cheap: should already be cached in the pk)*/
-
if (pk->has_expired || pk->is_revoked)
{
/* it does not make sense to look further at those keys */
- add_key_hash_table (visited, kid);
+ mark_keyblock_seen (visited, keyblock);
}
else if (cmpfnc (keyblock, cmpval))
{
@@ -920,7 +957,7 @@ make_key_array (KEYDB_HANDLE hd, KeyHashTable visited,
}
keys[nkeys++].keyblock = keyblock;
/* This key is signed - don't check it again */
- add_key_hash_table (visited, kid);
+ mark_keyblock_seen (visited, keyblock);
}
else
release_kbnode (keyblock);
@@ -1256,8 +1293,38 @@ validate_keys (int interactive)
goto leave;
}
+ /* mark all UTKs as visited and set validity to ultimate */
for (k=utk_list; k; k = k->next)
- add_key_hash_table (visited, k->kid);
+ {
+ KBNODE keyblock;
+
+ keyblock = get_pubkeyblock (k->kid);
+ if (!keyblock)
+ {
+ log_error (_("public key of ultimately"
+ " trusted key %08lX not found\n"), (ulong)k->kid[1]);
+ continue;
+ }
+ mark_keyblock_seen (visited, keyblock);
+ for (node=keyblock; node; node = node->next)
+ {
+ if (node->pkt->pkttype == PKT_USER_ID)
+ {
+ byte namehash[20];
+ PKT_user_id *uid = node->pkt->pkt.user_id;
+
+ if( uid->photo )
+ rmd160_hash_buffer (namehash, uid->photo, uid->photolen);
+ else
+ rmd160_hash_buffer (namehash, uid->name, uid->len );
+ update_validity (keyblock->pkt->pkt.public_key,
+ namehash, 0, TRUST_ULTIMATE);
+ }
+ }
+ release_kbnode (keyblock);
+ do_sync ();
+ }
+
klist = utk_list;
kdb = keydb_new (0);
diff --git a/g10/trustdb.h b/g10/trustdb.h
index 672d85241..e9c62670c 100644
--- a/g10/trustdb.h
+++ b/g10/trustdb.h
@@ -33,7 +33,7 @@
#define TRUST_ULTIMATE 6 /* u: ultimately trusted */
/* trust values not covered by the mask */
#define TRUST_FLAG_REVOKED 32 /* r: revoked */
-#define TRUST_FLAG_SUB_REVOKED 64
+#define TRUST_FLAG_SUB_REVOKED 64 /* r: revoked but for subkeys */
#define TRUST_FLAG_DISABLED 128 /* d: key/uid disabled */