diff options
author | NIIBE Yutaka <[email protected]> | 2018-03-29 02:56:02 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2018-03-29 02:56:02 +0000 |
commit | a1515b3bbc10a210040dda3b482bcdb933fa8d7c (patch) | |
tree | b985f1f5090ea4f1edaf0d5366be97a61c665fd9 | |
parent | g10: check_pin_for_key_operation should be just before genkey. (diff) | |
download | gnupg-a1515b3bbc10a210040dda3b482bcdb933fa8d7c.tar.gz gnupg-a1515b3bbc10a210040dda3b482bcdb933fa8d7c.zip |
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 <[email protected]>
-rw-r--r-- | g10/card-util.c | 228 | ||||
-rw-r--r-- | g10/keygen.c | 17 | ||||
-rw-r--r-- | g10/main.h | 1 |
3 files changed, 169 insertions, 77 deletions
diff --git a/g10/card-util.c b/g10/card-util.c index 2aa9c3f28..263ab4ebd 100644 --- a/g10/card-util.c +++ b/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 - configured for the card. KEYNO is the number of the key used to - select the prompt. Returns 0 to use the default size (i.e. NBITS) - or the selected size. */ + configured for the card. Returns 0 to use the default size + (i.e. NBITS) or the selected size. */ 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 max_nbits = 4096; @@ -1368,78 +1367,175 @@ ask_card_keyattr (int keyno, unsigned int nbits) for (;;) { - prompt = xasprintf - (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); + prompt = xasprintf (_("What keysize do you want? (%u) "), nbits); answer = cpr_get ("cardedit.genkeys.size", prompt); cpr_kill_prompt (); req_nbits = *answer? atoi (answer): nbits; xfree (prompt); xfree (answer); - if (req_nbits == 25519) + if (req_nbits != nbits && (req_nbits % 32) ) { - if (req_nbits == nbits) - return 0; /* Use default. */ + req_nbits = ((req_nbits + 31) / 32) * 32; + tty_printf (_("rounded up to %u bits\n"), 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 type: %s\n"), - keyno==1? "cv25519":"ed25519"); + " 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 + attribute configured for the card. KEYNO is the number of the key + used to select the prompt. Returns NULL to use the default + attribute or the selected attribute structure. */ +static struct key_attr * +ask_card_keyattr (int keyno, const struct key_attr *current) +{ + 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 - { - if (req_nbits != nbits && (req_nbits % 32) ) - { - req_nbits = ((req_nbits + 31) / 32) * 32; - tty_printf (_("rounded up to %u bits\n"), req_nbits); - } + tty_printf (_("Invalid selection.\n")); + } + + if (algo == 0) + got leave; - if (req_nbits == nbits) - return 0; /* Use default. */ + key_attr = xmalloc (sizeof (struct key_attr)); - if (req_nbits < min_nbits || req_nbits > max_nbits) + 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) { - tty_printf (_("%s keysizes must be in the range %u-%u\n"), - "RSA", min_nbits, max_nbits); + xfree (key_attr); + key_attr = NULL; } 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; - } + 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 size of key KEYNO (0..2) to NBITS and show an error - * message if that fails. Using the magic value 25519 for NBITS - * switches to ed25519 or cv25519 depending on the KEYNO. */ + +/* 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, unsigned int nbits) +do_change_keyattr (int keyno, const struct key_attr *key_attr) { - gpg_error_t err; + gpg_error_t err = 0; 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", - keyno+1, - keyno == 1? PUBKEY_ALGO_ECDH : PUBKEY_ALGO_EDDSA, - keyno == 1? "cv25519" : "ed25519"); + keyno+1, key_attr->algo, key_attr->curve); 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); if (err) - log_error (_("error changing size of key %d to %u bits: %s\n"), - keyno+1, nbits, gpg_strerror (err)); + log_error (_("error changing key attribute for key %d: %s\n"), + keyno+1, gpg_strerror (err)); return err; } @@ -1502,26 +1598,21 @@ generate_card_keys (ctrl_t ctrl) key size. */ if (info.is_v2 && info.extcap.aac) { - unsigned int nbits; - for (keyno = 0; keyno < DIM (info.key_attr); keyno++) { - if (info.key_attr[keyno].algo == PUBKEY_ALGO_RSA - || 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 */); + struct key_attr *key_attr; - 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); if (get_info_for_key_operation (&info)) goto leave; - /* Ask again for this key size. */ + /* Ask again for this key. */ keyno--; } } @@ -1591,21 +1682,16 @@ card_generate_subkey (ctrl_t ctrl, kbnode_t pub_keyblock) key size. */ if (info.is_v2 && info.extcap.aac) { - if (info.key_attr[keyno-1].algo == PUBKEY_ALGO_RSA - || info.key_attr[keyno].algo == PUBKEY_ALGO_ECDH - || info.key_attr[keyno].algo == PUBKEY_ALGO_EDDSA) - { - unsigned int nbits; - - ask_again: - 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); + struct key_attr *key_attr; - if (nbits && do_change_keyattr (keyno-1, nbits)) + ask_again: + if ((key_attr = ask_card_keyattr (keyno-1, &info.key_attr[keyno-1]))) + { + err = do_change_keyattr (keyno-1, 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); err = get_info_for_key_operation (&info); if (err) diff --git a/g10/keygen.c b/g10/keygen.c index 109879854..a4949f486 100644 --- a/g10/keygen.c +++ b/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 function may adjust. Returns a const string of the name of the curve. */ -static const char * -ask_curve (int *algo, int *subkey_algo) +const char * +ask_curve (int *algo, int *subkey_algo, const char *current) { /* NB: We always use a complete algo list so that we have stable 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? ")); cpr_kill_prompt (); 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. */ 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_ECDH) { - curve = ask_curve (&algo, &subkey_algo); + curve = ask_curve (&algo, &subkey_algo, NULL); r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYTYPE; 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_ECDH) { - curve = ask_curve (&algo, NULL); + curve = ask_curve (&algo, NULL, NULL); r = xmalloc_clear (sizeof *r + strlen (curve)); r->key = pKEYCURVE; 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 || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH) - curve = ask_curve (&algo, NULL); + curve = ask_curve (&algo, NULL, NULL); else nbits = ask_keysize (algo, 0); diff --git a/g10/main.h b/g10/main.h index 6c15a2a8d..af25d559c 100644 --- a/g10/main.h +++ b/g10/main.h @@ -292,6 +292,7 @@ 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); +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, const char *usagestr, const char *expirestr); void generate_keypair (ctrl_t ctrl, int full, const char *fname, |