mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
scd:openpgp: Allow auto-changing of the key attributes in genkey.
* scd/app-openpgp.c (struct app_local_s): Add field keyalgo. (parse_algorithm_attribute): Store the new keyalgo field. (change_keyattr): Change info message. (change_keyattr_from_string): Rewrite to also accept a keyref and a keyalgo string. (do_genkey): Change the keyattr if a keyalgo string is given. * scd/command.c (cmd_genkey): Add option --algo. -- Having this feature makes it easier to use OpenPGP cards in a similar way to other cards. Note that the explicit changing via SETATTR is still supported. Signed-off-by: Werner Koch <wk@gnupg.org> (cherry picked from commit d7d75da50543bc7259c5a6e6367b58cbca7f1b7b) (cherry picked from commit b349adc5c0d00d2fc405a45bd078f1580b5610cc)
This commit is contained in:
parent
2e39fed109
commit
210ba98355
@ -226,5 +226,8 @@ gpg_error_t compute_openpgp_fpr_ecc (int keyversion,
|
|||||||
unsigned char *result,
|
unsigned char *result,
|
||||||
unsigned int *r_resultlen);
|
unsigned int *r_resultlen);
|
||||||
|
|
||||||
|
/*-- openpgp-oid.c --*/
|
||||||
|
enum gcry_pk_algos map_openpgp_pk_to_gcry (pubkey_algo_t algo);
|
||||||
|
|
||||||
|
|
||||||
#endif /*GNUPG_COMMON_OPENPGPDEFS_H*/
|
#endif /*GNUPG_COMMON_OPENPGPDEFS_H*/
|
||||||
|
@ -223,6 +223,7 @@ struct app_local_s {
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
key_type_t key_type;
|
key_type_t key_type;
|
||||||
|
const char *keyalgo; /* Algorithm in standard string format. */
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
unsigned int n_bits; /* Size of the modulus in bits. The rest
|
unsigned int n_bits; /* Size of the modulus in bits. The rest
|
||||||
@ -257,6 +258,7 @@ static gpg_error_t change_keyattr_from_string
|
|||||||
(app_t app,
|
(app_t app,
|
||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
|
const char *keyref, const char *keyalgo,
|
||||||
const void *value, size_t valuelen);
|
const void *value, size_t valuelen);
|
||||||
|
|
||||||
|
|
||||||
@ -2612,7 +2614,8 @@ do_setattr (app_t app, ctrl_t ctrl, const char *name,
|
|||||||
return gpg_error (GPG_ERR_NOT_SUPPORTED); /* Not yet supported. */
|
return gpg_error (GPG_ERR_NOT_SUPPORTED); /* Not yet supported. */
|
||||||
|
|
||||||
if (table[idx].special == 3)
|
if (table[idx].special == 3)
|
||||||
return change_keyattr_from_string (app, pincb, pincb_arg, value, valuelen);
|
return change_keyattr_from_string (app, pincb, pincb_arg,
|
||||||
|
NULL, NULL, value, valuelen);
|
||||||
|
|
||||||
switch (table[idx].need_chv)
|
switch (table[idx].need_chv)
|
||||||
{
|
{
|
||||||
@ -3389,9 +3392,10 @@ change_keyattr (app_t app, int keyno, const unsigned char *buf, size_t buflen,
|
|||||||
/* Change the attribute. */
|
/* Change the attribute. */
|
||||||
err = iso7816_put_data (app_get_slot (app), 0, 0xC1+keyno, buf, buflen);
|
err = iso7816_put_data (app_get_slot (app), 0, 0xC1+keyno, buf, buflen);
|
||||||
if (err)
|
if (err)
|
||||||
log_error ("error changing key attribute (key=%d)\n", keyno+1);
|
log_error ("error changing key attribute of OPENPGP.%d\n",
|
||||||
|
keyno+1);
|
||||||
else
|
else
|
||||||
log_info ("key attribute changed (key=%d)\n", keyno+1);
|
log_info ("key attribute of OPENPGP.%d changed\n", keyno+1);
|
||||||
flush_cache (app);
|
flush_cache (app);
|
||||||
err = parse_algorithm_attribute (app, keyno);
|
err = parse_algorithm_attribute (app, keyno);
|
||||||
app->did_chv1 = 0;
|
app->did_chv1 = 0;
|
||||||
@ -3451,51 +3455,138 @@ change_rsa_keyattr (app_t app, int keyno, unsigned int nbits,
|
|||||||
|
|
||||||
|
|
||||||
/* Helper to process an setattr command for name KEY-ATTR.
|
/* Helper to process an setattr command for name KEY-ATTR.
|
||||||
In (VALUE,VALUELEN), it expects following string:
|
*
|
||||||
RSA: "--force <key> <algo> rsa<nbits>"
|
* If KEYREF and KEYALGO are NULL (VALUE,VALUELEN) are expected to
|
||||||
ECC: "--force <key> <algo> <curvename>"
|
* contain one of the following strings:
|
||||||
*/
|
* RSA: "--force <key> <algo> rsa<nbits>"
|
||||||
|
* ECC: "--force <key> <algo> <curvename>"
|
||||||
|
*
|
||||||
|
* If KEYREF and KEYALGO is given the key attribute for KEYREF are
|
||||||
|
* changed to what is described by KEYALGO (e.g. "rsa3072", "rsa2048",
|
||||||
|
* or "ed25519").
|
||||||
|
*/
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
change_keyattr_from_string (app_t app,
|
change_keyattr_from_string (app_t app,
|
||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
|
const char *keyref, const char *keyalgo,
|
||||||
const void *value, size_t valuelen)
|
const void *value, size_t valuelen)
|
||||||
{
|
{
|
||||||
gpg_error_t err = 0;
|
gpg_error_t err = 0;
|
||||||
char *string;
|
char *string = NULL;
|
||||||
int key, keyno, algo;
|
int key, keyno, algo;
|
||||||
int n = 0;
|
unsigned int nbits = 0;
|
||||||
|
const char *oidstr = NULL; /* OID of the curve. */
|
||||||
|
char *endp;
|
||||||
|
|
||||||
/* VALUE is expected to be a string but not guaranteed to be
|
if (keyref && keyalgo && *keyref && *keyalgo)
|
||||||
terminated. Thus copy it to an allocated buffer first. */
|
|
||||||
string = xtrymalloc (valuelen+1);
|
|
||||||
if (!string)
|
|
||||||
return gpg_error_from_syserror ();
|
|
||||||
memcpy (string, value, valuelen);
|
|
||||||
string[valuelen] = 0;
|
|
||||||
|
|
||||||
/* Because this function deletes the key we require the string
|
|
||||||
"--force" in the data to make clear that something serious might
|
|
||||||
happen. */
|
|
||||||
sscanf (string, "--force %d %d %n", &key, &algo, &n);
|
|
||||||
if (n < 12)
|
|
||||||
{
|
{
|
||||||
err = gpg_error (GPG_ERR_INV_DATA);
|
if (!ascii_strcasecmp (keyref, "OPENPGP.1"))
|
||||||
|
keyno = 0;
|
||||||
|
else if (!ascii_strcasecmp (keyref, "OPENPGP.2"))
|
||||||
|
keyno = 1;
|
||||||
|
else if (!ascii_strcasecmp (keyref, "OPENPGP.3"))
|
||||||
|
keyno = 2;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_INV_ID);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp (keyalgo, "rsa", 3) && digitp (keyalgo+3))
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
nbits = strtoul (keyalgo+3, &endp, 10);
|
||||||
|
if (errno || *endp)
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_INV_DATA);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
algo = PUBKEY_ALGO_RSA;
|
||||||
|
}
|
||||||
|
else if ((!strncmp (keyalgo, "dsa", 3) || !strncmp (keyalgo, "elg", 3))
|
||||||
|
&& digitp (keyalgo+3))
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nbits = 0;
|
||||||
|
oidstr = openpgp_curve_to_oid (keyalgo, NULL, &algo);
|
||||||
|
if (!oidstr)
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_INV_DATA);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
if (!algo)
|
||||||
|
algo = keyno == 1? PUBKEY_ALGO_ECDH : PUBKEY_ALGO_ECDSA;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!keyref && !keyalgo && value)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
/* VALUE is expected to be a string but not guaranteed to be
|
||||||
|
* terminated. Thus copy it to an allocated buffer first. */
|
||||||
|
string = xtrymalloc (valuelen+1);
|
||||||
|
if (!string)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
memcpy (string, value, valuelen);
|
||||||
|
string[valuelen] = 0;
|
||||||
|
|
||||||
|
/* Because this function deletes the key we require the string
|
||||||
|
* "--force" in the data to make clear that something serious
|
||||||
|
* might happen. */
|
||||||
|
n = 0;
|
||||||
|
sscanf (string, "--force %d %d %n", &key, &algo, &n);
|
||||||
|
if (n < 12)
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_INV_DATA);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
keyno = key - 1;
|
||||||
|
if (algo == PUBKEY_ALGO_RSA)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
nbits = strtoul (string+n+3, NULL, 10);
|
||||||
|
if (errno)
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_INV_DATA);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA
|
||||||
|
|| algo == PUBKEY_ALGO_EDDSA)
|
||||||
|
{
|
||||||
|
oidstr = openpgp_curve_to_oid (string+n, NULL, NULL);
|
||||||
|
if (!oidstr)
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_INV_DATA);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_INV_ARG);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyno = key - 1;
|
|
||||||
if (keyno < 0 || keyno > 2)
|
if (keyno < 0 || keyno > 2)
|
||||||
err = gpg_error (GPG_ERR_INV_ID);
|
err = gpg_error (GPG_ERR_INV_ID);
|
||||||
else if (algo == PUBKEY_ALGO_RSA)
|
else if (algo == PUBKEY_ALGO_RSA)
|
||||||
{
|
{
|
||||||
unsigned int nbits;
|
if (nbits < 1024)
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
nbits = strtoul (string+n+3, NULL, 10);
|
|
||||||
if (errno)
|
|
||||||
err = gpg_error (GPG_ERR_INV_DATA);
|
|
||||||
else if (nbits < 1024)
|
|
||||||
err = gpg_error (GPG_ERR_TOO_SHORT);
|
err = gpg_error (GPG_ERR_TOO_SHORT);
|
||||||
else if (nbits > 4096)
|
else if (nbits > 4096)
|
||||||
err = gpg_error (GPG_ERR_TOO_LARGE);
|
err = gpg_error (GPG_ERR_TOO_LARGE);
|
||||||
@ -3505,18 +3596,23 @@ change_keyattr_from_string (app_t app,
|
|||||||
else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA
|
else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA
|
||||||
|| algo == PUBKEY_ALGO_EDDSA)
|
|| algo == PUBKEY_ALGO_EDDSA)
|
||||||
{
|
{
|
||||||
const char *oidstr;
|
|
||||||
gcry_mpi_t oid;
|
gcry_mpi_t oid;
|
||||||
const unsigned char *oidbuf;
|
const unsigned char *oidbuf;
|
||||||
size_t oid_len;
|
size_t oid_len;
|
||||||
|
unsigned int n;
|
||||||
|
|
||||||
oidstr = openpgp_curve_to_oid (string+n, NULL, NULL);
|
/* Check that the requested algo matches the properties of the
|
||||||
if (!oidstr)
|
* key slot. */
|
||||||
{
|
if (keyno == 1 && algo != PUBKEY_ALGO_ECDH)
|
||||||
err = gpg_error (GPG_ERR_INV_DATA);
|
err = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
|
||||||
goto leave;
|
else if (keyno != 1 && algo == PUBKEY_ALGO_ECDH)
|
||||||
}
|
err = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
|
||||||
|
else
|
||||||
|
err = 0;
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
/* Convert the OID string to an OpenPGP formatted OID. */
|
||||||
err = openpgp_oid_from_str (oidstr, &oid);
|
err = openpgp_oid_from_str (oidstr, &oid);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -3524,7 +3620,14 @@ change_keyattr_from_string (app_t app,
|
|||||||
oidbuf = gcry_mpi_get_opaque (oid, &n);
|
oidbuf = gcry_mpi_get_opaque (oid, &n);
|
||||||
oid_len = (n+7)/8;
|
oid_len = (n+7)/8;
|
||||||
|
|
||||||
/* We have enough room at STRING. */
|
/* Create the template. */
|
||||||
|
xfree (string);
|
||||||
|
string = xtrymalloc (1 + oid_len);
|
||||||
|
if (!string)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
string[0] = algo;
|
string[0] = algo;
|
||||||
memcpy (string+1, oidbuf+1, oid_len-1);
|
memcpy (string+1, oidbuf+1, oid_len-1);
|
||||||
err = change_keyattr (app, keyno, string, oid_len, pincb, pincb_arg);
|
err = change_keyattr (app, keyno, string, oid_len, pincb, pincb_arg);
|
||||||
@ -4204,26 +4307,31 @@ do_writekey (app_t app, ctrl_t ctrl,
|
|||||||
|
|
||||||
/* Handle the GENKEY command. */
|
/* Handle the GENKEY command. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, const char *keytype,
|
do_genkey (app_t app, ctrl_t ctrl, const char *keyref, const char *keyalgo,
|
||||||
unsigned int flags, time_t createtime,
|
unsigned int flags, time_t createtime,
|
||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg)
|
void *pincb_arg)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
char numbuf[30];
|
char numbuf[30];
|
||||||
|
const char *keynostr;
|
||||||
unsigned char *buffer = NULL;
|
unsigned char *buffer = NULL;
|
||||||
const unsigned char *keydata;
|
const unsigned char *keydata;
|
||||||
size_t buflen, keydatalen;
|
size_t buflen, keydatalen;
|
||||||
u32 created_at;
|
u32 created_at;
|
||||||
int keyno = atoi (keynostr) - 1;
|
int keyno;
|
||||||
int force = (flags & 1);
|
int force = !!(flags & APP_GENKEY_FLAG_FORCE);
|
||||||
time_t start_at;
|
time_t start_at;
|
||||||
int exmode = 0;
|
int exmode = 0;
|
||||||
int le_value = 256; /* Use legacy value. */
|
int le_value = 256; /* Use legacy value. */
|
||||||
|
|
||||||
(void)keytype; /* Ignored for OpenPGP cards. */
|
/* Strip the OpenPGP prefix which is for historical reasons optional. */
|
||||||
|
keynostr = keyref;
|
||||||
|
if (!ascii_strncasecmp (keynostr, "OPENPGP.", 8))
|
||||||
|
keynostr += 8;
|
||||||
|
|
||||||
if (keyno < 0 || keyno > 2)
|
keyno = atoi (keynostr) - 1;
|
||||||
|
if (!digitp (keynostr) || keyno < 0 || keyno > 2)
|
||||||
return gpg_error (GPG_ERR_INV_ID);
|
return gpg_error (GPG_ERR_INV_ID);
|
||||||
|
|
||||||
/* We flush the cache to increase the traffic before a key
|
/* We flush the cache to increase the traffic before a key
|
||||||
@ -4241,6 +4349,19 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, const char *keytype,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
if (keyalgo && app->app_local->keyattr[keyno].keyalgo
|
||||||
|
&& strcmp (keyalgo, app->app_local->keyattr[keyno].keyalgo))
|
||||||
|
{
|
||||||
|
/* Specific algorithm requested which is not the currently
|
||||||
|
* configured algorithm. Change it. */
|
||||||
|
log_info ("openpgp: changing key attribute from %s to %s\n",
|
||||||
|
app->app_local->keyattr[keyno].keyalgo, keyalgo);
|
||||||
|
err = change_keyattr_from_string (app, pincb, pincb_arg,
|
||||||
|
keyref, keyalgo, NULL, 0);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA)
|
if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA)
|
||||||
{
|
{
|
||||||
unsigned int keybits = app->app_local->keyattr[keyno].rsa.n_bits;
|
unsigned int keybits = app->app_local->keyattr[keyno].rsa.n_bits;
|
||||||
@ -5164,7 +5285,7 @@ parse_historical (struct app_local_s *apploc,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the OID in an DER encoding is available by GnuPG/libgcrypt,
|
* Check if the OID in an DER encoding is available by GnuPG/libgcrypt,
|
||||||
* and return the curve name. Return NULL if not available.
|
* and return the canonical curve name. Return NULL if not available.
|
||||||
* The constant string is not allocated dynamically, never free it.
|
* The constant string is not allocated dynamically, never free it.
|
||||||
*/
|
*/
|
||||||
static const char *
|
static const char *
|
||||||
@ -5208,9 +5329,12 @@ parse_algorithm_attribute (app_t app, int keyno)
|
|||||||
size_t buflen;
|
size_t buflen;
|
||||||
void *relptr;
|
void *relptr;
|
||||||
const char desc[3][5] = {"sign", "encr", "auth"};
|
const char desc[3][5] = {"sign", "encr", "auth"};
|
||||||
|
enum gcry_pk_algos galgo;
|
||||||
|
unsigned int nbits;
|
||||||
|
const char *curve;
|
||||||
gpg_error_t err = 0;
|
gpg_error_t err = 0;
|
||||||
|
|
||||||
assert (keyno >=0 && keyno <= 2);
|
log_assert (keyno >=0 && keyno <= 2);
|
||||||
|
|
||||||
app->app_local->keyattr[keyno].key_type = KEY_TYPE_RSA;
|
app->app_local->keyattr[keyno].key_type = KEY_TYPE_RSA;
|
||||||
app->app_local->keyattr[keyno].rsa.n_bits = 0;
|
app->app_local->keyattr[keyno].rsa.n_bits = 0;
|
||||||
@ -5230,6 +5354,11 @@ parse_algorithm_attribute (app_t app, int keyno)
|
|||||||
|
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info ("Key-Attr-%s ..: ", desc[keyno]);
|
log_info ("Key-Attr-%s ..: ", desc[keyno]);
|
||||||
|
|
||||||
|
galgo = map_openpgp_pk_to_gcry (*buffer);
|
||||||
|
nbits = 0;
|
||||||
|
curve = NULL;
|
||||||
|
|
||||||
if (*buffer == PUBKEY_ALGO_RSA && (buflen == 5 || buflen == 6))
|
if (*buffer == PUBKEY_ALGO_RSA && (buflen == 5 || buflen == 6))
|
||||||
{
|
{
|
||||||
app->app_local->keyattr[keyno].rsa.n_bits = (buffer[1]<<8 | buffer[2]);
|
app->app_local->keyattr[keyno].rsa.n_bits = (buffer[1]<<8 | buffer[2]);
|
||||||
@ -5244,6 +5373,7 @@ parse_algorithm_attribute (app_t app, int keyno)
|
|||||||
buffer[5] == 3? RSA_CRT_N :
|
buffer[5] == 3? RSA_CRT_N :
|
||||||
RSA_UNKNOWN_FMT);
|
RSA_UNKNOWN_FMT);
|
||||||
|
|
||||||
|
nbits = app->app_local->keyattr[keyno].rsa.n_bits;
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_printf
|
log_printf
|
||||||
("RSA, n=%u, e=%u, fmt=%s\n",
|
("RSA, n=%u, e=%u, fmt=%s\n",
|
||||||
@ -5257,7 +5387,6 @@ parse_algorithm_attribute (app_t app, int keyno)
|
|||||||
else if (*buffer == PUBKEY_ALGO_ECDH || *buffer == PUBKEY_ALGO_ECDSA
|
else if (*buffer == PUBKEY_ALGO_ECDH || *buffer == PUBKEY_ALGO_ECDSA
|
||||||
|| *buffer == PUBKEY_ALGO_EDDSA)
|
|| *buffer == PUBKEY_ALGO_EDDSA)
|
||||||
{
|
{
|
||||||
const char *curve;
|
|
||||||
int oidlen = buflen - 1;
|
int oidlen = buflen - 1;
|
||||||
|
|
||||||
app->app_local->keyattr[keyno].ecc.flags = 0;
|
app->app_local->keyattr[keyno].ecc.flags = 0;
|
||||||
@ -5309,6 +5438,13 @@ parse_algorithm_attribute (app_t app, int keyno)
|
|||||||
else if (opt.verbose)
|
else if (opt.verbose)
|
||||||
log_printhex (buffer, buflen, "");
|
log_printhex (buffer, buflen, "");
|
||||||
|
|
||||||
|
app->app_local->keyattr[keyno].keyalgo
|
||||||
|
= get_keyalgo_string (galgo, nbits, curve);
|
||||||
|
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info ("Key-Algo-%s ..: %s\n",
|
||||||
|
desc[keyno], app->app_local->keyattr[keyno].keyalgo);
|
||||||
|
|
||||||
xfree (relptr);
|
xfree (relptr);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1083,10 +1083,10 @@ cmd_writekey (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
|
|
||||||
static const char hlp_genkey[] =
|
static const char hlp_genkey[] =
|
||||||
"GENKEY [--force] [--timestamp=<isodate>] <no>\n"
|
"GENKEY [--force] [--timestamp=<isodate>] [--algo=ALGO] <keyref>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Generate a key on-card identified by NO, which is application\n"
|
"Generate a key on-card identified by <keyref>, which is application\n"
|
||||||
"specific. Return values are application specific. For OpenPGP\n"
|
"specific. Return values are also application specific. For OpenPGP\n"
|
||||||
"cards 3 status lines are returned:\n"
|
"cards 3 status lines are returned:\n"
|
||||||
"\n"
|
"\n"
|
||||||
" S KEY-FPR <hexstring>\n"
|
" S KEY-FPR <hexstring>\n"
|
||||||
@ -1105,16 +1105,21 @@ static const char hlp_genkey[] =
|
|||||||
"value. The value needs to be in ISO Format; e.g.\n"
|
"value. The value needs to be in ISO Format; e.g.\n"
|
||||||
"\"--timestamp=20030316T120000\" and after 1970-01-01 00:00:00.\n"
|
"\"--timestamp=20030316T120000\" and after 1970-01-01 00:00:00.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"The option --algo can be used to request creation using a specific\n"
|
||||||
|
"algorithm. The possible algorithms are card dependent.\n"
|
||||||
|
"\n"
|
||||||
"The public part of the key can also later be retrieved using the\n"
|
"The public part of the key can also later be retrieved using the\n"
|
||||||
"READKEY command.";
|
"READKEY command.";
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_genkey (assuan_context_t ctx, char *line)
|
cmd_genkey (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
int rc;
|
gpg_error_t err;
|
||||||
char *save_line;
|
char *keyref_buffer = NULL;
|
||||||
|
char *keyref;
|
||||||
int force;
|
int force;
|
||||||
const char *s;
|
const char *s;
|
||||||
|
char *opt_algo = NULL;
|
||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
|
|
||||||
force = has_option (line, "--force");
|
force = has_option (line, "--force");
|
||||||
@ -1130,39 +1135,41 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
|||||||
else
|
else
|
||||||
timestamp = 0;
|
timestamp = 0;
|
||||||
|
|
||||||
|
err = get_option_value (line, "--algo", &opt_algo);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
if (!*line)
|
if (!*line)
|
||||||
{
|
return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
|
||||||
rc = set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
|
keyref = line;
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
save_line = line;
|
|
||||||
while (*line && !spacep (line))
|
while (*line && !spacep (line))
|
||||||
line++;
|
line++;
|
||||||
*line = 0;
|
*line = 0;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl)))
|
if ((err = open_card (ctrl)))
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
if (!ctrl->app_ctx)
|
if (!ctrl->app_ctx)
|
||||||
{
|
{
|
||||||
rc = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
|
err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
keyref = keyref_buffer = xtrystrdup (keyref);
|
||||||
char *tmp = xtrystrdup (save_line);
|
if (!keyref)
|
||||||
if (!tmp)
|
{
|
||||||
return gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
rc = app_genkey (ctrl->app_ctx, ctrl, tmp, NULL,
|
goto leave;
|
||||||
force? APP_GENKEY_FLAG_FORCE : 0,
|
}
|
||||||
timestamp, pin_cb, ctx);
|
err = app_genkey (ctrl->app_ctx, ctrl, keyref, opt_algo,
|
||||||
xfree (tmp);
|
force? APP_GENKEY_FLAG_FORCE : 0,
|
||||||
}
|
timestamp, pin_cb, ctx);
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
return rc;
|
xfree (keyref_buffer);
|
||||||
|
xfree (opt_algo);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user