mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-01 16:33:02 +01:00
g10: Support key attribute change at --card-edit/generate.
* g10/card-util.c (ask_card_rsa_keysize): Drop support for magic number 25519 for ed25519/cv25519. Rename from ask_card_keyattr. (ask_card_keyattr): Support ECC, as well as RSA. (do_change_keyattr): Support ECC dropping magical number 25519. * g10/keygen.c (ask_curve): Allow call from outside, adding last arg of CURRENT. (generate_keypair): Follow the change of ask_curve. (generate_subkeypair): Likewise. -- GnuPG-bug-id: 3781 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
02d7bb819f
commit
a1515b3bbc
246
g10/card-util.c
246
g10/card-util.c
@ -1355,11 +1355,10 @@ show_keysize_warning (void)
|
|||||||
|
|
||||||
|
|
||||||
/* Ask for the size of a card key. NBITS is the current size
|
/* Ask for the size of a card key. NBITS is the current size
|
||||||
configured for the card. KEYNO is the number of the key used to
|
configured for the card. Returns 0 to use the default size
|
||||||
select the prompt. Returns 0 to use the default size (i.e. NBITS)
|
(i.e. NBITS) or the selected size. */
|
||||||
or the selected size. */
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
ask_card_keyattr (int keyno, unsigned int nbits)
|
ask_card_rsa_keysize (unsigned int nbits)
|
||||||
{
|
{
|
||||||
unsigned int min_nbits = 1024;
|
unsigned int min_nbits = 1024;
|
||||||
unsigned int max_nbits = 4096;
|
unsigned int max_nbits = 4096;
|
||||||
@ -1368,78 +1367,175 @@ ask_card_keyattr (int keyno, unsigned int nbits)
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
prompt = xasprintf
|
prompt = xasprintf (_("What keysize do you want? (%u) "), nbits);
|
||||||
(keyno == 0?
|
|
||||||
_("What keysize do you want for the Signature key? (%u) "):
|
|
||||||
keyno == 1?
|
|
||||||
_("What keysize do you want for the Encryption key? (%u) "):
|
|
||||||
_("What keysize do you want for the Authentication key? (%u) "),
|
|
||||||
nbits);
|
|
||||||
answer = cpr_get ("cardedit.genkeys.size", prompt);
|
answer = cpr_get ("cardedit.genkeys.size", prompt);
|
||||||
cpr_kill_prompt ();
|
cpr_kill_prompt ();
|
||||||
req_nbits = *answer? atoi (answer): nbits;
|
req_nbits = *answer? atoi (answer): nbits;
|
||||||
xfree (prompt);
|
xfree (prompt);
|
||||||
xfree (answer);
|
xfree (answer);
|
||||||
|
|
||||||
if (req_nbits == 25519)
|
if (req_nbits != nbits && (req_nbits % 32) )
|
||||||
{
|
{
|
||||||
if (req_nbits == nbits)
|
req_nbits = ((req_nbits + 31) / 32) * 32;
|
||||||
return 0; /* Use default. */
|
tty_printf (_("rounded up to %u bits\n"), req_nbits);
|
||||||
|
}
|
||||||
|
|
||||||
tty_printf (_("The card will now be re-configured"
|
if (req_nbits == nbits)
|
||||||
" to generate a key of type: %s\n"),
|
return 0; /* Use default. */
|
||||||
keyno==1? "cv25519":"ed25519");
|
|
||||||
show_keysize_warning ();
|
if (req_nbits < min_nbits || req_nbits > max_nbits)
|
||||||
return req_nbits;
|
{
|
||||||
|
tty_printf (_("%s keysizes must be in the range %u-%u\n"),
|
||||||
|
"RSA", min_nbits, max_nbits);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (req_nbits != nbits && (req_nbits % 32) )
|
tty_printf (_("The card will now be re-configured"
|
||||||
{
|
" to generate a key of %u bits\n"), req_nbits);
|
||||||
req_nbits = ((req_nbits + 31) / 32) * 32;
|
show_keysize_warning ();
|
||||||
tty_printf (_("rounded up to %u bits\n"), req_nbits);
|
return req_nbits;
|
||||||
}
|
|
||||||
|
|
||||||
if (req_nbits == nbits)
|
|
||||||
return 0; /* Use default. */
|
|
||||||
|
|
||||||
if (req_nbits < min_nbits || req_nbits > max_nbits)
|
|
||||||
{
|
|
||||||
tty_printf (_("%s keysizes must be in the range %u-%u\n"),
|
|
||||||
"RSA", min_nbits, max_nbits);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tty_printf (_("The card will now be re-configured"
|
|
||||||
" to generate a key of %u bits\n"), req_nbits);
|
|
||||||
show_keysize_warning ();
|
|
||||||
return req_nbits;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ask for the key attribute of a card key. CURRENT is the current
|
||||||
/* Change the size of key KEYNO (0..2) to NBITS and show an error
|
attribute configured for the card. KEYNO is the number of the key
|
||||||
* message if that fails. Using the magic value 25519 for NBITS
|
used to select the prompt. Returns NULL to use the default
|
||||||
* switches to ed25519 or cv25519 depending on the KEYNO. */
|
attribute or the selected attribute structure. */
|
||||||
static gpg_error_t
|
static struct key_attr *
|
||||||
do_change_keyattr (int keyno, unsigned int nbits)
|
ask_card_keyattr (int keyno, const struct key_attr *current)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
struct key_attr *key_attr = NULL;
|
||||||
|
char *answer = NULL;
|
||||||
|
int algo;
|
||||||
|
|
||||||
|
tty_printf (_("Changing card key attribute for: "));
|
||||||
|
if (keyno == 0)
|
||||||
|
tty_printf (_("Signature key\n"));
|
||||||
|
else if (keyno == 1)
|
||||||
|
tty_printf (_("Encryption key\n"));
|
||||||
|
else
|
||||||
|
tty_printf (_("Authentication key\n"));
|
||||||
|
|
||||||
|
tty_printf (_("Please select what kind of key you want:\n"));
|
||||||
|
tty_printf (_(" (%d) RSA\n"), 1 );
|
||||||
|
tty_printf (_(" (%d) ECC\n"), 2 );
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
xfree (answer);
|
||||||
|
answer = cpr_get ("cardedit.genkeys.algo", _("Your selection? "));
|
||||||
|
cpr_kill_prompt ();
|
||||||
|
algo = *answer? atoi (answer) : 0;
|
||||||
|
|
||||||
|
if (!*answer || algo == 1 || algo == 2)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
tty_printf (_("Invalid selection.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (algo == 0)
|
||||||
|
got leave;
|
||||||
|
|
||||||
|
key_attr = xmalloc (sizeof (struct key_attr));
|
||||||
|
|
||||||
|
if (algo == 1)
|
||||||
|
{
|
||||||
|
unsigned int nbits, result_nbits;
|
||||||
|
|
||||||
|
if (current->algo == PUBKEY_ALGO_RSA)
|
||||||
|
nbits = current->nbits;
|
||||||
|
else
|
||||||
|
nbits = 2048;
|
||||||
|
|
||||||
|
result_nbits = ask_card_rsa_keysize (nbits);
|
||||||
|
if (result_nbits == 0)
|
||||||
|
{
|
||||||
|
if (current->algo == PUBKEY_ALGO_RSA)
|
||||||
|
{
|
||||||
|
xfree (key_attr);
|
||||||
|
key_attr = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result_nbits = nbits;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_attr)
|
||||||
|
{
|
||||||
|
key_attr->algo = PUBKEY_ALGO_RSA;
|
||||||
|
key_attr->nbits = result_nbits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *curve;
|
||||||
|
const char *oid_str;
|
||||||
|
|
||||||
|
if (current->algo == PUBKEY_ALGO_RSA)
|
||||||
|
{
|
||||||
|
if (keyno == 1)
|
||||||
|
/* Encryption key */
|
||||||
|
algo = PUBKEY_ALGO_ECDH;
|
||||||
|
else /* Signature key or Authentication key */
|
||||||
|
algo = PUBKEY_ALGO_ECDSA;
|
||||||
|
curve = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
algo = current->algo;
|
||||||
|
curve = current->curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
curve = ask_curve (&algo, NULL, curve);
|
||||||
|
if (curve)
|
||||||
|
{
|
||||||
|
key_attr->algo = algo;
|
||||||
|
oid_str = openpgp_curve_to_oid (curve, NULL);
|
||||||
|
key_attr->curve = openpgp_oid_to_curve (oid_str, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xfree (key_attr);
|
||||||
|
key_attr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
|
if (!key_attr)
|
||||||
|
tty_printf (_("No change."));
|
||||||
|
|
||||||
|
return key_attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Change the key attribute of key KEYNO (0..2) and show an error
|
||||||
|
* message if that fails. */
|
||||||
|
static gpg_error_t
|
||||||
|
do_change_keyattr (int keyno, const struct key_attr *key_attr)
|
||||||
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
char args[100];
|
char args[100];
|
||||||
|
|
||||||
if (nbits == 25519)
|
if (key_attr->algo == PUBKEY_ALGO_RSA)
|
||||||
|
snprintf (args, sizeof args, "--force %d 1 rsa%u", keyno+1,
|
||||||
|
key_attr->nbits);
|
||||||
|
else if (key_attr->algo == PUBKEY_ALGO_ECDH
|
||||||
|
|| key_attr->algo == PUBKEY_ALGO_ECDSA
|
||||||
|
|| key_attr->algo == PUBKEY_ALGO_EDDSA)
|
||||||
snprintf (args, sizeof args, "--force %d %d %s",
|
snprintf (args, sizeof args, "--force %d %d %s",
|
||||||
keyno+1,
|
keyno+1, key_attr->algo, key_attr->curve);
|
||||||
keyno == 1? PUBKEY_ALGO_ECDH : PUBKEY_ALGO_EDDSA,
|
|
||||||
keyno == 1? "cv25519" : "ed25519");
|
|
||||||
else
|
else
|
||||||
snprintf (args, sizeof args, "--force %d 1 rsa%u", keyno+1, nbits);
|
{
|
||||||
|
log_error (_("public key algorithm %d (%s) is not supported\n"),
|
||||||
|
key_attr->algo, gcry_pk_algo_name (key_attr->algo));
|
||||||
|
return gpg_error (GPG_ERR_PUBKEY_ALGO);
|
||||||
|
}
|
||||||
|
|
||||||
err = agent_scd_setattr ("KEY-ATTR", args, strlen (args), NULL);
|
err = agent_scd_setattr ("KEY-ATTR", args, strlen (args), NULL);
|
||||||
if (err)
|
if (err)
|
||||||
log_error (_("error changing size of key %d to %u bits: %s\n"),
|
log_error (_("error changing key attribute for key %d: %s\n"),
|
||||||
keyno+1, nbits, gpg_strerror (err));
|
keyno+1, gpg_strerror (err));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1502,26 +1598,21 @@ generate_card_keys (ctrl_t ctrl)
|
|||||||
key size. */
|
key size. */
|
||||||
if (info.is_v2 && info.extcap.aac)
|
if (info.is_v2 && info.extcap.aac)
|
||||||
{
|
{
|
||||||
unsigned int nbits;
|
|
||||||
|
|
||||||
for (keyno = 0; keyno < DIM (info.key_attr); keyno++)
|
for (keyno = 0; keyno < DIM (info.key_attr); keyno++)
|
||||||
{
|
{
|
||||||
if (info.key_attr[keyno].algo == PUBKEY_ALGO_RSA
|
struct key_attr *key_attr;
|
||||||
|| info.key_attr[keyno].algo == PUBKEY_ALGO_ECDH
|
|
||||||
|| info.key_attr[keyno].algo == PUBKEY_ALGO_EDDSA)
|
|
||||||
{
|
|
||||||
if (info.key_attr[keyno].algo == PUBKEY_ALGO_RSA)
|
|
||||||
nbits = ask_card_keyattr (keyno, info.key_attr[keyno].nbits);
|
|
||||||
else
|
|
||||||
nbits = ask_card_keyattr (keyno, 25519 /* magic */);
|
|
||||||
|
|
||||||
if (nbits && do_change_keyattr (keyno, nbits))
|
if ((key_attr = ask_card_keyattr (keyno, &info.key_attr[keyno])))
|
||||||
|
{
|
||||||
|
gpg_error_t err = do_change_keyattr (keyno, key_attr);
|
||||||
|
xfree (key_attr);
|
||||||
|
if (err)
|
||||||
{
|
{
|
||||||
/* Error: Better read the default key size again. */
|
/* Error: Better read the default key attribute again. */
|
||||||
agent_release_card_info (&info);
|
agent_release_card_info (&info);
|
||||||
if (get_info_for_key_operation (&info))
|
if (get_info_for_key_operation (&info))
|
||||||
goto leave;
|
goto leave;
|
||||||
/* Ask again for this key size. */
|
/* Ask again for this key. */
|
||||||
keyno--;
|
keyno--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1591,21 +1682,16 @@ card_generate_subkey (ctrl_t ctrl, kbnode_t pub_keyblock)
|
|||||||
key size. */
|
key size. */
|
||||||
if (info.is_v2 && info.extcap.aac)
|
if (info.is_v2 && info.extcap.aac)
|
||||||
{
|
{
|
||||||
if (info.key_attr[keyno-1].algo == PUBKEY_ALGO_RSA
|
struct key_attr *key_attr;
|
||||||
|| info.key_attr[keyno].algo == PUBKEY_ALGO_ECDH
|
|
||||||
|| info.key_attr[keyno].algo == PUBKEY_ALGO_EDDSA)
|
ask_again:
|
||||||
|
if ((key_attr = ask_card_keyattr (keyno-1, &info.key_attr[keyno-1])))
|
||||||
{
|
{
|
||||||
unsigned int nbits;
|
err = do_change_keyattr (keyno-1, key_attr);
|
||||||
|
xfree (key_attr);
|
||||||
ask_again:
|
if (err)
|
||||||
if (info.key_attr[keyno].algo == PUBKEY_ALGO_RSA)
|
|
||||||
nbits = ask_card_keyattr (keyno-1, info.key_attr[keyno-1].nbits);
|
|
||||||
else
|
|
||||||
nbits = ask_card_keyattr (keyno-1, 25519);
|
|
||||||
|
|
||||||
if (nbits && do_change_keyattr (keyno-1, nbits))
|
|
||||||
{
|
{
|
||||||
/* Error: Better read the default key size again. */
|
/* Error: Better read the default key attribute again. */
|
||||||
agent_release_card_info (&info);
|
agent_release_card_info (&info);
|
||||||
err = get_info_for_key_operation (&info);
|
err = get_info_for_key_operation (&info);
|
||||||
if (err)
|
if (err)
|
||||||
|
17
g10/keygen.c
17
g10/keygen.c
@ -2235,8 +2235,8 @@ ask_keysize (int algo, unsigned int primary_keysize)
|
|||||||
/* Ask for the curve. ALGO is the selected algorithm which this
|
/* Ask for the curve. ALGO is the selected algorithm which this
|
||||||
function may adjust. Returns a const string of the name of the
|
function may adjust. Returns a const string of the name of the
|
||||||
curve. */
|
curve. */
|
||||||
static const char *
|
const char *
|
||||||
ask_curve (int *algo, int *subkey_algo)
|
ask_curve (int *algo, int *subkey_algo, const char *current)
|
||||||
{
|
{
|
||||||
/* NB: We always use a complete algo list so that we have stable
|
/* NB: We always use a complete algo list so that we have stable
|
||||||
numbers in the menu regardless on how Gpg was configured. */
|
numbers in the menu regardless on how Gpg was configured. */
|
||||||
@ -2327,7 +2327,12 @@ ask_curve (int *algo, int *subkey_algo)
|
|||||||
answer = cpr_get ("keygen.curve", _("Your selection? "));
|
answer = cpr_get ("keygen.curve", _("Your selection? "));
|
||||||
cpr_kill_prompt ();
|
cpr_kill_prompt ();
|
||||||
idx = *answer? atoi (answer) : 1;
|
idx = *answer? atoi (answer) : 1;
|
||||||
if (*answer && !idx)
|
if (!*answer && current)
|
||||||
|
{
|
||||||
|
xfree(answer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (*answer && !idx)
|
||||||
{
|
{
|
||||||
/* See whether the user entered the name of the curve. */
|
/* See whether the user entered the name of the curve. */
|
||||||
for (idx=0; idx < DIM(curves); idx++)
|
for (idx=0; idx < DIM(curves); idx++)
|
||||||
@ -4263,7 +4268,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
|||||||
|| algo == PUBKEY_ALGO_EDDSA
|
|| algo == PUBKEY_ALGO_EDDSA
|
||||||
|| algo == PUBKEY_ALGO_ECDH)
|
|| algo == PUBKEY_ALGO_ECDH)
|
||||||
{
|
{
|
||||||
curve = ask_curve (&algo, &subkey_algo);
|
curve = ask_curve (&algo, &subkey_algo, NULL);
|
||||||
r = xmalloc_clear( sizeof *r + 20 );
|
r = xmalloc_clear( sizeof *r + 20 );
|
||||||
r->key = pKEYTYPE;
|
r->key = pKEYTYPE;
|
||||||
sprintf( r->u.value, "%d", algo);
|
sprintf( r->u.value, "%d", algo);
|
||||||
@ -4333,7 +4338,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
|||||||
|| algo == PUBKEY_ALGO_EDDSA
|
|| algo == PUBKEY_ALGO_EDDSA
|
||||||
|| algo == PUBKEY_ALGO_ECDH)
|
|| algo == PUBKEY_ALGO_ECDH)
|
||||||
{
|
{
|
||||||
curve = ask_curve (&algo, NULL);
|
curve = ask_curve (&algo, NULL, NULL);
|
||||||
r = xmalloc_clear (sizeof *r + strlen (curve));
|
r = xmalloc_clear (sizeof *r + strlen (curve));
|
||||||
r->key = pKEYCURVE;
|
r->key = pKEYCURVE;
|
||||||
strcpy (r->u.value, curve);
|
strcpy (r->u.value, curve);
|
||||||
@ -5075,7 +5080,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
|
|||||||
else if (algo == PUBKEY_ALGO_ECDSA
|
else if (algo == PUBKEY_ALGO_ECDSA
|
||||||
|| algo == PUBKEY_ALGO_EDDSA
|
|| algo == PUBKEY_ALGO_EDDSA
|
||||||
|| algo == PUBKEY_ALGO_ECDH)
|
|| algo == PUBKEY_ALGO_ECDH)
|
||||||
curve = ask_curve (&algo, NULL);
|
curve = ask_curve (&algo, NULL, NULL);
|
||||||
else
|
else
|
||||||
nbits = ask_keysize (algo, 0);
|
nbits = ask_keysize (algo, 0);
|
||||||
|
|
||||||
|
@ -292,6 +292,7 @@ u32 parse_expire_string(const char *string);
|
|||||||
u32 ask_expire_interval(int object,const char *def_expire);
|
u32 ask_expire_interval(int object,const char *def_expire);
|
||||||
u32 ask_expiredate(void);
|
u32 ask_expiredate(void);
|
||||||
unsigned int ask_key_flags (int algo, int subkey, unsigned int current);
|
unsigned int ask_key_flags (int algo, int subkey, unsigned int current);
|
||||||
|
const char *ask_curve (int *algo, int *subkey_algo, const char *current);
|
||||||
void quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
|
void quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
|
||||||
const char *usagestr, const char *expirestr);
|
const char *usagestr, const char *expirestr);
|
||||||
void generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
void generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user