mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
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@gnupg.org>
This commit is contained in:
parent
9663b08848
commit
9b28b82e7c
119
g10/keyedit.c
119
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)
|
||||
{
|
||||
|
36
g10/keygen.c
36
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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user