[Pkg-gnupg-commit] [gnupg2] 28/205: gpg: Add hidden key-edit subcommand "change-usage".
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Wed May 11 08:38:11 UTC 2016
This is an automated email from the git hooks/post-receive script.
dkg pushed a commit to branch experimental
in repository gnupg2.
commit 9b28b82e7c40d1eacc446d5932cd613c56378ed8
Author: Werner Koch <wk at gnupg.org>
Date: Sun Feb 14 15:50:12 2016 +0100
gpg: Add hidden key-edit subcommand "change-usage".
* g10/keyedit.c (cmdCHANGEUSAGE): New.
(cmds): Add command "change-usage".
(keyedit_menu): Handle that command.
(menu_changeusage): New.
* g10/keygen.c (keygen_add_key_flags): New.
(ask_key_flags): Add optional arg current.
--
Signed-off-by: Werner Koch <wk at gnupg.org>
---
g10/keyedit.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
g10/keygen.c | 36 +++++++++++++-----
g10/main.h | 2 +
3 files changed, 146 insertions(+), 11 deletions(-)
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 30f52a4..19ddf29 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -70,6 +70,7 @@ static int menu_clean (KBNODE keyblock, int self_only);
static void menu_delkey (KBNODE pub_keyblock);
static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive);
static int menu_expire (KBNODE pub_keyblock);
+static int menu_changeusage (kbnode_t keyblock);
static int menu_backsign (KBNODE pub_keyblock);
static int menu_set_primary_uid (KBNODE pub_keyblock);
static int menu_set_preferences (KBNODE pub_keyblock);
@@ -1362,7 +1363,7 @@ enum cmdids
cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
- cmdEXPIRE, cmdBACKSIGN,
+ cmdEXPIRE, cmdCHANGEUSAGE, cmdBACKSIGN,
#ifndef NO_TRUST_MODELS
cmdENABLEKEY, cmdDISABLEKEY,
#endif /*!NO_TRUST_MODELS*/
@@ -1393,6 +1394,7 @@ static struct
{ "key", cmdSELKEY, 0, N_("select subkey N")},
{ "check", cmdCHECK, 0, N_("check signatures")},
{ "c", cmdCHECK, 0, NULL},
+ { "change-usage", cmdCHANGEUSAGE, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
{ "cross-certify", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
{ "backsign", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
{ "sign", cmdSIGN, KEYEDIT_NOT_SK | KEYEDIT_TAIL_MATCH,
@@ -2122,6 +2124,15 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
}
break;
+ case cmdCHANGEUSAGE:
+ if (menu_changeusage (keyblock))
+ {
+ merge_keys_and_selfsig (keyblock);
+ modified = 1;
+ redisplay = 1;
+ }
+ break;
+
case cmdBACKSIGN:
if (menu_backsign (keyblock))
{
@@ -4110,6 +4121,112 @@ menu_expire (KBNODE pub_keyblock)
}
+/* Change the capability of a selected key. This command should only
+ * be used to rectify badly created keys and as such is not suggested
+ * for general use. */
+static int
+menu_changeusage (kbnode_t keyblock)
+{
+ int n1, rc;
+ int mainkey = 0;
+ PKT_public_key *main_pk, *sub_pk;
+ PKT_user_id *uid;
+ kbnode_t node;
+ u32 keyid[2];
+
+ n1 = count_selected_keys (keyblock);
+ if (n1 > 1)
+ {
+ tty_printf (_("You must select exactly one key.\n"));
+ return 0;
+ }
+ else if (n1)
+ tty_printf ("Changing usage of a subkey.\n");
+ else
+ {
+ tty_printf ("Changing usage of the primary key.\n");
+ mainkey = 1;
+ }
+
+ /* Now we can actually change the self-signature(s) */
+ main_pk = sub_pk = NULL;
+ uid = NULL;
+ for (node = keyblock; node; node = node->next)
+ {
+ if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+ {
+ main_pk = node->pkt->pkt.public_key;
+ keyid_from_pk (main_pk, keyid);
+ }
+ else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+ {
+ if (node->flag & NODFLG_SELKEY)
+ sub_pk = node->pkt->pkt.public_key;
+ else
+ sub_pk = NULL;
+ }
+ else if (node->pkt->pkttype == PKT_USER_ID)
+ uid = node->pkt->pkt.user_id;
+ else if (main_pk && node->pkt->pkttype == PKT_SIGNATURE
+ && (mainkey || sub_pk))
+ {
+ PKT_signature *sig = node->pkt->pkt.signature;
+ if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
+ && ((mainkey && uid
+ && uid->created && (sig->sig_class & ~3) == 0x10)
+ || (!mainkey && sig->sig_class == 0x18))
+ && sig->flags.chosen_selfsig)
+ {
+ /* This is the self-signature which is to be replaced. */
+ PKT_signature *newsig;
+ PACKET *newpkt;
+
+ if ((mainkey && main_pk->version < 4)
+ || (!mainkey && sub_pk->version < 4))
+ {
+ log_info ("You can't change the capabilities of a v3 key\n");
+ return 0;
+ }
+
+ if (mainkey)
+ main_pk->pubkey_usage = ask_key_flags (main_pk->pubkey_algo, 0,
+ main_pk->pubkey_usage);
+ else
+ sub_pk->pubkey_usage = ask_key_flags (sub_pk->pubkey_algo, 1,
+ sub_pk->pubkey_usage);
+
+ if (mainkey)
+ rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL,
+ main_pk, keygen_add_key_flags,
+ main_pk);
+ else
+ rc =
+ update_keysig_packet (&newsig, sig, main_pk, NULL, sub_pk,
+ main_pk, keygen_add_key_flags, sub_pk);
+ if (rc)
+ {
+ log_error ("make_keysig_packet failed: %s\n",
+ gpg_strerror (rc));
+ return 0;
+ }
+
+ /* Replace the packet. */
+ newpkt = xmalloc_clear (sizeof *newpkt);
+ newpkt->pkttype = PKT_SIGNATURE;
+ newpkt->pkt.signature = newsig;
+ free_packet (node->pkt);
+ xfree (node->pkt);
+ node->pkt = newpkt;
+ sub_pk = NULL;
+ break;
+ }
+ }
+ }
+
+ return 1;
+}
+
+
static int
menu_backsign (KBNODE pub_keyblock)
{
diff --git a/g10/keygen.c b/g10/keygen.c
index 0f7a6a0..7b5a35b 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -252,6 +252,18 @@ keygen_add_key_expire (PKT_signature *sig, void *opaque)
}
+/* Add the key usage (i.e. key flags) in SIG from the public keys
+ * pubkey_usage field. OPAQUE has the public key. */
+int
+keygen_add_key_flags (PKT_signature *sig, void *opaque)
+{
+ PKT_public_key *pk = opaque;
+
+ do_add_key_flags (sig, pk->pubkey_usage);
+ return 0;
+}
+
+
static int
keygen_add_key_flags_and_expire (PKT_signature *sig, void *opaque)
{
@@ -1646,9 +1658,10 @@ print_key_flags(int flags)
}
-/* Returns the key flags */
-static unsigned int
-ask_key_flags(int algo,int subkey)
+/* Ask for the key flags and return them. CURRENT gives the curren
+ * usage which should normally be given as 0. */
+unsigned int
+ask_key_flags (int algo, int subkey, unsigned int current)
{
/* TRANSLATORS: Please use only plain ASCII characters for the
translation. If this is not possible use single digits. The
@@ -1663,7 +1676,6 @@ ask_key_flags(int algo,int subkey)
const char *togglers=_("SsEeAaQq");
char *answer=NULL;
const char *s;
- unsigned int current=0;
unsigned int possible=openpgp_pk_algo_usage(algo);
if ( strlen(togglers) != 8 )
@@ -1678,8 +1690,12 @@ ask_key_flags(int algo,int subkey)
possible&=~PUBKEY_USAGE_CERT;
/* Preload the current set with the possible set, minus
- authentication, since nobody really uses auth yet. */
- current=possible&~PUBKEY_USAGE_AUTH;
+ authentication if CURRENT has been given as 0. If CURRENT has
+ been has non-zero we mask with all possible usages. */
+ if (current)
+ current &= possible;
+ else
+ current = (possible&~PUBKEY_USAGE_AUTH);
for(;;)
{
@@ -1922,13 +1938,13 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
else if ((algo == 7 || !strcmp (answer, "dsa/*")) && opt.expert)
{
algo = PUBKEY_ALGO_DSA;
- *r_usage = ask_key_flags (algo, addmode);
+ *r_usage = ask_key_flags (algo, addmode, 0);
break;
}
else if ((algo == 8 || !strcmp (answer, "rsa/*")) && opt.expert)
{
algo = PUBKEY_ALGO_RSA;
- *r_usage = ask_key_flags (algo, addmode);
+ *r_usage = ask_key_flags (algo, addmode, 0);
break;
}
else if ((algo == 9 || !strcmp (answer, "ecc+ecc"))
@@ -1947,7 +1963,7 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
else if ((algo == 11 || !strcmp (answer, "ecc/*")) && opt.expert)
{
algo = PUBKEY_ALGO_ECDSA;
- *r_usage = ask_key_flags (algo, addmode);
+ *r_usage = ask_key_flags (algo, addmode, 0);
break;
}
else if ((algo == 12 || !strcmp (answer, "ecc/e"))
@@ -1985,7 +2001,7 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
xfree (keygrip);
keygrip = answer;
answer = NULL;
- *r_usage = ask_key_flags (algo, addmode);
+ *r_usage = ask_key_flags (algo, addmode, 0);
break;
}
else
diff --git a/g10/main.h b/g10/main.h
index ec24426..863afa9 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -280,12 +280,14 @@ void show_basic_key_info (KBNODE keyblock);
u32 parse_expire_string(const char *string);
u32 ask_expire_interval(int object,const char *def_expire);
u32 ask_expiredate(void);
+unsigned int ask_key_flags (int algo, int subkey, unsigned int current);
void quick_generate_keypair (ctrl_t ctrl, const char *uid);
void generate_keypair (ctrl_t ctrl, int full, const char *fname,
const char *card_serialno, int card_backup_key);
int keygen_set_std_prefs (const char *string,int personal);
PKT_user_id *keygen_get_std_prefs (void);
int keygen_add_key_expire( PKT_signature *sig, void *opaque );
+int keygen_add_key_flags (PKT_signature *sig, void *opaque);
int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
int keygen_upd_std_prefs( PKT_signature *sig, void *opaque );
int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git
More information about the Pkg-gnupg-commit
mailing list