gpg: Disallow the use of v3 keys.

* g10/gpg.c: Add options --allow-v3-keys and --no-allow-v3-keys.
(main): Enable --allow-v3-keys in --pgp2 mode.
* g10/options.h (opt): Add field allow_v3_keys.
* g10/import.c (delete_v3_subkeys): New.
(import_one): Skip v3 keys and delete v3 subkeys.
(import_print_stats): Print stats on v3 keys and subkeys.
* g10/getkey.c (finish_lookup): Skip v3 keys.
--

This is a first take on disabling v3 keys.  We may need to add some
tweaks to make decryption using an existing v3 key easier.  There is
no need to disallow decryption.

Thanks to Georgi Guninski to put some pressure on us to finally do
what PGP 2 folks will probably don’t like.  See the discussion on
gnupg-devel starting 2012-06-22.
This commit is contained in:
Werner Koch 2012-06-25 16:27:04 +02:00
parent ca8eec8e28
commit 2b32eb15aa
7 changed files with 108 additions and 5 deletions

4
NEWS
View File

@ -11,6 +11,10 @@ Noteworthy changes in version 2.1.0beta4 (unreleased)
* The hash algorithm is now printed for sig records in key listings.
* GPG does not anymore allow the use of the long deprecated v3 keys
(PGP 2 keys). The new option --allow-v3-keys can be used to
exceptionally allow them.
Noteworthy changes in version 2.1.0beta3 (2011-12-20)
-----------------------------------------------------

View File

@ -459,7 +459,7 @@ more arguments in future versions.
IMPORT_RES <count> <no_user_id> <imported> <imported_rsa> <unchanged>
<n_uids> <n_subk> <n_sigs> <n_revoc> <sec_read> <sec_imported>
<sec_dups> <skipped_new_keys> <not_imported>
<sec_dups> <skipped_new_keys> <not_imported> <n_v3> <n_v3_subkeys>
Final statistics on import process (this is one long line)
FILE_START <what> <filename>

View File

@ -2637,6 +2637,20 @@ Disable all checks on the form of the user ID while generating a new
one. This option should only be used in very special environments as
it does not ensure the de-facto standard format of user IDs.
@ifset gpgtwoone
@item --allow-v3-keys
@itemx --no-allow-v3-keys
@opindex allow-v3-keys
Allow the use of deprecated v3 keys with @command{gpg}. The default
is not to allow their use.
Since version 2.1 GnuPG does not anymore allow the import or use of v3
keys. Those keys have been generated in the past by PGP 2 and exhibit
a couple of flaws. For example they rely on the broken MD5 algorithm.
OpenPGP has long deprecated their use (cf. RFC-4880, section 5.5.2).
This option may be used to exceptionally allow their use.
@end ifset
@item --ignore-time-conflict
@opindex ignore-time-conflict
GnuPG normally checks that the timestamps associated with keys and

View File

@ -2318,6 +2318,12 @@ finish_lookup (GETKEY_CTX ctx)
if (DBG_CACHE)
log_debug ("\tchecking subkey %08lX\n",
(ulong) keyid_from_pk (pk, NULL));
if (pk->version <= 3 && !opt.allow_v3_keys)
{
if (DBG_CACHE)
log_debug ("\tv3 subkey not allowed\n");
continue;
}
if (!pk->flags.valid)
{
if (DBG_CACHE)
@ -2373,7 +2379,12 @@ finish_lookup (GETKEY_CTX ctx)
if (DBG_CACHE && !foundk && !req_prim)
log_debug ("\tno suitable subkeys found - trying primary\n");
pk = keyblock->pkt->pkt.public_key;
if (!pk->flags.valid)
if (pk->version <= 3 && !opt.allow_v3_keys)
{
if (DBG_CACHE)
log_debug ("\tv3 primary key not allowed\n");
}
else if (!pk->flags.valid)
{
if (DBG_CACHE)
log_debug ("\tprimary key not valid\n");

View File

@ -305,6 +305,8 @@ enum cmd_and_opt_values
oNoAllowNonSelfsignedUID,
oAllowFreeformUID,
oNoAllowFreeformUID,
oAllowV3Keys,
oNoAllowV3Keys,
oAllowSecretKeyImport,
oEnableSpecialFilenames,
oNoLiteral,
@ -682,6 +684,9 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oNoAllowNonSelfsignedUID, "no-allow-non-selfsigned-uid", "@"),
ARGPARSE_s_n (oAllowFreeformUID, "allow-freeform-uid", "@"),
ARGPARSE_s_n (oNoAllowFreeformUID, "no-allow-freeform-uid", "@"),
ARGPARSE_s_n (oAllowFreeformUID, "allow-freeform-uid", "@"),
ARGPARSE_s_n (oAllowV3Keys, "allow-v3-keys", "@"),
ARGPARSE_s_n (oNoAllowV3Keys, "no-allow-v3-keys", "@"),
ARGPARSE_s_n (oNoLiteral, "no-literal", "@"),
ARGPARSE_p_u (oSetFilesize, "set-filesize", "@"),
ARGPARSE_s_n (oHonorHttpProxy, "honor-http-proxy", "@"),
@ -2805,6 +2810,8 @@ main (int argc, char **argv)
case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break;
case oAllowFreeformUID: opt.allow_freeform_uid = 1; break;
case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break;
case oAllowV3Keys: opt.allow_v3_keys = 1; break;
case oNoAllowV3Keys: opt.allow_v3_keys = 0; break;
case oNoLiteral: opt.no_literal = 1; break;
case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
case oHonorHttpProxy:
@ -3184,6 +3191,7 @@ main (int argc, char **argv)
xfree(s2k_digest_string);
s2k_digest_string = xstrdup("md5");
opt.compress_algo = COMPRESS_ALGO_ZIP;
opt.allow_v3_keys = 1;
}
}
else if(PGP6)

View File

@ -57,6 +57,8 @@ struct stats_s {
ulong not_imported;
ulong n_sigs_cleaned;
ulong n_uids_cleaned;
ulong skipped_v3_keys;
ulong skipped_v3_subkeys;
};
@ -77,6 +79,7 @@ static int chk_self_sigs( const char *fname, KBNODE keyblock,
PKT_public_key *pk, u32 *keyid, int *non_self );
static int delete_inv_parts( const char *fname, KBNODE keyblock,
u32 *keyid, unsigned int options );
static int delete_v3_subkeys (kbnode_t keyblock);
static int merge_blocks( const char *fname, KBNODE keyblock_orig,
KBNODE keyblock, u32 *keyid,
int *n_uids, int *n_sigs, int *n_subk );
@ -330,6 +333,9 @@ import_print_stats (void *hd)
if( stats->skipped_new_keys )
log_info(_(" skipped new keys: %lu\n"),
stats->skipped_new_keys );
if( stats->skipped_v3_keys )
log_info(_(" skipped v3 keys: %lu\n"),
stats->skipped_v3_keys);
if( stats->no_user_id )
log_info(_(" w/o user IDs: %lu\n"), stats->no_user_id );
if( stats->imported || stats->imported_rsa ) {
@ -344,6 +350,9 @@ import_print_stats (void *hd)
log_info(_(" new user IDs: %lu\n"), stats->n_uids );
if( stats->n_subk )
log_info(_(" new subkeys: %lu\n"), stats->n_subk );
if( stats->skipped_v3_subkeys)
log_info(_(" skipped v3 subkeys: %lu\n"),
stats->skipped_v3_subkeys);
if( stats->n_sigs )
log_info(_(" new signatures: %lu\n"), stats->n_sigs );
if( stats->n_revoc )
@ -363,8 +372,10 @@ import_print_stats (void *hd)
}
if( is_status_enabled() ) {
char buf[14*20];
sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
char buf[16*20];
snprintf (buf, sizeof buf,
"%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu"
" %lu %lu",
stats->count,
stats->no_user_id,
stats->imported,
@ -378,7 +389,9 @@ import_print_stats (void *hd)
stats->secret_imported,
stats->secret_dups,
stats->skipped_new_keys,
stats->not_imported );
stats->not_imported,
stats->skipped_v3_keys,
stats->skipped_v3_subkeys);
write_status_text( STATUS_IMPORT_RES, buf );
}
}
@ -771,6 +784,7 @@ import_one (ctrl_t ctrl,
int mod_key = 0;
int same_key = 0;
int non_self = 0;
int count;
/* get the key and print some info about it */
node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
@ -795,6 +809,18 @@ import_one (ctrl_t ctrl,
log_printf ("\n");
}
/* We don't allow to import v3 keys unless the --allow-v3-keys
option is active. Note that this checks only the primary key.
v3 subkeys will be removed later. */
if (pk->version <= 3 && !opt.allow_v3_keys)
{
if (opt.verbose)
log_info (_("key %s: v3 keys are not allowed - skipped\n"),
keystr (keyid));
stats->skipped_new_keys++;
stats->skipped_v3_keys++;
return 0;
}
if( !uidnode )
{
@ -855,6 +881,14 @@ import_one (ctrl_t ctrl,
return 0;
}
if (!opt.allow_v3_keys && (count = delete_v3_subkeys (keyblock)))
{
stats->skipped_v3_subkeys += count;
if (!opt.quiet)
log_info (_("key %s: removed v3 subkeys: %d\n"),
keystr (keyid), count);
}
/* do we have this key already in one of our pubrings ? */
pk_orig = xmalloc_clear( sizeof *pk_orig );
rc = get_pubkey_fast ( pk_orig, keyid );
@ -2094,6 +2128,37 @@ delete_inv_parts( const char *fname, KBNODE keyblock,
}
/* Remove all v3 public subkeys from KEYBLOCK. Returns the number of
* removed subkeys. */
static int
delete_v3_subkeys (kbnode_t keyblock)
{
kbnode_t node;
int count = 0;
for (node = keyblock->next; node; node = node->next )
{
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
&& node->pkt->pkt.public_key->version == 3)
{
delete_kbnode (node);
while (node->next && node->next->pkt->pkttype == PKT_SIGNATURE)
{
delete_kbnode (node->next);
node = node->next;
}
count++;
}
}
/* Because KEYBLOCK is the primary public key, it is never marked
* for deletion and thus commit_keyblock won't change KEYBLOCK. */
if (count)
commit_kbnode (&keyblock);
return count;
}
/****************
* It may happen that the imported keyblock has duplicated user IDs.
* We check this here and collapse those user IDs together with their

View File

@ -170,6 +170,7 @@ struct
strlist_t sig_subpackets;
int allow_non_selfsigned_uid;
int allow_freeform_uid;
int allow_v3_keys; /* Allow the use of v3 keys. */
int no_literal;
ulong set_filesize;
int fast_list_mode;