From 1fc1d26083f394a46da6a8b05b60a222cbf879f2 Mon Sep 17 00:00:00 2001 From: David Shaw Date: Wed, 30 Apr 2003 05:33:52 +0000 Subject: [PATCH] * build-packet.c (build_sig_subpkt): Comments. * exec.c (exec_write): Cast NULL to void* to properly terminate varargs list. * keyedit.c (show_key_with_all_names): Just for safety, catch an invalid pk algorithm. * sign.c (make_keysig_packet): Crucial that the call to mksubpkt comes LAST before the calls to finalize the sig as that makes it possible for the mksubpkt function to get a reliable pointer to the subpacket area. * pkclist.c (do_we_trust_pre): If an untrusted key was chosen by a particular user ID, use that ID as the one to ask about when prompting whether to use the key anyway. (build_pk_list): Similar change here when adding keys to the recipient list. * trustdb.c (update_validity): Fix bug that prevented more than one validity record per trust record. (get_validity): When retrieving validity for a (user) supplied user ID, return the validity for that user ID only, and do not fall back to the general key validity. (validate_one_keyblock): Some commentary on whether non-self-signed user IDs belong in the web of trust (arguably, they do). --- g10/ChangeLog | 30 ++++++++++++++++++++++++++ g10/build-packet.c | 4 ++++ g10/exec.c | 5 ++--- g10/keyedit.c | 6 ++++-- g10/pkclist.c | 37 +++++++++++++++++++++------------ g10/sign.c | 5 ++++- g10/trustdb.c | 52 ++++++++++++++++++++++++++++++++++++---------- 7 files changed, 109 insertions(+), 30 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index d80849f07..e7398ef58 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,33 @@ +2003-04-30 David Shaw + + * build-packet.c (build_sig_subpkt): Comments. + + * exec.c (exec_write): Cast NULL to void* to properly terminate + varargs list. + + * keyedit.c (show_key_with_all_names): Just for safety, catch an + invalid pk algorithm. + + * sign.c (make_keysig_packet): Crucial that the call to mksubpkt + comes LAST before the calls to finalize the sig as that makes it + possible for the mksubpkt function to get a reliable pointer to + the subpacket area. + + * pkclist.c (do_we_trust_pre): If an untrusted key was chosen by a + particular user ID, use that ID as the one to ask about when + prompting whether to use the key anyway. + (build_pk_list): Similar change here when adding keys to the + recipient list. + + * trustdb.c (update_validity): Fix bug that prevented more than + one validity record per trust record. + (get_validity): When retrieving validity for a (user) supplied + user ID, return the validity for that user ID only, and do not + fall back to the general key validity. + (validate_one_keyblock): Some commentary on whether + non-self-signed user IDs belong in the web of trust (arguably, + they do). + 2003-04-27 David Shaw * g10.c (main): Add --no-textmode. diff --git a/g10/build-packet.c b/g10/build-packet.c index 92e357f7e..3fec9a84c 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -794,6 +794,10 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type, case SIGSUBPKT_PRIV_VERIFY_CACHE: /*(obsolete)*/ BUG(); break; + /* The issuer being unhashed is a historical oddity. It + should work equally as well hashed. Of course, if even an + unhashed issuer is tampered with, it makes it awfully hard + to verify the sig... */ case SIGSUBPKT_ISSUER: hashed = 0; break; diff --git a/g10/exec.c b/g10/exec.c index fd592e853..0278438f6 100644 --- a/g10/exec.c +++ b/g10/exec.c @@ -417,14 +417,14 @@ int exec_write(struct exec_info **info,const char *program, if(DBG_EXTPROG) log_debug("execlp: %s\n",program); - execlp(program,program,NULL); + execlp(program,program,(void *)NULL); } else { if(DBG_EXTPROG) log_debug("execlp: %s -c %s\n",shell,(*info)->command); - execlp(shell,shell,"-c",(*info)->command,NULL); + execlp(shell,shell,"-c",(*info)->command,(void *)NULL); } /* If we get this far the exec failed. Clean up and return. */ @@ -617,4 +617,3 @@ int exec_finish(struct exec_info *info) return ret; } #endif /* ! NO_EXEC */ - diff --git a/g10/keyedit.c b/g10/keyedit.c index 0324b4070..333552c38 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1983,13 +1983,15 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker, for(i=0;inumrevkeys;i++) { u32 r_keyid[2]; char *user; - + const char *algo= + pubkey_algo_to_string(pk->revkey[i].algid); + keyid_from_fingerprint(pk->revkey[i].fpr, MAX_FINGERPRINT_LEN,r_keyid); user=get_user_id_string (r_keyid); tty_printf (_("This key may be revoked by %s key "), - pubkey_algo_to_string (pk->revkey[i].algid)); + algo?algo:"?"); tty_print_utf8_string (user, strlen (user)); if ((pk->revkey[i].class&0x40)) tty_printf (_(" (sensitive)")); diff --git a/g10/pkclist.c b/g10/pkclist.c index 99f98b336..671fe208a 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -542,17 +542,23 @@ do_we_trust_pre( PKT_public_key *pk, unsigned int trustlevel ) return 0; if( !opt.batch && !rc ) { - char *p; u32 keyid[2]; - size_t n; keyid_from_pk( pk, keyid); tty_printf( "%4u%c/%08lX %s \"", nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), (ulong)keyid[1], datestr_from_pk( pk ) ); - p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ), - m_free(p); + /* If the pk was chosen by a particular user ID, this is the + one to ask about. */ + if(pk->user_id) + tty_print_utf8_string(pk->user_id->name,pk->user_id->len); + else + { + size_t n; + char *p = get_user_id( keyid, &n ); + tty_print_utf8_string( p, n ); + m_free(p); + } tty_printf("\"\n"); print_fingerprint (pk, NULL, 2); tty_printf("\n"); @@ -932,8 +938,8 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ) } else { int trustlevel; - - trustlevel = get_validity (pk, NULL); + + trustlevel = get_validity (pk, pk->user_id); if( (trustlevel & TRUST_FLAG_DISABLED) ) { tty_printf(_("Public key is disabled.\n") ); } @@ -946,8 +952,6 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ) } else { PK_LIST r; - char *p; - size_t n; u32 keyid[2]; keyid_from_pk( pk, keyid); @@ -956,9 +960,16 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ) pubkey_letter( pk->pubkey_algo ), (ulong)keyid[1], datestr_from_pk( pk ) ); - p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ); - m_free(p); + if(pk->user_id) + tty_print_utf8_string(pk->user_id->name, + pk->user_id->len); + else + { + size_t n; + char *p = get_user_id( keyid, &n ); + tty_print_utf8_string( p, n ); + m_free(p); + } tty_printf("\"\n"); r = m_alloc( sizeof *r ); @@ -1028,7 +1039,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ) else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) { int trustlevel; - trustlevel = get_validity (pk, NULL); + trustlevel = get_validity (pk, pk->user_id); if( (trustlevel & TRUST_FLAG_DISABLED) ) { free_public_key(pk); pk = NULL; log_info(_("%s: skipped: public key is disabled\n"), diff --git a/g10/sign.c b/g10/sign.c index 2b56240e6..8311bdb08 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1251,12 +1251,15 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, sig->sig_class = sigclass; if( sig->version >= 4 ) build_sig_subpkt_from_sig( sig ); + mk_notation_and_policy( sig, pk, sk ); + /* Crucial that the call to mksubpkt comes LAST before the calls + to finalize the sig as that makes it possible for the mksubpkt + function to get a reliable pointer to the subpacket area. */ if( sig->version >= 4 && mksubpkt ) rc = (*mksubpkt)( sig, opaque ); if( !rc ) { - mk_notation_and_policy( sig, pk, sk ); hash_sigversion_to_magic (md, sig); md_final(md); diff --git a/g10/trustdb.c b/g10/trustdb.c index c97687653..b3aa436d4 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -873,13 +873,13 @@ update_validity (PKT_public_key *pk, PKT_user_id *uid, vrec.rectype = RECTYPE_VALID; memcpy (vrec.r.valid.namehash, uid->namehash, 20); vrec.r.valid.next = trec.r.trust.validlist; + trec.r.trust.validlist = vrec.recnum; } vrec.r.valid.validity = validity; vrec.r.valid.full_count = uid->help_full_count; vrec.r.valid.marginal_count = uid->help_marginal_count; write_record (&vrec); trec.r.trust.depth = depth; - trec.r.trust.validlist = vrec.recnum; write_record (&trec); } @@ -985,7 +985,7 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid) if(uid) namehash_from_uid(uid); - + init_trustdb (); if (!did_nextcheck && (opt.trust_model==TM_CLASSIC || opt.trust_model==TM_OPENPGP)) @@ -1043,16 +1043,30 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid) while (recno) { read_record (recno, &vrec, RECTYPE_VALID); - if ( validity < (vrec.r.valid.validity & TRUST_MASK) ) - validity = (vrec.r.valid.validity & TRUST_MASK); - if ( uid && !memcmp (vrec.r.valid.namehash, uid->namehash, 20) ) - break; + + if(uid) + { + /* If a user ID is given we return the validity for that + user ID ONLY. If the namehash is not found, then there + is no validity at all (i.e. the user ID wasn't + signed). */ + if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0) + { + validity=(vrec.r.valid.validity & TRUST_MASK); + break; + } + } + else + { + /* If no namehash is given, we take the maximum validity + over all user IDs */ + if ( validity < (vrec.r.valid.validity & TRUST_MASK) ) + validity = (vrec.r.valid.validity & TRUST_MASK); + } + recno = vrec.r.valid.next; } - if (recno) /* okay, use the user ID associated one */ - validity = (vrec.r.valid.validity & TRUST_MASK); - if ( (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) ) validity |= TRUST_FLAG_DISABLED; @@ -1528,6 +1542,16 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist, keyid_from_pk(pk, main_kid); for (node=kb; node; node = node->next) { + /* A bit of discussion here: is it better for the web of trust + to be built among only self-signed uids? On the one hand, a + self-signed uid is a statement that the key owner definitely + intended that uid to be there, but on the other hand, a + signed (but not self-signed) uid does carry trust, of a sort, + even if it is a statement being made by people other than the + key owner "through" the uids on the key owner's key. I'm + going with the latter. -dshaw */ + + /* && node->pkt->pkt.user_id->created) */ if (node->pkt->pkttype == PKT_USER_ID) { if (uidnode && issigned) @@ -1542,13 +1566,19 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist, } uidnode = node; uid=uidnode->pkt->pkt.user_id; +#if 0 + /* If the selfsig is going to expire... This is disabled as + we do count un-self-signed uids in the web of trust. */ + if(uid->expiredate && uid->expiredate<*next_expire) + *next_expire = uid->expiredate; +#endif issigned = 0; get_validity_counts(pk,uid); mark_usable_uid_certs (kb, uidnode, main_kid, klist, curtime, next_expire); } - else if (node->pkt->pkttype == PKT_SIGNATURE - && (node->flag & (1<<8)) && uid) + else if (node->pkt->pkttype == PKT_SIGNATURE + && (node->flag & (1<<8)) && uid) { /* Note that we are only seeing unrevoked sigs here */ PKT_signature *sig = node->pkt->pkt.signature;