diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/getkey.c | 13 | ||||
-rw-r--r-- | g10/gpg.c | 8 | ||||
-rw-r--r-- | g10/import.c | 71 | ||||
-rw-r--r-- | g10/options.h | 1 |
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"); @@ -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; |