1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-23 10:29:58 +01:00

Some minor fixes for revocation keys: print a warning if a key is imported

that has been revoked by designated revoker, but the designated revoker is
not present to verify the revocation (whew!).  This applies to all ways to
get a key into the system: --import --recv-keys, and --search-keys.  If
auto-key-retrieve is set, try and retrieve the revocation key.

Also, auto-key-retrieve is now a keyserver-option.
This commit is contained in:
David Shaw 2002-03-07 19:44:57 +00:00
parent c027e8610b
commit f8f52d8ffe
9 changed files with 162 additions and 30 deletions

View File

@ -1,3 +1,27 @@
2002-03-07 David Shaw <dshaw@jabberwocky.com>
* g10.c (main): make a few more strings translatable.
* options.h, options.skel, g10.c (main), gpgv.c, mainproc.c
(check_sig_and_print), keyserver.c (parse_keyserver_options):
--auto-key-retrieve should really be a keyserver-option variable.
* import.c (revocation_present): new function to print a warning
if a key is imported that has been revoked by designated revoker,
but the designated revoker is not present to verify the
revocation. If keyserver-options auto-key-retrieve is set, try
and fetch the designated revoker from the keyserver.
* import.c (import_one): call revocation_present after importing a
new key. Note that this applies to --import, --recv-keys, and
--search-keys.
* keyserver-internal.h, keyserver.c (keyserver_import_fprint):
import via fingerprint (for revocation keys).
* keyserver.c (keyserver_import_keyid): much simpler
implementation now that we're using KEYDB_SEARCH_DESC internally.
2002-03-04 David Shaw <dshaw@jabberwocky.com> 2002-03-04 David Shaw <dshaw@jabberwocky.com>
* revoke.c (gen_revoke): do not prompt for revocation reason for * revoke.c (gen_revoke): do not prompt for revocation reason for

View File

@ -1227,8 +1227,10 @@ main( int argc, char **argv )
case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break; case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
case oHonorHttpProxy: case oHonorHttpProxy:
opt.honor_http_proxy = 1; opt.honor_http_proxy = 1;
log_info("WARNING: --honor-http-proxy is deprecated.\n"); log_info(_("WARNING: %s is a deprecated option.\n"),
log_info("please use \"--keyserver-options honor-http-proxy\" instead\n"); "--honor-http-proxy");
log_info(_("please use \"--keyserver-options %s\" instead\n"),
"honor-http-proxy");
break; break;
case oFastListMode: opt.fast_list_mode = 1; break; case oFastListMode: opt.fast_list_mode = 1; break;
case oFixedListMode: opt.fixed_list_mode = 1; break; case oFixedListMode: opt.fixed_list_mode = 1; break;
@ -1237,8 +1239,17 @@ main( int argc, char **argv )
case oIgnoreValidFrom: opt.ignore_valid_from = 1; break; case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
case oIgnoreCrcError: opt.ignore_crc_error = 1; break; case oIgnoreCrcError: opt.ignore_crc_error = 1; break;
case oNoRandomSeedFile: use_random_seed = 0; break; case oNoRandomSeedFile: use_random_seed = 0; break;
case oAutoKeyRetrieve: opt.auto_key_retrieve = 1; break; case oAutoKeyRetrieve:
case oNoAutoKeyRetrieve: opt.auto_key_retrieve = 0; break; case oNoAutoKeyRetrieve:
opt.keyserver_options.auto_key_retrieve=
(pargs.r_opt==oAutoKeyRetrieve);
log_info(_("WARNING: %s is a deprecated option.\n"),
pargs.r_opt==oAutoKeyRetrieve?
"--auto-key-retrieve":"--no-auto-key-retrieve");
log_info(_("please use \"--keyserver-options %s\" instead\n"),
pargs.r_opt==oAutoKeyRetrieve?
"auto-key-retrieve":"no-auto-key-retrieve");
break;
case oShowSessionKey: opt.show_session_key = 1; break; case oShowSessionKey: opt.show_session_key = 1; break;
case oOverrideSessionKey: case oOverrideSessionKey:
opt.override_session_key = pargs.r.ret_str; opt.override_session_key = pargs.r.ret_str;

View File

@ -147,7 +147,7 @@ main( int argc, char **argv )
i18n_init(); i18n_init();
opt.command_fd = -1; /* no command fd */ opt.command_fd = -1; /* no command fd */
opt.pgp2_workarounds = 1; opt.pgp2_workarounds = 1;
opt.auto_key_retrieve = 1; opt.keyserver_options.auto_key_retrieve = 1;
opt.always_trust = 1; opt.always_trust = 1;
opt.batch = 1; opt.batch = 1;

View File

@ -35,7 +35,7 @@
#include "main.h" #include "main.h"
#include "i18n.h" #include "i18n.h"
#include "status.h" #include "status.h"
#include "keyserver-internal.h"
struct stats_s { struct stats_s {
ulong count; ulong count;
@ -57,6 +57,7 @@ struct stats_s {
static int import( IOBUF inp, int fast, const char* fname, static int import( IOBUF inp, int fast, const char* fname,
struct stats_s *stats ); struct stats_s *stats );
static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root ); static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
static void revocation_present(KBNODE keyblock);
static void remove_bad_stuff (KBNODE keyblock); static void remove_bad_stuff (KBNODE keyblock);
static int import_one( const char *fname, KBNODE keyblock, int fast, static int import_one( const char *fname, KBNODE keyblock, int fast,
struct stats_s *stats); struct stats_s *stats);
@ -597,6 +598,9 @@ import_one( const char *fname, KBNODE keyblock, int fast,
leave: leave:
release_kbnode( keyblock_orig ); release_kbnode( keyblock_orig );
free_public_key( pk_orig ); free_public_key( pk_orig );
revocation_present(keyblock);
return rc; return rc;
} }
@ -1073,7 +1077,84 @@ collapse_uids( KBNODE *keyblock )
return 1; return 1;
} }
/* Check for a 0x20 revocation from a revocation key that is not
present. This gets called without the benefit of merge_xxxx so you
can't rely on pk->revkey and friends. */
static void
revocation_present(KBNODE keyblock)
{
KBNODE onode,inode;
PKT_public_key *pk=keyblock->pkt->pkt.public_key;
for(onode=keyblock->next;onode;onode=onode->next)
{
/* If we reach user IDs, we're done. */
if(onode->pkt->pkttype==PKT_USER_ID)
break;
if(onode->pkt->pkttype==PKT_SIGNATURE &&
onode->pkt->pkt.signature->sig_class==0x1F &&
onode->pkt->pkt.signature->revkey)
{
int idx;
PKT_signature *sig=onode->pkt->pkt.signature;
for(idx=0;idx<sig->numrevkeys;idx++)
{
u32 keyid[2];
keyid_from_fingerprint(sig->revkey[idx]->fpr,
MAX_FINGERPRINT_LEN,keyid);
for(inode=keyblock->next;inode;inode=inode->next)
{
/* If we reach user IDs, we're done. */
if(inode->pkt->pkttype==PKT_USER_ID)
break;
if(inode->pkt->pkttype==PKT_SIGNATURE &&
inode->pkt->pkt.signature->sig_class==0x20 &&
inode->pkt->pkt.signature->keyid[0]==keyid[0] &&
inode->pkt->pkt.signature->keyid[1]==keyid[1])
{
/* Okay, we have a revocation key, and a
revocation issued by it. Do we have the key
itself? */
int rc;
rc=get_pubkey_byfprint(NULL,sig->revkey[idx]->fpr,
MAX_FINGERPRINT_LEN);
if(rc==G10ERR_NO_PUBKEY || rc==G10ERR_UNU_PUBKEY)
{
/* No, so try and get it */
if(opt.keyserver_scheme &&
opt.keyserver_options.auto_key_retrieve)
{
log_info(_("Warning: key %08lX may be revoked: "
"fetching revocation key %08lX\n"),
(ulong)keyid_from_pk(pk,NULL),
(ulong)keyid[1]);
keyserver_import_fprint(sig->revkey[idx]->fpr,
MAX_FINGERPRINT_LEN);
/* Do we have it now? */
rc=get_pubkey_byfprint(NULL,
sig->revkey[idx]->fpr,
MAX_FINGERPRINT_LEN);
}
if(rc==G10ERR_NO_PUBKEY || rc==G10ERR_UNU_PUBKEY)
log_info(_("Warning: key %08lX may be revoked: "
"revocation key %08lX not present.\n"),
(ulong)keyid_from_pk(pk,NULL),
(ulong)keyid[1]);
}
}
}
}
}
}
}
/**************** /****************
* compare and merge the blocks * compare and merge the blocks
@ -1440,4 +1521,3 @@ append_key( KBNODE keyblock, KBNODE node, int *n_sigs,
return 0; return 0;
} }

View File

@ -12,6 +12,7 @@ void parse_keyserver_options(char *options);
int parse_keyserver_uri(char *uri); int parse_keyserver_uri(char *uri);
int keyserver_export(STRLIST users); int keyserver_export(STRLIST users);
int keyserver_import(STRLIST users); int keyserver_import(STRLIST users);
int keyserver_import_fprint(const byte *fprint,size_t fprint_len);
int keyserver_import_keyid(u32 *keyid); int keyserver_import_keyid(u32 *keyid);
int keyserver_refresh(STRLIST users); int keyserver_refresh(STRLIST users);
int keyserver_search(STRLIST tokens); int keyserver_search(STRLIST tokens);

View File

@ -90,6 +90,10 @@ parse_keyserver_options(char *options)
opt.keyserver_options.refresh_add_fake_v3_keyids=1; opt.keyserver_options.refresh_add_fake_v3_keyids=1;
else if(strcasecmp(tok,"no-refresh-add-fake-v3-keyids")==0) else if(strcasecmp(tok,"no-refresh-add-fake-v3-keyids")==0)
opt.keyserver_options.refresh_add_fake_v3_keyids=0; opt.keyserver_options.refresh_add_fake_v3_keyids=0;
else if(strcasecmp(tok,"auto-key-retrieve")==0)
opt.keyserver_options.refresh_add_fake_v3_keyids=1;
else if(strcasecmp(tok,"no-auto-key-retrieve")==0)
opt.keyserver_options.refresh_add_fake_v3_keyids=0;
else if(strlen(tok)>0) else if(strlen(tok)>0)
add_to_strlist(&opt.keyserver_options.other,tok); add_to_strlist(&opt.keyserver_options.other,tok);
@ -676,22 +680,37 @@ keyserver_import(STRLIST users)
return rc; return rc;
} }
int
keyserver_import_fprint(const byte *fprint,size_t fprint_len)
{
KEYDB_SEARCH_DESC desc;
memset(&desc,0,sizeof(desc));
if(fprint_len==16)
desc.mode=KEYDB_SEARCH_MODE_FPR16;
else if(fprint_len==20)
desc.mode=KEYDB_SEARCH_MODE_FPR20;
else
return -1;
memcpy(desc.u.fpr,fprint,fprint_len);
return keyserver_work(GET,NULL,&desc,1);
}
int int
keyserver_import_keyid(u32 *keyid) keyserver_import_keyid(u32 *keyid)
{ {
STRLIST sl=NULL; KEYDB_SEARCH_DESC desc;
char key[17];
int ret;
sprintf(key,"%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]); memset(&desc,0,sizeof(desc));
add_to_strlist(&sl,key); desc.mode=KEYDB_SEARCH_MODE_LONG_KID;
desc.u.kid[0]=keyid[0];
desc.u.kid[1]=keyid[1];
ret=keyserver_import(sl); return keyserver_work(GET,NULL,&desc,1);
free_strlist(sl);
return ret;
} }
/* code mostly stolen from do_export_stream */ /* code mostly stolen from do_export_stream */

View File

@ -1258,7 +1258,7 @@ check_sig_and_print( CTX c, KBNODE node )
(int)strlen(tstr), tstr, astr? astr: "?", (ulong)sig->keyid[1] ); (int)strlen(tstr), tstr, astr? astr: "?", (ulong)sig->keyid[1] );
rc = do_check_sig(c, node, NULL ); rc = do_check_sig(c, node, NULL );
if( rc == G10ERR_NO_PUBKEY && opt.keyserver_scheme && opt.auto_key_retrieve) { if( rc == G10ERR_NO_PUBKEY && opt.keyserver_scheme && opt.keyserver_options.auto_key_retrieve) {
if( keyserver_import_keyid ( sig->keyid )==0 ) if( keyserver_import_keyid ( sig->keyid )==0 )
rc = do_check_sig(c, node, NULL ); rc = do_check_sig(c, node, NULL );
} }

View File

@ -109,6 +109,7 @@ struct {
int use_temp_files:1; int use_temp_files:1;
int keep_temp_files:1; int keep_temp_files:1;
int refresh_add_fake_v3_keyids:1; int refresh_add_fake_v3_keyids:1;
int auto_key_retrieve:1;
STRLIST other; STRLIST other;
} keyserver_options; } keyserver_options;
int exec_disable; int exec_disable;
@ -133,7 +134,6 @@ struct {
int ignore_valid_from; int ignore_valid_from;
int ignore_crc_error; int ignore_crc_error;
int command_fd; int command_fd;
int auto_key_retrieve;
const char *override_session_key; const char *override_session_key;
int show_session_key; int show_session_key;
int use_agent; int use_agent;

View File

@ -131,25 +131,25 @@ lock-once
# on the keyserver. # on the keyserver.
# #
# verbose = show more information as the keys are fetched. # verbose = show more information as the keys are fetched.
# Can be included more than once to increase the amount # Can be used more than once to increase the amount
# of information shown. # of information shown.
# #
# use-temp-files = use temporary files instead of a pipe to talk to the # use-temp-files = use temporary files instead of a pipe to talk to the
# keyserver. Some platforms (Win32 for one) always # keyserver. Some platforms (Win32 for one) always
# have this on. # have this on.
# #
# keep-temp-files = don't delete the temporary files after using them # keep-temp-files = do not delete temporary files after using them
# (really only useful for debugging) # (really only useful for debugging)
# #
# honor-http-proxy = if the keyserver uses http, honor the http_proxy # honor-http-proxy = if the keyserver uses http, honor the http_proxy
# environment variable # environment variable
#
# auto-key-retrieve = automatically fetch keys as needed from the
# keyserver when verifying signatures or when importing
# keys that have been revoked by a revocation key that
# is not present on the keyring.
#keyserver-options include-disabled include-revoked #keyserver-options auto-key-retrieve include-disabled include-revoked
# Uncomment this line to automatically fetch a key from a keyserver
# (which must be set - see above) when verifying signatures.
#auto-key-retrieve
# Uncomment this line to display photo user IDs in key listings # Uncomment this line to display photo user IDs in key listings
#show-photos #show-photos
@ -201,6 +201,3 @@ lock-once
# --gpg-agent-info=<path>:<pid>:1 # --gpg-agent-info=<path>:<pid>:1
# #
# may be used to override it. # may be used to override it.
#