From 438b7881ba0bf4e5fd8e5d5212601e5691f2aafe Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 10 Feb 2020 14:12:36 +0100 Subject: [PATCH] card: Remove command "key-attr" and hack on "generate". * tools/gpg-card.h (struct key_attr): Remove. (struct key_info_s): Remove key_attr. Add keyalgo and keyalgo_id. * tools/card-call-scd.c (learn_status_cb): Rework the key-attr info. * tools/gpg-card.c (list_one_kinfo): Always show the algorithm; if there is no key show the key attributes instead. (list_openpgp): Do not print the "Key attributes". (generate_key): Factor the repalce key pormpt out to ... (ask_replace_keys): new. (generate_openpgp): Rename to generate_all_openpgp_card_keys and add an algo parameter. (generate_generic): Rename to generate_key. Prepare generation of a single OpenPGP key. (cmd_generate): Revamp. (ask_card_rsa_keysize): Remove. (ask_card_keyattr): Remove. (do_change_keyattr): Remove. (cmd_keyattr): Remove. (enum cmdids): Remove cmdKEYATTR. (cmds): Ditto. (dispatch_command): Ditto. (interactive_loop): Ditto. -- This change shows the key attributes of an OpenPGP card instead of the key's algorithm if no key exists. It also remove the key-attr command because for uniformity it is better to do this directly in scd/app-openpgp.c At least for this new gpg-card tool. There a couple of other changes but to the generate command but they are not yet ready. Signed-off-by: Werner Koch --- tools/card-call-scd.c | 57 +++-- tools/gpg-card.c | 528 +++++++++++++----------------------------- tools/gpg-card.h | 16 +- 3 files changed, 203 insertions(+), 398 deletions(-) diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 80058efa9..54380c5c9 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -817,25 +817,54 @@ learn_status_cb (void *opaque, const char *line) } else if (!memcmp (keyword, "KEY-ATTR", keywordlen)) { - int keyno = 0; - int algo = GCRY_PK_RSA; - int n = 0; + char keyrefbuf[20]; + int keyno, algo, n; + const char *curve; + unsigned int nbits; + /* To prepare for future changes we allow for a full OpenPGP + * keyref here. */ + if (!ascii_strncasecmp (line, "OPENPGP.", 8)) + line += 8; + + /* Note that KEY-ATTR returns OpenPGP algorithm numbers but + * we want to use the Gcrypt numbers here. A compatible + * change would be to add another paramater along with a + * magic algo number to indicate that. */ + algo = PUBKEY_ALGO_RSA; + keyno = n = 0; sscanf (line, "%d %d %n", &keyno, &algo, &n); - keyno--; - if (keyno < 0 || keyno >= DIM (parm->key_attr)) + algo = map_openpgp_pk_to_gcry (algo); + if (keyno < 1 || keyno > 3) ; /* Out of range - ignore. */ else { - parm->key_attr[keyno].algo = algo; - if (algo == PUBKEY_ALGO_RSA) - parm->key_attr[keyno].nbits = strtoul (line+n+3, NULL, 10); - else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA - || algo == PUBKEY_ALGO_EDDSA) + snprintf (keyrefbuf, sizeof keyrefbuf, "OPENPGP.%d", keyno); + keyref = keyrefbuf; + + kinfo = find_kinfo (parm, keyref); + if (!kinfo) /* No: new entry. */ + kinfo = create_kinfo (parm, keyref); + + /* Although we could use the the value at %n directly as + * keyalgo string, we want to use the standard + * keyalgo_string function and thus we reconstruct it + * here to make sure the displayed form of the curve + * names is used. */ + nbits = 0; + curve = NULL; + if (algo == GCRY_PK_ECDH || algo == GCRY_PK_ECDSA + || algo == GCRY_PK_EDDSA || algo == GCRY_PK_ECC) { - parm->key_attr[keyno].curve = - openpgp_is_curve_supported (line + n, NULL, NULL); + curve = openpgp_is_curve_supported (line + n, NULL, NULL); } + else /* For rsa we see here for example "rsa2048". */ + { + if (line[n] && line[n+1] && line[n+2]) + nbits = strtoul (line+n+3, NULL, 10); + } + kinfo->keyalgo = get_keyalgo_string (algo, nbits, curve); + kinfo->keyalgo_id = algo; } } break; @@ -1267,11 +1296,11 @@ scd_genkey_cb (void *opaque, const char *line) return 0; } + /* Send a GENKEY command to the SCdaemon. If *CREATETIME is not 0, * the value will be passed to SCDAEMON with --timestamp option so that * the key is created with this. Otherwise, timestamp was generated by - * SCDEAMON. On success, creation time is stored back to - * CREATETIME. */ + * SCDAEMON. On success, creation time is stored back to CREATETIME. */ gpg_error_t scd_genkey (const char *keyref, int force, const char *algo, u32 *createtime) { diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 5d5829aad..9979020a3 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -127,6 +127,7 @@ typedef struct keyinfolabel_s *keyinfolabel_t; /* Local prototypes. */ +static void show_keysize_warning (void); static gpg_error_t dispatch_command (card_info_t info, const char *command); static void interactive_loop (void); #ifdef HAVE_LIBREADLINE @@ -652,6 +653,7 @@ list_one_kinfo (key_info_t firstkinfo, key_info_t kinfo, { tty_fprintf (fp, "[none]\n"); tty_fprintf (fp, " keyref .....: %s\n", kinfo->keyref); + tty_fprintf (fp, " algorithm ..: %s\n", kinfo->keyalgo); goto leave; } @@ -681,6 +683,10 @@ list_one_kinfo (key_info_t firstkinfo, key_info_t kinfo, gcry_sexp_release (s_pkey); s_pkey = NULL; } + else + { + tty_fprintf (fp, " algorithm ..: %s\n", kinfo->keyalgo); + } if (kinfo->fprlen && kinfo->created) { @@ -746,6 +752,8 @@ list_one_kinfo (key_info_t firstkinfo, key_info_t kinfo, tty_fprintf (fp, " [none]\n"); if (label_keyref) tty_fprintf (fp, " keyref .....: %s\n", label_keyref); + if (kinfo) + tty_fprintf (fp, " algorithm ..: %s\n", kinfo->keyalgo); } leave: @@ -798,7 +806,6 @@ list_openpgp (card_info_t info, estream_t fp) { "Authentication key:", "OPENPGP.3" }, { NULL, NULL } }; - int i; if (!info->serialno || strncmp (info->serialno, "D27600012401", 12) @@ -845,26 +852,6 @@ list_openpgp (card_info_t info, estream_t fp) } tty_fprintf (fp, "Signature PIN ....: %s\n", info->chv1_cached? _("not forced"): _("forced")); - if (info->key_attr[0].algo) - { - tty_fprintf (fp, "Key attributes ...:"); - for (i=0; i < DIM (info->key_attr); i++) - if (info->key_attr[i].algo == PUBKEY_ALGO_RSA) - tty_fprintf (fp, " rsa%u", info->key_attr[i].nbits); - else if (info->key_attr[i].algo == PUBKEY_ALGO_ECDH - || info->key_attr[i].algo == PUBKEY_ALGO_ECDSA - || info->key_attr[i].algo == PUBKEY_ALGO_EDDSA) - { - const char *curve_for_print = "?"; - const char *oid; - - if (info->key_attr[i].curve - && (oid = openpgp_curve_to_oid (info->key_attr[i].curve, NULL))) - curve_for_print = openpgp_oid_to_curve (oid, 0); - tty_fprintf (fp, " %s", curve_for_print); - } - tty_fprintf (fp, "\n"); - } tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n", info->chvmaxlen[0], info->chvmaxlen[1], info->chvmaxlen[2]); tty_fprintf (fp, "PIN retry counter : %d %d %d\n", @@ -2002,7 +1989,7 @@ cmd_forcesig (card_info_t info) -/* Helper for cmd_generate_openpgp. Noe that either 0 or 1 is stored at +/* Helper for cmd_generate_openpgp. Nore that either 0 or 1 is stored at * FORCED_CHV1. */ static gpg_error_t check_pin_for_key_operation (card_info_t info, int *forced_chv1) @@ -2055,9 +2042,42 @@ restore_forced_chv1 (int *forced_chv1) } -/* Implementation of cmd_generate for OpenPGP cards. */ +/* Ask whether existing keys shall be overwritten. With NULL used for + * KINFO it will ask for all keys, other wise for the given key. */ static gpg_error_t -generate_openpgp (card_info_t info) +ask_replace_keys (key_info_t kinfo) +{ + gpg_error_t err; + char *answer; + + tty_printf ("\n"); + if (kinfo) + log_info (_("Note: key %s is already stored on the card!\n"), + kinfo->keyref); + else + log_info (_("Note: Keys are already stored on the card!\n")); + tty_printf ("\n"); + if (kinfo) + answer = tty_getf (_("Replace existing key %s ? (y/N) "), kinfo->keyref); + else + answer = tty_get (_("Replace existing keys? (y/N) ")); + tty_kill_prompt (); + if (*answer == CONTROL_D) + err = gpg_error (GPG_ERR_CANCELED); + else if (!answer_is_yes_no_default (answer, 0/*(default to No)*/)) + err = gpg_error (GPG_ERR_CANCELED); + else + err = 0; + + xfree (answer); + return err; +} + + +/* Implementation of cmd_generate for OpenPGP cards to generate all + * standard keys at once. */ +static gpg_error_t +generate_all_openpgp_card_keys (card_info_t info, char **algos) { gpg_error_t err; int forced_chv1 = -1; @@ -2089,22 +2109,9 @@ generate_openpgp (card_info_t info) || (kinfo3 && kinfo3->fprlen && !mem_is_zero (kinfo3->fpr,kinfo3->fprlen)) ) { - tty_printf ("\n"); - log_info (_("Note: keys are already stored on the card!\n")); - tty_printf ("\n"); - answer = tty_get (_("Replace existing keys? (y/N) ")); - tty_kill_prompt (); - if (*answer == CONTROL_D) - { - err = gpg_error (GPG_ERR_CANCELED); - goto leave; - } - - if (!answer_is_yes_no_default (answer, 0/*(default to No)*/)) - { - err = gpg_error (GPG_ERR_CANCELED); - goto leave; - } + err = ask_replace_keys (NULL); + if (err) + goto leave; } /* If no displayed name has been set, we assume that this is a fresh @@ -2123,7 +2130,9 @@ generate_openpgp (card_info_t info) if (err) goto leave; - /* FIXME: We need to divert to a function which spwans gpg which + (void)algos; /* FIXME: If we have ALGOS, we need to change the key attr. */ + + /* FIXME: We need to divert to a function which spawns gpg which * will then create the key. This also requires new features in * gpg. We might also first create the keys on the card and then * tell gpg to use them to create the OpenPGP keyblock. */ @@ -2138,17 +2147,50 @@ generate_openpgp (card_info_t info) } -/* Generic implementation of cmd_generate. */ +/* Create a single key. This is a helper for cmd_generate. */ static gpg_error_t -generate_generic (card_info_t info, const char *keyref, int force, - const char *algo) +generate_key (card_info_t info, const char *keyref, int force, + const char *algo) { gpg_error_t err; + key_info_t kinfo; - (void)info; + if (info->apptype == APP_TYPE_OPENPGP) + { + kinfo = find_kinfo (info, keyref); + if (!kinfo) + { + err = gpg_error (GPG_ERR_INV_ID); + goto leave; + } + + if (!force + && kinfo->fprlen && !mem_is_zero (kinfo->fpr, kinfo->fprlen)) + { + err = ask_replace_keys (NULL); + if (err) + goto leave; + } + + log_debug ("current algo is: %s\n", kinfo->keyalgo); + if (algo) + { + log_debug ("setting algo to: %s\n", algo); + /* OpenPGP cards require us to set the key attributes prior + * to generation because the generate command does not take + * key attributes. Actually this should be hidden by + * scd/app-openpgp but that is not the case. */ + + + + } + goto leave; + /* err = generate_openpgp (info); */ + } err = scd_genkey (keyref, force, algo, NULL); + leave: return err; } @@ -2165,17 +2207,21 @@ cmd_generate (card_info_t info, char *argstr) }; gpg_error_t err; int opt_force; - char *opt_algo = NULL; /* Malloced. */ + char *p; + char **opt_algo = NULL; /* Malloced. */ char *keyref_buffer = NULL; /* Malloced. */ char *keyref; /* Points into argstr or keyref_buffer. */ - int i; + int i, j; if (!info) return print_help - ("GENERATE [--force] [--algo=ALGO] KEYREF\n\n" - "Create a new key on a card. For OpenPGP cards a menu is used\n" - "and KEYREF is ignored. Use --force to overwrite an existing key.\n" - "Using \"help\" for ALGO gives a list of known algorithms.\n", + ("GENERATE [--force] [--algo=ALGO{+ALGO2}] KEYREF\n\n" + "Create a new key on a card.\n" + "Use --force to overwrite an existing key.\n" + "Use \"help\" for ALGO to get a list of known algorithms.\n" + "For OpenPGP cards several algos may be given.\n" + "Note that the OpenPGP key generation is done interactively\n" + "unless a single ALGO or KEYREF are given.", APP_TYPE_OPENPGP, APP_TYPE_PIV, 0); if (opt.interactive || opt.verbose) @@ -2184,9 +2230,21 @@ cmd_generate (card_info_t info, char *argstr) info->dispserialno? info->dispserialno : info->serialno); opt_force = has_leading_option (argstr, "--force"); - err = get_option_value (argstr, "--algo", &opt_algo); + err = get_option_value (argstr, "--algo", &p); if (err) goto leave; + if (p) + { + opt_algo = strtokenize (p, "+"); + if (!opt_algo) + { + err = gpg_error_from_syserror (); + xfree (p); + goto leave; + } + xfree (p); + } + argstr = skip_options (argstr); keyref = argstr; @@ -2211,33 +2269,40 @@ cmd_generate (card_info_t info, char *argstr) if (opt_algo) { - for (i=0; valid_algos[i]; i++) - if (*valid_algos[i] && !strcmp (valid_algos[i], opt_algo)) - break; - if (!valid_algos[i]) + /* opt_algo is an array of algos. */ + for (i=0; opt_algo[i]; i++) { - int lf = 1; - if (!ascii_strcasecmp (opt_algo, "help")) - log_info ("Known algorithms:\n"); - else + for (j=0; valid_algos[j]; j++) + if (*valid_algos[j] && !strcmp (valid_algos[j], opt_algo[i])) + break; + if (!valid_algos[j]) { - log_info ("Invalid algorithm '%s' given. Use one:\n", opt_algo); - err = gpg_error (GPG_ERR_PUBKEY_ALGO); - } - for (i=0; valid_algos[i]; i++) - { - if (!*valid_algos[i]) - lf = 1; - else if (lf) - { - lf = 0; - log_info (" %s%s", valid_algos[i], valid_algos[i+1]?",":"."); - } + int lf = 1; + if (!ascii_strcasecmp (opt_algo[i], "help")) + log_info ("Known algorithms:\n"); else - log_printf (" %s%s", valid_algos[i], valid_algos[i+1]?",":"."); + { + log_info ("Invalid algorithm '%s' given. Use one of:\n", + opt_algo[i]); + err = gpg_error (GPG_ERR_PUBKEY_ALGO); + } + for (i=0; valid_algos[i]; i++) + { + if (!*valid_algos[i]) + lf = 1; + else if (lf) + { + lf = 0; + log_info (" %s%s", + valid_algos[i], valid_algos[i+1]?",":"."); + } + else + log_printf (" %s%s", + valid_algos[i], valid_algos[i+1]?",":"."); + } + show_keysize_warning (); + goto leave; } - log_info ("Note that the card may not support all of them.\n"); - goto leave; } } @@ -2264,16 +2329,25 @@ cmd_generate (card_info_t info, char *argstr) } /* Divert to dedicated functions. */ - if (info->apptype == APP_TYPE_OPENPGP) + if (info->apptype == APP_TYPE_OPENPGP + && !keyref + && (!opt_algo || (opt_algo[0] && opt_algo[1]))) { - if (opt_force || opt_algo || keyref) - log_info ("Note: Options are ignored for OpenPGP cards.\n"); - err = generate_openpgp (info); + /* With no algo requested or more than one algo requested and no + * keyref given we create all keys. */ + if (opt_force || keyref) + log_info ("Note: OpenPGP key generation is interactive.\n"); + err = generate_all_openpgp_card_keys (info, opt_algo); } else if (!keyref) err = gpg_error (GPG_ERR_INV_ID); + else if (opt_algo && opt_algo[0] && opt_algo[1]) + { + log_error ("only one algorithm expected as value for --algo.\n"); + err = gpg_error (GPG_ERR_INV_ARG); + } else - err = generate_generic (info, keyref, opt_force, opt_algo); + err = generate_key (info, keyref, opt_force, opt_algo? opt_algo[0]:NULL); leave: xfree (opt_algo); @@ -2805,295 +2879,6 @@ show_keysize_warning (void) } -/* Ask for the size of a card key. NBITS is the current size - * configured for the card. Returns 0 on success and stored the - * chosen key size at R_KEYSIZE; 0 is stored to indicate that the - * default size shall be used. */ -static gpg_error_t -ask_card_rsa_keysize (unsigned int nbits, unsigned int *r_keysize) -{ - unsigned int min_nbits = 1024; - unsigned int max_nbits = 4096; - char*answer; - unsigned int req_nbits; - - for (;;) - { - answer = tty_getf (_("What keysize do you want? (%u) "), nbits); - trim_spaces (answer); - tty_kill_prompt (); - if (*answer == CONTROL_D) - { - xfree (answer); - return gpg_error (GPG_ERR_CANCELED); - } - req_nbits = *answer? atoi (answer): nbits; - xfree (answer); - - if (req_nbits != nbits && (req_nbits % 32) ) - { - req_nbits = ((req_nbits + 31) / 32) * 32; - tty_printf (_("rounded up to %u bits\n"), req_nbits); - } - - if (req_nbits == nbits) - { - /* Use default. */ - *r_keysize = 0; - return 0; - } - - 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 - { - *r_keysize = req_nbits; - return 0; - } - } -} - - -/* 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. Stores NULL at result to use the - * default attribute or stores the selected attribute structure at - * RESULT. On error an error code is returned. */ -static gpg_error_t -ask_card_keyattr (int keyno, const struct key_attr *current, - struct key_attr **result) -{ - gpg_error_t err; - struct key_attr *key_attr = NULL; - char *answer = NULL; - int selection; - - *result = NULL; - - key_attr = xcalloc (1, sizeof *key_attr); - - 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 = tty_get (_("Your selection? ")); - trim_spaces (answer); - tty_kill_prompt (); - if (!*answer || *answer == CONTROL_D) - { - err = gpg_error (GPG_ERR_CANCELED); - goto leave; - } - selection = *answer? atoi (answer) : 0; - - if (selection == 1 || selection == 2) - break; - else - tty_printf (_("Invalid selection.\n")); - } - - - if (selection == 1) - { - unsigned int nbits, result_nbits; - - if (current->algo == PUBKEY_ALGO_RSA) - nbits = current->nbits; - else - nbits = 2048; - - err = ask_card_rsa_keysize (nbits, &result_nbits); - if (err) - goto leave; - 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 if (selection == 2) - { - const char *curve; - /* const char *oid_str; */ - int algo; - - 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; - } - - (void)curve; - (void)algo; - err = GPG_ERR_NOT_IMPLEMENTED; - goto leave; - /* FIXME: We need to move the ask_cure code out to common or - * provide another sultion. */ - /* 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; */ - /* } */ - } - else - { - err = gpg_error (GPG_ERR_BUG); - goto leave; - } - - /* Tell the user what we are going to do. */ - if (key_attr->algo == PUBKEY_ALGO_RSA) - { - tty_printf (_("The card will now be re-configured" - " to generate a key of %u bits\n"), key_attr->nbits); - } - else if (key_attr->algo == PUBKEY_ALGO_ECDH - || key_attr->algo == PUBKEY_ALGO_ECDSA - || key_attr->algo == PUBKEY_ALGO_EDDSA) - { - tty_printf (_("The card will now be re-configured" - " to generate a key of type: %s\n"), key_attr->curve); - } - show_keysize_warning (); - - *result = key_attr; - key_attr = NULL; - - leave: - xfree (key_attr); - xfree (answer); - return err; -} - - -/* 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]; - - 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, key_attr->algo, key_attr->curve); - else - { - /* FIXME: Above we use openpgp algo names but in the error - * message we use the gcrypt names. We should settle for a - * consistent solution. */ - log_error (_("public key algorithm %d (%s) is not supported\n"), - key_attr->algo, gcry_pk_algo_name (key_attr->algo)); - err = gpg_error (GPG_ERR_PUBKEY_ALGO); - goto leave; - } - - err = scd_setattr ("KEY-ATTR", args, strlen (args)); - if (err) - log_error (_("error changing key attribute for key %d: %s\n"), - keyno+1, gpg_strerror (err)); - leave: - return err; -} - - -static gpg_error_t -cmd_keyattr (card_info_t info, char *argstr) -{ - gpg_error_t err = 0; - int keyno; - struct key_attr *key_attr = NULL; - - (void)argstr; - - if (!info) - return print_help - ("KEY-ATTR\n\n" - "Menu to change the key attributes of an OpenPGP card.", - APP_TYPE_OPENPGP, 0); - - if (info->apptype != APP_TYPE_OPENPGP) - { - log_info ("Note: This is an OpenPGP only command.\n"); - return gpg_error (GPG_ERR_NOT_SUPPORTED); - } - - if (!(info->is_v2 && info->extcap.aac)) - { - log_error (_("This command is not supported by this card\n")); - err = gpg_error (GPG_ERR_NOT_SUPPORTED); - goto leave; - } - - for (keyno = 0; keyno < DIM (info->key_attr); keyno++) - { - xfree (key_attr); - key_attr = NULL; - err = ask_card_keyattr (keyno, &info->key_attr[keyno], &key_attr); - if (err) - goto leave; - - err = do_change_keyattr (keyno, key_attr); - if (err) - { - /* Error: Better read the default key attribute again. */ - log_debug ("FIXME\n"); - /* Ask again for this key. */ - keyno--; - } - } - - leave: - xfree (key_attr); - return err; -} - - static gpg_error_t cmd_uif (card_info_t info, char *argstr) { @@ -3196,7 +2981,7 @@ enum cmdids cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSALUT, cmdCAFPR, cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT, cmdREADCERT, cmdWRITEKEY, cmdUNBLOCK, cmdFACTRST, cmdKDFSETUP, - cmdKEYATTR, cmdUIF, cmdAUTH, cmdYUBIKEY, + cmdUIF, cmdAUTH, cmdYUBIKEY, cmdINVCMD }; @@ -3230,7 +3015,6 @@ static struct { "reset" , cmdRESET, N_("send a reset to the card daemon")}, { "factory-reset",cmdFACTRST, N_("destroy all keys and data")}, { "kdf-setup", cmdKDFSETUP, N_("setup KDF for PIN authentication")}, - { "key-attr", cmdKEYATTR, N_("change the key attribute")}, { "uif", cmdUIF, N_("change the User Interaction Flag")}, { "privatedo", cmdPRIVATEDO, N_("change a private data object")}, { "readcert", cmdREADCERT, N_("read a certificate from a data object")}, @@ -3356,7 +3140,6 @@ dispatch_command (card_info_t info, const char *orig_command) case cmdUNBLOCK: err = cmd_unblock (info); break; case cmdFACTRST: err = cmd_factoryreset (info); break; case cmdKDFSETUP: err = cmd_kdfsetup (info, argstr); break; - case cmdKEYATTR: err = cmd_keyattr (info, argstr); break; case cmdUIF: err = cmd_uif (info, argstr); break; case cmdYUBIKEY: err = cmd_yubikey (info, argstr); break; @@ -3578,7 +3361,6 @@ interactive_loop (void) redisplay = 1; break; case cmdKDFSETUP: err = cmd_kdfsetup (info, argstr); break; - case cmdKEYATTR: err = cmd_keyattr (info, argstr); break; case cmdUIF: err = cmd_uif (info, argstr); break; case cmdYUBIKEY: err = cmd_yubikey (info, argstr); break; diff --git a/tools/gpg-card.h b/tools/gpg-card.h index c6f73405f..02c1ed314 100644 --- a/tools/gpg-card.h +++ b/tools/gpg-card.h @@ -102,16 +102,6 @@ typedef enum } app_type_t; -/* OpenPGP card key attributes. */ -struct key_attr -{ - int algo; /* Algorithm identifier. */ - union { - unsigned int nbits; /* Supported keysize. */ - const char *curve; /* Name of curve. */ - }; -}; - /* An object to store information pertaining to a key pair as stored * on a card. This is commonly used as a linked list with all keys * known for the current card. */ @@ -123,6 +113,11 @@ struct key_info_s unsigned char xflag; /* Temporary flag to help processing a list. */ + /* OpenPGP card and possible other cards keyalgo string (an atom) + * and the id of the algorithm. */ + const char *keyalgo; + enum gcry_pk_algos keyalgo_id; + /* The three next items are mostly useful for OpenPGP cards. */ unsigned char fprlen; /* Use length of the next item. */ unsigned char fpr[32]; /* The binary fingerprint of length FPRLEN. */ @@ -169,7 +164,6 @@ struct card_info_s int chvmaxlen[3]; /* Maximum allowed length of a CHV. */ int chvinfo[3]; /* Allowed retries for the CHV; 0 = blocked. */ unsigned char chvusage[2]; /* Data object 5F2F */ - struct key_attr key_attr[3]; /* OpenPGP card key attributes. */ struct { unsigned int ki:1; /* Key import available. */ unsigned int aac:1; /* Algorithm attributes are changeable. */