* trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename

is_disabled to cache_disabled_value, which now takes a pk and not just the
keyid. This is for speed since there is no need to re-fetch a key when we
already have that key handy.  Cache the result of the check so we don't
need to hit the trustdb more than once.

* getkey.c (skip_disabled): New function to get a pk and call is_disabled
on it. (key_byname): Use it here.

* packet.h, getkey.c (skip_disabled), keylist.c (print_capabilities): New
"pk_is_disabled" macro to retrieve the cached disabled value if available,
and fill it in via cache_disabled_value if not available.

* trustdb.c (get_validity): Cache the disabled value since we have it
handy and it might be useful later.

* parse-packet.c (parse_key): Clear disabled flag when parsing a new key.
Just in case someone forgets to clear the whole key.

* getkey.c (merge_selfsigs_main): Add an "if all else fails" path for
setting a single user ID primary when there are multiple set primaries all
at the same second, or no primaries set and the most recent user IDs are
at the same second, or no signed user IDs at all. This is arbitrary, but
deterministic.

* exec.h, photoid.h: Add copyright message.

* keylist.c (list_keyblock_print): Don't dump attribs for
revoked/expired/etc uids for non-colon key listings.  This is for
consistency with --show-photos.

* main.h, keylist.c (dump_attribs), mainproc.c (check_sig_and_print): Dump
attribs if --attrib-fd is set when verifying signatures.

* g10.c (main): New --gnupg option to disable the various --openpgp,
--pgpX, etc. options.  This is the same as --no-XXXX for those options.

* revoke.c (ask_revocation_reason): Clear old reason if user elects to
repeat question.  This is bug 153.

* keyedit.c (sign_uids): Show keyid of the key making the signature.
This commit is contained in:
David Shaw 2003-05-21 16:42:22 +00:00
parent 67a6cd7168
commit 2e821d77f7
15 changed files with 236 additions and 79 deletions

View File

@ -1,3 +1,52 @@
2003-05-21 David Shaw <dshaw@jabberwocky.com>
* trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename
is_disabled to cache_disabled_value, which now takes a pk and not
just the keyid. This is for speed since there is no need to
re-fetch a key when we already have that key handy. Cache the
result of the check so we don't need to hit the trustdb more than
once.
* getkey.c (skip_disabled): New function to get a pk and call
is_disabled on it. (key_byname): Use it here.
* packet.h, getkey.c (skip_disabled), keylist.c
(print_capabilities): New "pk_is_disabled" macro to retrieve the
cached disabled value if available, and fill it in via
cache_disabled_value if not available.
* trustdb.c (get_validity): Cache the disabled value since we have
it handy and it might be useful later.
* parse-packet.c (parse_key): Clear disabled flag when parsing a
new key. Just in case someone forgets to clear the whole key.
* getkey.c (merge_selfsigs_main): Add an "if all else fails" path
for setting a single user ID primary when there are multiple set
primaries all at the same second, or no primaries set and the most
recent user IDs are at the same second, or no signed user IDs at
all. This is arbitrary, but deterministic.
* exec.h, photoid.h: Add copyright message.
* keylist.c (list_keyblock_print): Don't dump attribs for
revoked/expired/etc uids for non-colon key listings. This is for
consistency with --show-photos.
* main.h, keylist.c (dump_attribs), mainproc.c
(check_sig_and_print): Dump attribs if --attrib-fd is set when
verifying signatures.
* g10.c (main): New --gnupg option to disable the various
--openpgp, --pgpX, etc. options. This is the same as --no-XXXX
for those options.
* revoke.c (ask_revocation_reason): Clear old reason if user
elects to repeat question. This is bug 153.
* keyedit.c (sign_uids): Show keyid of the key making the
signature.
2003-05-21 Werner Koch <wk@gnupg.org>
* progress.c (handle_progress)

View File

@ -1,3 +1,23 @@
/* exec.h
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef _EXEC_H_
#define _EXEC_H_

View File

@ -169,16 +169,13 @@ enum cmd_and_opt_values { aNull = 0,
oMarginalsNeeded,
oMaxCertDepth,
oLoadExtension,
oGnuPG,
oRFC1991,
oOpenPGP,
oPGP2,
oNoPGP2,
oPGP6,
oNoPGP6,
oPGP7,
oNoPGP7,
oPGP8,
oNoPGP8,
oCipherAlgo,
oDigestAlgo,
oCertDigestAlgo,
@ -458,16 +455,17 @@ static ARGPARSE_OPTS opts[] = {
{ oMaxCertDepth, "max-cert-depth", 1, "@" },
{ oTrustedKey, "trusted-key", 2, N_("|KEYID|ultimately trust this key")},
{ oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
{ oGnuPG, "gnupg", 0, "@"},
{ oGnuPG, "no-pgp2", 0, "@"},
{ oGnuPG, "no-pgp6", 0, "@"},
{ oGnuPG, "no-pgp7", 0, "@"},
{ oGnuPG, "no-pgp8", 0, "@"},
{ oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")},
{ oOpenPGP, "openpgp", 0, N_("set all packet, cipher and digest options to OpenPGP behavior")},
{ oPGP2, "pgp2", 0, N_("set all packet, cipher and digest options to PGP 2.x behavior")},
{ oNoPGP2, "no-pgp2", 0, "@"},
{ oPGP6, "pgp6", 0, "@"},
{ oNoPGP6, "no-pgp6", 0, "@"},
{ oPGP7, "pgp7", 0, "@"},
{ oNoPGP7, "no-pgp7", 0, "@"},
{ oPGP8, "pgp8", 0, "@"},
{ oNoPGP8, "no-pgp8", 0, "@"},
{ oS2KMode, "s2k-mode", 1, N_("|N|use passphrase mode N")},
{ oS2KDigest, "s2k-digest-algo",2,
N_("|NAME|use message digest algorithm NAME for passphrases")},
@ -1551,16 +1549,11 @@ main( int argc, char **argv )
opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
break;
case oPGP2: opt.compliance = CO_PGP2; break;
case oPGP6: opt.compliance = CO_PGP6; break;
case oPGP7: opt.compliance = CO_PGP7; break;
case oPGP8: opt.compliance = CO_PGP8; break;
case oNoPGP2:
case oNoPGP6:
case oNoPGP7:
case oNoPGP8:
opt.compliance = CO_GNUPG;
break;
case oPGP2: opt.compliance = CO_PGP2; break;
case oPGP6: opt.compliance = CO_PGP6; break;
case oPGP7: opt.compliance = CO_PGP7; break;
case oPGP8: opt.compliance = CO_PGP8; break;
case oGnuPG: opt.compliance = CO_GNUPG; break;
case oEmuMDEncodeBug: opt.emulate_bugs |= EMUBUG_MDENCODE; break;
case oCompressSigs: opt.compress_sigs = 1; break;
case oRunAsShmCP:

View File

@ -1,5 +1,6 @@
/* getkey.c - Get a key from the database
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
* 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -724,6 +725,27 @@ classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc )
}
static int
skip_disabled(void *dummy,u32 *keyid)
{
int rc,disabled=0;
PKT_public_key *pk=m_alloc_clear(sizeof(PKT_public_key));
rc = get_pubkey(pk, keyid);
if(rc)
{
log_error("error checking disabled status of %08lX: %s\n",
(ulong)keyid[1],g10_errstr(rc));
goto leave;
}
disabled=pk_is_disabled(pk);
leave:
free_public_key(pk);
return disabled;
}
/****************
* Try to get the pubkey by the userid. This function looks for the
* first pubkey certificate which has the given name in a user_id.
@ -774,7 +796,7 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
&& ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR16
&& ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR20
&& ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR)
ctx->items[n].skipfnc=is_disabled;
ctx->items[n].skipfnc=skip_disabled;
}
ctx->kr_handle = keydb_new (secmode);
@ -1296,12 +1318,12 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n);
if (p && n && (p[0] & 0x01))
uid->mdc_feature = 1;
/* and the keyserver modify flag */
uid->ks_modify = 1;
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n);
if (p && n && (p[0] & 0x80))
uid->ks_modify = 0;
}
static void
@ -1670,14 +1692,38 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
if ( k->pkt->pkttype == PKT_USER_ID &&
!k->pkt->pkt.user_id->attrib_data) {
PKT_user_id *uid = k->pkt->pkt.user_id;
if ( uid->is_primary && uid->created > uiddate ) {
uiddate = uid->created;
uidnode = k;
}
if ( !uid->is_primary && uid->created > uiddate2 ) {
uiddate2 = uid->created;
uidnode2 = k;
}
if (uid->is_primary)
{
if(uid->created > uiddate)
{
uiddate = uid->created;
uidnode = k;
}
else if(uid->created==uiddate && uidnode)
{
/* The dates are equal, so we need to do a
different (and arbitrary) comparison. This
should rarely, if ever, happen. It's good to
try and guarantee that two different GnuPG
users with two different keyrings at least pick
the same primary. */
if(cmp_user_ids(uid,uidnode->pkt->pkt.user_id)>0)
uidnode=k;
}
}
else
{
if(uid->created > uiddate2)
{
uiddate2 = uid->created;
uidnode2 = k;
}
else if(uid->created==uiddate2 && uidnode2)
{
if(cmp_user_ids(uid,uidnode2->pkt->pkt.user_id)>0)
uidnode2=k;
}
}
}
}
if ( uidnode ) {
@ -1692,23 +1738,43 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
}
}
else if( uidnode2 ) {
/* none is flagged primary - use the latest user ID we have */
/* none is flagged primary - use the latest user ID we have,
and disambiguate with the arbitrary packet comparison. */
uidnode2->pkt->pkt.user_id->is_primary = 1;
}
else
{
/* None of our uids were self-signed, so pick the first one to
be the primary. This is the best we can do here since
there are no self sigs to date the uids. */
/* None of our uids were self-signed, so pick the one that
sorts first to be the primary. This is the best we can do
here since there are no self sigs to date the uids. */
uidnode = NULL;
for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
k = k->next )
{
if(k->pkt->pkttype==PKT_USER_ID &&
!k->pkt->pkt.user_id->attrib_data)
if(k->pkt->pkttype==PKT_USER_ID
&& !k->pkt->pkt.user_id->attrib_data)
{
k->pkt->pkt.user_id->is_primary=1;
break;
if(!uidnode)
{
uidnode=k;
uidnode->pkt->pkt.user_id->is_primary=1;
continue;
}
else
{
if(cmp_user_ids(k->pkt->pkt.user_id,
uidnode->pkt->pkt.user_id)>0)
{
uidnode->pkt->pkt.user_id->is_primary=0;
uidnode=k;
uidnode->pkt->pkt.user_id->is_primary=1;
}
else
k->pkt->pkt.user_id->is_primary=0; /* just to be
safe */
}
}
}
}

View File

@ -234,7 +234,7 @@ check_signatures_trust( PKT_signature *sig )
*/
int
is_disabled(void *dummy,u32 *keyid)
cache_disabled_value(PKT_public_key *pk)
{
return 0;
}

View File

@ -765,7 +765,7 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
p = get_user_id( sk_keyid, &n );
tty_print_utf8_string( p, n );
m_free(p); p = NULL;
tty_printf("\"\n");
tty_printf("\" (%08lX)\n",(ulong)sk_keyid[1]);
if(selfsig)
{

View File

@ -358,23 +358,17 @@ print_capabilities (PKT_public_key *pk, PKT_secret_key *sk, KBNODE keyblock)
}
}
if ( keyblock ) { /* figure our the usable capabilities */
if ( keyblock ) { /* figure out the usable capabilities */
KBNODE k;
int enc=0, sign=0, cert=0, disabled=0;
for (k=keyblock; k; k = k->next ) {
if ( k->pkt->pkttype == PKT_PUBLIC_KEY
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
u32 kid[2];
pk = k->pkt->pkt.public_key;
if(k->pkt->pkttype==PKT_PUBLIC_KEY)
{
keyid_from_pk(pk,kid);
if(is_disabled(NULL,kid))
disabled=1;
}
if(pk->is_primary)
disabled=pk_is_disabled(pk);
if ( pk->is_valid && !pk->is_revoked && !pk->has_expired ) {
if ( pk->pubkey_usage & PUBKEY_USAGE_ENC )
@ -416,13 +410,13 @@ print_capabilities (PKT_public_key *pk, PKT_secret_key *sk, KBNODE keyblock)
putchar(':');
}
static void dump_attribs(const PKT_user_id *uid,
PKT_public_key *pk,PKT_secret_key *sk)
void
dump_attribs(const PKT_user_id *uid,PKT_public_key *pk,PKT_secret_key *sk)
{
int i;
if(!attrib_fp)
BUG();
return;
for(i=0;i<uid->numattribs;i++)
{
@ -498,8 +492,6 @@ list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) {
if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL)
dump_attribs(node->pkt->pkt.user_id,pk,sk);
/* don't list revoked or expired UIDS unless we are in
* verbose mode and signature listing has not been
* requested */
@ -508,6 +500,9 @@ list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
node->pkt->pkt.user_id->is_expired ))
continue;
if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL)
dump_attribs(node->pkt->pkt.user_id,pk,sk);
if( any )
printf("uid%*s", 29, "");

View File

@ -212,6 +212,8 @@ void list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque );
void print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode);
void show_policy_url(PKT_signature *sig,int indent);
void show_notation(PKT_signature *sig,int indent);
void dump_attribs(const PKT_user_id *uid,
PKT_public_key *pk,PKT_secret_key *sk);
void set_attrib_fd(int fd);
void print_seckey_info (PKT_secret_key *sk);
void print_pubkey_info (PKT_public_key *pk);

View File

@ -1313,8 +1313,6 @@ check_sig_and_print( CTX c, KBNODE node )
}
}
}
tstr = asctimestamp(sig->timestamp);
astr = pubkey_algo_to_string( sig->pubkey_algo );
@ -1431,9 +1429,14 @@ check_sig_and_print( CTX c, KBNODE node )
!un->pkt->pkt.user_id->attrib_data )
continue;
if(opt.show_photos && un->pkt->pkt.user_id->attrib_data)
show_photos(un->pkt->pkt.user_id->attribs,
un->pkt->pkt.user_id->numattribs,pk,NULL);
if(un->pkt->pkt.user_id->attrib_data)
{
dump_attribs(un->pkt->pkt.user_id,pk,NULL);
if(opt.show_photos)
show_photos(un->pkt->pkt.user_id->attribs,
un->pkt->pkt.user_id->numattribs,pk,NULL);
}
log_info( _(" aka \""));
print_utf8_string( log_stream(), un->pkt->pkt.user_id->name,
@ -1692,7 +1695,3 @@ proc_tree( CTX c, KBNODE node )
dump_kbnode (node);
}
}

View File

@ -211,6 +211,7 @@ typedef struct {
u32 main_keyid[2]; /* keyid of the primary key */
u32 keyid[2]; /* calculated by keyid_from_pk() */
byte is_primary;
byte is_disabled; /* 0 for unset, 1 for enabled, 2 for disabled. */
prefitem_t *prefs; /* list of preferences (may be NULL) */
int mdc_feature; /* mdc feature set */
PKT_user_id *user_id; /* if != NULL: found by that uid */
@ -223,6 +224,10 @@ typedef struct {
MPI pkey[PUBKEY_MAX_NPKEY];
} PKT_public_key;
/* Evaluates as true if the pk is disabled, and false if it isn't. If
there is no disable value cached, fill one in. */
#define pk_is_disabled(a) (((a)->is_disabled)?((a)->is_disabled==2):(cache_disabled_value((a))))
typedef struct {
u32 timestamp; /* key made */
u32 expiredate; /* expires at this date or 0 if not at all */

View File

@ -1,5 +1,6 @@
/* parse-packet.c - read packets
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
* 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -1546,6 +1547,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
pk->req_usage = 0;
pk->pubkey_usage = 0; /* not yet used */
pk->is_revoked = 0;
pk->is_disabled = 0;
pk->keyid[0] = 0;
pk->keyid[1] = 0;
}

View File

@ -1,3 +1,23 @@
/* photoid.h
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/* Photo ID functions */
#ifndef _PHOTOID_H_

View File

@ -580,6 +580,7 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
const char *code_text = NULL;
do {
code=-1;
m_free(description);
description = NULL;

View File

@ -950,23 +950,17 @@ clear_validity (PKT_public_key *pk)
/* Return true if key is disabled */
int
is_disabled(void *dummy,u32 *keyid)
cache_disabled_value(PKT_public_key *pk)
{
int rc;
TRUSTREC trec;
int disabled=0; /* default to not disabled */
PKT_public_key *pk=m_alloc_clear(sizeof(PKT_public_key));
int disabled=0;
init_trustdb ();
if(pk->is_disabled)
return (pk->is_disabled==2);
init_trustdb();
rc = get_pubkey(pk, keyid);
if(rc)
{
log_error("error checking disabled status of %08lX: %s\n",
(ulong)keyid[1],g10_errstr(rc));
goto leave;
}
rc = read_trust_record (pk, &trec);
if (rc && rc != -1)
{
@ -979,9 +973,15 @@ is_disabled(void *dummy,u32 *keyid)
if(trec.r.trust.ownertrust & TRUST_FLAG_DISABLED)
disabled=1;
/* Cache it for later so we don't need to look at the trustdb every
time */
if(disabled)
pk->is_disabled=2;
else
pk->is_disabled=1;
leave:
free_public_key(pk);
return disabled;
return disabled;
}
/*
@ -1085,7 +1085,12 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid)
}
if ( (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) )
validity |= TRUST_FLAG_DISABLED;
{
validity |= TRUST_FLAG_DISABLED;
pk->is_disabled=2;
}
else
pk->is_disabled=1;
leave:
/* set some flags direct from the key */

View File

@ -52,7 +52,7 @@ int string_to_trust_value (const char *str);
void revalidation_mark (void);
int trustdb_pending_check(void);
int is_disabled(void *dummy,u32 *keyid);
int cache_disabled_value(PKT_public_key *pk);
unsigned int get_validity (PKT_public_key *pk, PKT_user_id *uid);
int get_validity_info (PKT_public_key *pk, PKT_user_id *uid);