aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/getkey.c13
-rw-r--r--g10/gpg.c8
-rw-r--r--g10/import.c71
-rw-r--r--g10/options.h1
4 files changed, 89 insertions, 4 deletions
diff --git a/g10/getkey.c b/g10/getkey.c
index 929427302..348755df1 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -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");
diff --git a/g10/gpg.c b/g10/gpg.c
index c8dbbfe83..74f34f6b4 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -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)
diff --git a/g10/import.c b/g10/import.c
index bfe02eb16..06a92af02 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -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
diff --git a/g10/options.h b/g10/options.h
index e67d0ce04..3a9f43c36 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -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;