mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: New option --default-new-key-algo.
* common/openpgp-oid.c (openpgp_is_curve_supported): Add optional arg R_ALGO and change all callers. * common/util.h (GPG_ERR_UNKNOWN_FLAG): New error code. * g10/options.h (struct opt): Add field DEF_NEW_KEY_ALGO. * g10/gpg.c (oDefaultNewKeyAlgo): New enum. (opts): New option "--default-new-key-algo". (main): Set the option. * g10/keygen.c: Remove DEFAULT_STD_ FUTURE_STD_ constants and replace them by ... (DEFAULT_STD_KEY_PARAM, FUTURE_STD_KEY_PARAM): new string constants. (get_keysize_range): Remove arg R_DEF and return that value instead. Change all callers. (gen_rsa): Use get_keysize_range instead of the removed DEFAULT_STD_KEYSIZE. (parse_key_parameter_part): New function. (parse_key_parameter_string): New function. (quick_generate_keypair): Refactor using parse_key_parameter_string. (generate_keypair): Ditto. (parse_algo_usage_expire): Ditto. -- This new option is intended to be used in the forthcoming --set-profile command of gpgconf. It allows to provide a gpg configuration with custom defaults for a new key using the simple commands which use the default algorithm set. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
cd532bb7b8
commit
ce29272e24
2
NEWS
2
NEWS
@ -1,6 +1,8 @@
|
||||
Noteworthy changes in version 2.1.17 (unreleased)
|
||||
-------------------------------------------------
|
||||
|
||||
* gpg: New option --default-new-key-algo.
|
||||
|
||||
|
||||
Noteworthy changes in version 2.1.16 (2016-11-18)
|
||||
-------------------------------------------------
|
||||
|
@ -411,17 +411,21 @@ openpgp_enum_curves (int *iterp)
|
||||
}
|
||||
|
||||
|
||||
/* Return the Libgcrypt name for for the gpg curve NAME if supported.
|
||||
* If R_ALGO is not NULL the required OpenPGP public key algo or 0 is
|
||||
* stored at that address. NULL is returned if the curev is not
|
||||
* supported. */
|
||||
/* Return the Libgcrypt name for the gpg curve NAME if supported. If
|
||||
* R_ALGO is not NULL the required OpenPGP public key algo or 0 is
|
||||
* stored at that address. If R_NBITS is not NULL the nominal bitsize
|
||||
* of the curves is stored there. NULL is returned if the curve is
|
||||
* not supported. */
|
||||
const char *
|
||||
openpgp_is_curve_supported (const char *name, int *r_algo)
|
||||
openpgp_is_curve_supported (const char *name, int *r_algo,
|
||||
unsigned int *r_nbits)
|
||||
{
|
||||
int idx;
|
||||
|
||||
if (r_algo)
|
||||
*r_algo = 0;
|
||||
if (r_nbits)
|
||||
*r_nbits = 0;
|
||||
for (idx = 0; idx < DIM (oidtable) && oidtable[idx].name; idx++)
|
||||
{
|
||||
if ((!strcmp (name, oidtable[idx].name)
|
||||
@ -430,6 +434,8 @@ openpgp_is_curve_supported (const char *name, int *r_algo)
|
||||
{
|
||||
if (r_algo)
|
||||
*r_algo = oidtable[idx].pubkey_algo;
|
||||
if (r_nbits)
|
||||
*r_nbits = oidtable[idx].nbits;
|
||||
return oidtable[idx].name;
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,9 @@
|
||||
* libgpg-error version. Define them here.
|
||||
* Example: (#if GPG_ERROR_VERSION_NUMBER < 0x011500 // 1.21)
|
||||
*/
|
||||
#if GPG_ERROR_VERSION_NUMBER < 0x011a00 /* 1.26 */
|
||||
# define GPG_ERR_UNKNOWN_FLAG 309
|
||||
#endif
|
||||
|
||||
|
||||
/* Hash function used with libksba. */
|
||||
@ -210,7 +213,8 @@ int openpgp_oid_is_cv25519 (gcry_mpi_t a);
|
||||
const char *openpgp_curve_to_oid (const char *name, unsigned int *r_nbits);
|
||||
const char *openpgp_oid_to_curve (const char *oid, int canon);
|
||||
const char *openpgp_enum_curves (int *idxp);
|
||||
const char *openpgp_is_curve_supported (const char *name, int *r_algo);
|
||||
const char *openpgp_is_curve_supported (const char *name,
|
||||
int *r_algo, unsigned int *r_nbits);
|
||||
|
||||
|
||||
/*-- homedir.c --*/
|
||||
|
13
doc/gpg.texi
13
doc/gpg.texi
@ -1159,7 +1159,11 @@ filename given on the command line, gpg might still need to read from
|
||||
STDIN (in particular if gpg figures that the input is a
|
||||
detached signature and no data file has been specified). Thus if you
|
||||
do not want to feed data via STDIN, you should connect STDIN to
|
||||
@file{/dev/null}.
|
||||
g@file{/dev/null}.
|
||||
|
||||
It is highly recommended to use this option along with the options
|
||||
@option{--status-fd} and @option{--with-colons} for any unattended of
|
||||
@command{gpg}.
|
||||
|
||||
@item --no-tty
|
||||
@opindex no-tty
|
||||
@ -3162,6 +3166,13 @@ letter d (for days), w (for weeks), m (for months), or y (for years)
|
||||
(for example "2m" for two months, or "5y" for five years), or an
|
||||
absolute date in the form YYYY-MM-DD. Defaults to "0".
|
||||
|
||||
@item --default-new-key-algo @var{string}
|
||||
@opindex default-new-key-algo @var{string}
|
||||
This option can be used to change the default algorithms for key
|
||||
generation. Note that the advanced key generation commands can always
|
||||
be used to specify a key algorithm directly. Please consult the
|
||||
source code to learn the syntax of @var{string}.
|
||||
|
||||
@item --allow-secret-key-import
|
||||
@opindex allow-secret-key-import
|
||||
This is an obsolete option and is not used anywhere.
|
||||
|
@ -624,7 +624,8 @@ learn_status_cb (void *opaque, const char *line)
|
||||
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)
|
||||
parm->key_attr[keyno].curve = openpgp_is_curve_supported (line+n, NULL);
|
||||
parm->key_attr[keyno].curve = openpgp_is_curve_supported (line + n,
|
||||
NULL, NULL);
|
||||
}
|
||||
else if (keywordlen == 12 && !memcmp (keyword, "PRIVATE-DO-", 11)
|
||||
&& strchr("1234", keyword[11]))
|
||||
|
@ -407,6 +407,7 @@ enum cmd_and_opt_values
|
||||
oPrintDANERecords,
|
||||
oTOFUDefaultPolicy,
|
||||
oTOFUDBFormat,
|
||||
oDefaultNewKeyAlgo,
|
||||
oWeakDigest,
|
||||
oUnwrap,
|
||||
oOnlySignTextIDs,
|
||||
@ -836,6 +837,8 @@ static ARGPARSE_OPTS opts[] = {
|
||||
ARGPARSE_s_n (oNoAllowMultipleMessages, "no-allow-multiple-messages", "@"),
|
||||
ARGPARSE_s_n (oAllowWeakDigestAlgos, "allow-weak-digest-algos", "@"),
|
||||
|
||||
ARGPARSE_s_s (oDefaultNewKeyAlgo, "default-new-key-algo", "@"),
|
||||
|
||||
/* These two are aliases to help users of the PGP command line
|
||||
product use gpg with minimal pain. Many commands are common
|
||||
already as they seem to have borrowed commands from us. Now I'm
|
||||
@ -3469,6 +3472,10 @@ main (int argc, char **argv)
|
||||
|
||||
case oNoAutostart: opt.autostart = 0; break;
|
||||
|
||||
case oDefaultNewKeyAlgo:
|
||||
opt.def_new_key_algo = pargs.r.ret_str;
|
||||
break;
|
||||
|
||||
case oNoop: break;
|
||||
|
||||
default:
|
||||
|
511
g10/keygen.c
511
g10/keygen.c
@ -48,24 +48,10 @@
|
||||
|
||||
/* The default algorithms. If you change them remember to change them
|
||||
also in gpg.c:gpgconf_list. You should also check that the value
|
||||
is inside the bounds enforced by ask_keysize and gen_xxx. */
|
||||
#define DEFAULT_STD_ALGO PUBKEY_ALGO_RSA
|
||||
#define DEFAULT_STD_KEYSIZE 2048
|
||||
#define DEFAULT_STD_KEYUSE (PUBKEY_USAGE_CERT|PUBKEY_USAGE_SIG)
|
||||
#define DEFAULT_STD_CURVE NULL
|
||||
#define DEFAULT_STD_SUBALGO PUBKEY_ALGO_RSA
|
||||
#define DEFAULT_STD_SUBKEYSIZE 2048
|
||||
#define DEFAULT_STD_SUBKEYUSE PUBKEY_USAGE_ENC
|
||||
#define DEFAULT_STD_SUBCURVE NULL
|
||||
|
||||
#define FUTURE_STD_ALGO PUBKEY_ALGO_EDDSA
|
||||
#define FUTURE_STD_KEYSIZE 0
|
||||
#define FUTURE_STD_KEYUSE (PUBKEY_USAGE_CERT|PUBKEY_USAGE_SIG)
|
||||
#define FUTURE_STD_CURVE "Ed25519"
|
||||
#define FUTURE_STD_SUBALGO PUBKEY_ALGO_ECDH
|
||||
#define FUTURE_STD_SUBKEYSIZE 0
|
||||
#define FUTURE_STD_SUBKEYUSE PUBKEY_USAGE_ENC
|
||||
#define FUTURE_STD_SUBCURVE "Curve25519"
|
||||
is inside the bounds enforced by ask_keysize and gen_xxx. See also
|
||||
get_keysize_range which encodes the allowed ranges. */
|
||||
#define DEFAULT_STD_KEY_PARAM "rsa2048/cert,sign+rsa2048/encr"
|
||||
#define FUTURE_STD_KEY_PARAM "ed25519/cert,sign+cv25519/encr"
|
||||
|
||||
/* Flag bits used during key generation. */
|
||||
#define KEYGEN_FLAG_NO_PROTECTION 1
|
||||
@ -157,8 +143,12 @@ static int write_keyblock (iobuf_t out, kbnode_t node);
|
||||
static gpg_error_t gen_card_key (int keyno, int algo, int is_primary,
|
||||
kbnode_t pub_root, u32 *timestamp,
|
||||
u32 expireval);
|
||||
static unsigned int get_keysize_range (int algo,
|
||||
unsigned int *min, unsigned int *max);
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
print_status_key_created (int letter, PKT_public_key *pk, const char *handle)
|
||||
{
|
||||
@ -1602,7 +1592,7 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root,
|
||||
log_assert (is_RSA(algo));
|
||||
|
||||
if (!nbits)
|
||||
nbits = DEFAULT_STD_KEYSIZE;
|
||||
nbits = get_keysize_range (algo, NULL, NULL);
|
||||
|
||||
if (nbits < 1024)
|
||||
{
|
||||
@ -2056,36 +2046,46 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
get_keysize_range (int algo,
|
||||
unsigned int *min, unsigned int *def, unsigned int *max)
|
||||
static unsigned int
|
||||
get_keysize_range (int algo, unsigned int *min, unsigned int *max)
|
||||
{
|
||||
*min = opt.compliance == CO_DE_VS ? 2048: 1024;
|
||||
*def = DEFAULT_STD_KEYSIZE;
|
||||
*max = 4096;
|
||||
unsigned int def;
|
||||
unsigned int dummy1, dummy2;
|
||||
|
||||
if (!min)
|
||||
min = &dummy1;
|
||||
if (!max)
|
||||
max = &dummy2;
|
||||
|
||||
/* Deviations from the standard values. */
|
||||
switch(algo)
|
||||
{
|
||||
case PUBKEY_ALGO_DSA:
|
||||
*min = opt.expert? 768 : 1024;
|
||||
*def=2048;
|
||||
*max=3072;
|
||||
def=2048;
|
||||
break;
|
||||
|
||||
case PUBKEY_ALGO_ECDSA:
|
||||
case PUBKEY_ALGO_ECDH:
|
||||
*min=256;
|
||||
*def=256;
|
||||
*max=521;
|
||||
def=256;
|
||||
break;
|
||||
|
||||
case PUBKEY_ALGO_EDDSA:
|
||||
*min=255;
|
||||
*def=255;
|
||||
*max=441;
|
||||
def=255;
|
||||
break;
|
||||
|
||||
default:
|
||||
*min = opt.compliance == CO_DE_VS ? 2048: 1024;
|
||||
*max = 4096;
|
||||
def = 2048;
|
||||
break;
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
@ -2147,7 +2147,7 @@ ask_keysize (int algo, unsigned int primary_keysize)
|
||||
int for_subkey = !!primary_keysize;
|
||||
int autocomp = 0;
|
||||
|
||||
get_keysize_range (algo, &min, &def, &max);
|
||||
def = get_keysize_range (algo, &min, &max);
|
||||
|
||||
if (primary_keysize && !opt.expert)
|
||||
{
|
||||
@ -2854,6 +2854,292 @@ generate_user_id (KBNODE keyblock, const char *uidstr)
|
||||
}
|
||||
|
||||
|
||||
/* Helper for parse_key_parameter_string for one part of the
|
||||
* specification string; i.e. ALGO/FLAGS. If STRING is NULL or empty
|
||||
* success is returned. On error an error code is returned. Note
|
||||
* that STRING may be modified by this function. NULL may be passed
|
||||
* for any parameter. FOR_SUBKEY shall be true if this is used as a
|
||||
* subkey. */
|
||||
static gpg_error_t
|
||||
parse_key_parameter_part (char *string, int for_subkey,
|
||||
int *r_algo, unsigned int *r_size,
|
||||
unsigned int *r_keyuse,
|
||||
char const **r_curve)
|
||||
{
|
||||
char *flags;
|
||||
int algo = 0;
|
||||
char *endp;
|
||||
const char *curve = NULL;
|
||||
int ecdh_or_ecdsa = 0;
|
||||
unsigned int size;
|
||||
int keyuse;
|
||||
int i;
|
||||
const char *s;
|
||||
|
||||
if (!string || !*string)
|
||||
return 0; /* Success. */
|
||||
|
||||
flags = strchr (string, '/');
|
||||
if (flags)
|
||||
*flags++ = 0;
|
||||
|
||||
if (strlen (string) > 3 && digitp (string+3))
|
||||
{
|
||||
if (!ascii_memcasecmp (string, "rsa", 3))
|
||||
algo = PUBKEY_ALGO_RSA;
|
||||
else if (!ascii_memcasecmp (string, "dsa", 3))
|
||||
algo = PUBKEY_ALGO_DSA;
|
||||
else if (!ascii_memcasecmp (string, "elg", 3))
|
||||
algo = PUBKEY_ALGO_ELGAMAL_E;
|
||||
}
|
||||
if (algo)
|
||||
{
|
||||
size = strtoul (string+3, &endp, 10);
|
||||
if (size < 512 || size > 16384 || *endp)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
}
|
||||
else if ((curve = openpgp_is_curve_supported (string, &algo, &size)))
|
||||
{
|
||||
if (!algo)
|
||||
{
|
||||
algo = PUBKEY_ALGO_ECDH; /* Default ECC algorithm. */
|
||||
ecdh_or_ecdsa = 1; /* We may need to switch the algo. */
|
||||
}
|
||||
}
|
||||
else
|
||||
return gpg_error (GPG_ERR_UNKNOWN_CURVE);
|
||||
|
||||
/* Parse the flags. */
|
||||
keyuse = 0;
|
||||
if (flags)
|
||||
{
|
||||
char **tokens = NULL;
|
||||
|
||||
tokens = strtokenize (flags, ",");
|
||||
if (!tokens)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
for (i=0; (s = tokens[i]); i++)
|
||||
{
|
||||
if (!*s)
|
||||
;
|
||||
else if (!ascii_strcasecmp (s, "sign"))
|
||||
keyuse |= PUBKEY_USAGE_SIG;
|
||||
else if (!ascii_strcasecmp (s, "encrypt")
|
||||
|| !ascii_strcasecmp (s, "encr"))
|
||||
keyuse |= PUBKEY_USAGE_ENC;
|
||||
else if (!ascii_strcasecmp (s, "auth"))
|
||||
keyuse |= PUBKEY_USAGE_AUTH;
|
||||
else if (!ascii_strcasecmp (s, "cert"))
|
||||
keyuse |= PUBKEY_USAGE_CERT;
|
||||
else if (!ascii_strcasecmp (s, "ecdsa"))
|
||||
{
|
||||
if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA)
|
||||
algo = PUBKEY_ALGO_ECDSA;
|
||||
else
|
||||
{
|
||||
xfree (tokens);
|
||||
return gpg_error (GPG_ERR_INV_FLAG);
|
||||
}
|
||||
ecdh_or_ecdsa = 0;
|
||||
}
|
||||
else if (!ascii_strcasecmp (s, "ecdh"))
|
||||
{
|
||||
if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA)
|
||||
algo = PUBKEY_ALGO_ECDH;
|
||||
else
|
||||
{
|
||||
xfree (tokens);
|
||||
return gpg_error (GPG_ERR_INV_FLAG);
|
||||
}
|
||||
ecdh_or_ecdsa = 0;
|
||||
}
|
||||
else if (!ascii_strcasecmp (s, "eddsa"))
|
||||
{
|
||||
/* Not required but we allow it for consistency. */
|
||||
if (algo == PUBKEY_ALGO_EDDSA)
|
||||
;
|
||||
else
|
||||
{
|
||||
xfree (tokens);
|
||||
return gpg_error (GPG_ERR_INV_FLAG);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xfree (tokens);
|
||||
return gpg_error (GPG_ERR_UNKNOWN_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
xfree (tokens);
|
||||
}
|
||||
|
||||
/* If not yet decided switch between ecdh and ecdsa. */
|
||||
if (ecdh_or_ecdsa && keyuse)
|
||||
algo = (keyuse & PUBKEY_USAGE_ENC)? PUBKEY_ALGO_ECDH : PUBKEY_ALGO_ECDSA;
|
||||
else if (ecdh_or_ecdsa)
|
||||
algo = for_subkey? PUBKEY_ALGO_ECDH : PUBKEY_ALGO_ECDSA;
|
||||
|
||||
/* Set or fix key usage. */
|
||||
if (!keyuse)
|
||||
{
|
||||
if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA
|
||||
|| algo == PUBKEY_ALGO_DSA)
|
||||
keyuse = PUBKEY_USAGE_SIG;
|
||||
else if (algo == PUBKEY_ALGO_RSA)
|
||||
keyuse = for_subkey? PUBKEY_USAGE_ENC : PUBKEY_USAGE_SIG;
|
||||
else
|
||||
keyuse = PUBKEY_USAGE_ENC;
|
||||
}
|
||||
else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA
|
||||
|| algo == PUBKEY_ALGO_DSA)
|
||||
{
|
||||
keyuse &= ~PUBKEY_USAGE_ENC; /* Forbid encryption. */
|
||||
}
|
||||
else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ELGAMAL_E)
|
||||
{
|
||||
keyuse = PUBKEY_USAGE_ENC; /* Allow only encryption. */
|
||||
}
|
||||
|
||||
/* Make sure a primary key can certify. */
|
||||
if (!for_subkey)
|
||||
keyuse |= PUBKEY_USAGE_CERT;
|
||||
|
||||
/* Check that usage is actually possible. */
|
||||
if (/**/((keyuse & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH|PUBKEY_USAGE_CERT))
|
||||
&& !pubkey_get_nsig (algo))
|
||||
|| ((keyuse & PUBKEY_USAGE_ENC)
|
||||
&& !pubkey_get_nenc (algo))
|
||||
|| (for_subkey && (keyuse & PUBKEY_USAGE_CERT)))
|
||||
return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
|
||||
|
||||
/* Return values. */
|
||||
if (r_algo)
|
||||
*r_algo = algo;
|
||||
if (r_size)
|
||||
{
|
||||
unsigned int min, def, max;
|
||||
|
||||
/* Make sure the keysize is in the allowed range. */
|
||||
def = get_keysize_range (algo, &min, &max);
|
||||
if (!size)
|
||||
size = def;
|
||||
else if (size < min)
|
||||
size = min;
|
||||
else if (size > max)
|
||||
size = max;
|
||||
|
||||
*r_size = fixup_keysize (size, algo, 1);
|
||||
}
|
||||
if (r_keyuse)
|
||||
*r_keyuse = keyuse;
|
||||
if (r_curve)
|
||||
*r_curve = curve;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse and return the standard key generation parameter.
|
||||
* The string is expected to be in this format:
|
||||
*
|
||||
* ALGO[/FLAGS][+SUBALGO[/FLAGS]]
|
||||
*
|
||||
* Here ALGO is a string in the same format as printed by the
|
||||
* keylisting. For example:
|
||||
*
|
||||
* rsa3072 := RSA with 3072 bit.
|
||||
* dsa2048 := DSA with 2048 bit.
|
||||
* elg2048 := Elgamal with 2048 bit.
|
||||
* ed25519 := EDDSA using curve Ed25519.
|
||||
* cv25519 := ECDH using curve Curve25519.
|
||||
* nistp256:= ECDSA or ECDH using curve NIST P-256
|
||||
*
|
||||
* All strings with an unknown prefix are considered an elliptic
|
||||
* curve. Curves which have no implicit algorithm require that FLAGS
|
||||
* is given to select whether ECDSA or ECDH is used; this can eoither
|
||||
* be done using an algorithm keyword or usage keywords.
|
||||
*
|
||||
* FLAGS is a comma delimited string of keywords:
|
||||
*
|
||||
* cert := Allow usage Certify
|
||||
* sign := Allow usage Sign
|
||||
* encr := Allow usage Encrypt
|
||||
* auth := Allow usage Authentication
|
||||
* encrypt := Alias for "encr"
|
||||
* ecdsa := Use algorithm ECDSA.
|
||||
* eddsa := Use algorithm EdDSA.
|
||||
* ecdh := Use algorithm ECDH.
|
||||
*
|
||||
* There are several defaults and fallbacks depending on the
|
||||
* algorithm. PART can be used to select which part of STRING is
|
||||
* used:
|
||||
* -1 := Both parts
|
||||
* 0 := Only the part of the primary key
|
||||
* 1 := Only the part of the secondary key is parsed but returned
|
||||
* in the args for the primary key (R_ALGO,....)
|
||||
*
|
||||
*/
|
||||
gpg_error_t
|
||||
parse_key_parameter_string (const char *string, int part,
|
||||
int *r_algo, unsigned int *r_size,
|
||||
unsigned *r_keyuse,
|
||||
char const **r_curve,
|
||||
int *r_subalgo, unsigned int *r_subsize,
|
||||
unsigned *r_subkeyuse,
|
||||
char const **r_subcurve)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
char *primary, *secondary;
|
||||
|
||||
if (r_algo)
|
||||
*r_algo = 0;
|
||||
if (r_size)
|
||||
*r_size = 0;
|
||||
if (r_keyuse)
|
||||
*r_keyuse = 0;
|
||||
if (r_curve)
|
||||
*r_curve = NULL;
|
||||
if (r_subalgo)
|
||||
*r_subalgo = 0;
|
||||
if (r_subsize)
|
||||
*r_subsize = 0;
|
||||
if (r_subkeyuse)
|
||||
*r_subkeyuse = 0;
|
||||
if (r_subcurve)
|
||||
*r_subcurve = NULL;
|
||||
|
||||
if (!string || !*string
|
||||
|| !strcmp (string, "default") || !strcmp (string, "-"))
|
||||
string = opt.def_new_key_algo? opt.def_new_key_algo : DEFAULT_STD_KEY_PARAM;
|
||||
else if (!strcmp (string, "future-default"))
|
||||
string = FUTURE_STD_KEY_PARAM;
|
||||
|
||||
primary = xstrdup (string);
|
||||
secondary = strchr (primary, '+');
|
||||
if (secondary)
|
||||
*secondary++ = 0;
|
||||
if (part == -1 || part == 0)
|
||||
{
|
||||
err = parse_key_parameter_part (primary, 0, r_algo, r_size,
|
||||
r_keyuse, r_curve);
|
||||
if (!err && part == -1)
|
||||
err = parse_key_parameter_part (secondary, 1, r_subalgo, r_subsize,
|
||||
r_subkeyuse, r_subcurve);
|
||||
}
|
||||
else if (part == 1)
|
||||
{
|
||||
err = parse_key_parameter_part (secondary, 1, r_algo, r_size,
|
||||
r_keyuse, r_curve);
|
||||
}
|
||||
|
||||
xfree (primary);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Append R to the linked list PARA. */
|
||||
static void
|
||||
append_to_parameter (struct para_data_s *para, struct para_data_s *r)
|
||||
@ -2926,8 +3212,15 @@ get_parameter_algo( struct para_data_s *para, enum para_name key,
|
||||
if (!ascii_strcasecmp (r->u.value, "default"))
|
||||
{
|
||||
/* Note: If you change this default algo, remember to change it
|
||||
also in gpg.c:gpgconf_list. */
|
||||
i = DEFAULT_STD_ALGO;
|
||||
* also in gpg.c:gpgconf_list. */
|
||||
/* FIXME: We only allow the algo here and have a separate thing
|
||||
* for the curve etc. That is a ugly but demanded for backward
|
||||
* compatibility with the batch key generation. It would be
|
||||
* better to make full use of parse_key_parameter_string. */
|
||||
parse_key_parameter_string (NULL, 0,
|
||||
&i, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
|
||||
if (r_default)
|
||||
*r_default = 1;
|
||||
}
|
||||
@ -2952,8 +3245,8 @@ get_parameter_algo( struct para_data_s *para, enum para_name key,
|
||||
|
||||
|
||||
/* Parse a usage string. The usage keywords "auth", "sign", "encr"
|
||||
* may be elimited by space, tab, or comma. On error -1 is returned
|
||||
* instead of the usage flags/ */
|
||||
* may be delimited by space, tab, or comma. On error -1 is returned
|
||||
* instead of the usage flags. */
|
||||
static int
|
||||
parse_usagestr (const char *usagestr)
|
||||
{
|
||||
@ -3639,25 +3932,27 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
|
||||
&& (!*usagestr || !strcmp (usagestr, "default")
|
||||
|| !strcmp (usagestr, "-")))
|
||||
{
|
||||
if (!strcmp (algostr, "future-default"))
|
||||
/* Use default key parameters. */
|
||||
int algo, subalgo;
|
||||
unsigned int size, subsize;
|
||||
unsigned int keyuse, subkeyuse;
|
||||
const char *curve, *subcurve;
|
||||
|
||||
err = parse_key_parameter_string (algostr, -1,
|
||||
&algo, &size, &keyuse, &curve,
|
||||
&subalgo, &subsize, &subkeyuse,
|
||||
&subcurve);
|
||||
if (err)
|
||||
{
|
||||
para = quickgen_set_para (para, 0,
|
||||
FUTURE_STD_ALGO, FUTURE_STD_KEYSIZE,
|
||||
FUTURE_STD_CURVE, 0);
|
||||
para = quickgen_set_para (para, 1,
|
||||
FUTURE_STD_SUBALGO, FUTURE_STD_SUBKEYSIZE,
|
||||
FUTURE_STD_SUBCURVE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
para = quickgen_set_para (para, 0,
|
||||
DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE,
|
||||
DEFAULT_STD_CURVE, 0);
|
||||
para = quickgen_set_para (para, 1,
|
||||
DEFAULT_STD_SUBALGO, DEFAULT_STD_SUBKEYSIZE,
|
||||
DEFAULT_STD_SUBCURVE, 0);
|
||||
log_error (_("Key generation failed: %s\n"), gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
para = quickgen_set_para (para, 0, algo, size, curve, keyuse);
|
||||
if (subalgo)
|
||||
para = quickgen_set_para (para, 1,
|
||||
subalgo, subsize, subcurve, subkeyuse);
|
||||
|
||||
if (*expirestr)
|
||||
{
|
||||
u32 expire;
|
||||
@ -3736,6 +4031,7 @@ void
|
||||
generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
||||
const char *card_serialno, int card_backup_key)
|
||||
{
|
||||
gpg_error_t err;
|
||||
unsigned int nbits;
|
||||
char *uid = NULL;
|
||||
int algo;
|
||||
@ -3768,14 +4064,14 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
||||
if (card_serialno)
|
||||
{
|
||||
#ifdef ENABLE_CARD_SUPPORT
|
||||
gpg_error_t err;
|
||||
struct agent_card_info_s info;
|
||||
|
||||
memset (&info, 0, sizeof (info));
|
||||
err = agent_scd_getattr ("KEY-ATTR", &info);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("error getting current key info: %s\n"), gpg_strerror (err));
|
||||
log_error (_("error getting current key info: %s\n"),
|
||||
gpg_strerror (err));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3978,6 +4274,11 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
||||
}
|
||||
else /* Default key generation. */
|
||||
{
|
||||
int subalgo;
|
||||
unsigned int size, subsize;
|
||||
unsigned int keyuse, subkeyuse;
|
||||
const char *curve, *subcurve;
|
||||
|
||||
tty_printf ( _("Note: Use \"%s %s\""
|
||||
" for a full featured key generation dialog.\n"),
|
||||
#if USE_GPG2_HACK
|
||||
@ -3986,12 +4287,22 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
||||
GPG_NAME
|
||||
#endif
|
||||
, "--full-gen-key" );
|
||||
para = quickgen_set_para (para, 0,
|
||||
DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE,
|
||||
DEFAULT_STD_CURVE, 0);
|
||||
para = quickgen_set_para (para, 1,
|
||||
DEFAULT_STD_SUBALGO, DEFAULT_STD_SUBKEYSIZE,
|
||||
DEFAULT_STD_SUBCURVE, 0);
|
||||
|
||||
err = parse_key_parameter_string (NULL, -1,
|
||||
&algo, &size, &keyuse, &curve,
|
||||
&subalgo, &subsize,
|
||||
&subkeyuse, &subcurve);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("Key generation failed: %s\n"), gpg_strerror (err));
|
||||
return;
|
||||
}
|
||||
para = quickgen_set_para (para, 0, algo, size, curve, keyuse);
|
||||
if (subalgo)
|
||||
para = quickgen_set_para (para, 1,
|
||||
subalgo, subsize, subcurve, subkeyuse);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -4479,87 +4790,38 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
|
||||
int *r_algo, unsigned int *r_usage, u32 *r_expire,
|
||||
unsigned int *r_nbits, char **r_curve)
|
||||
{
|
||||
gpg_error_t err;
|
||||
int algo;
|
||||
unsigned int use, nbits;
|
||||
u32 expire;
|
||||
int wantuse;
|
||||
unsigned int min, def, max;
|
||||
const char *curve = NULL;
|
||||
int eccalgo = 0;
|
||||
|
||||
*r_curve = NULL;
|
||||
|
||||
nbits = 0;
|
||||
|
||||
/* Parse the algo string. */
|
||||
if (!algostr || !*algostr
|
||||
|| !strcmp (algostr, "default") || !strcmp (algostr, "-"))
|
||||
{
|
||||
algo = for_subkey? DEFAULT_STD_SUBALGO : DEFAULT_STD_ALGO;
|
||||
use = for_subkey? DEFAULT_STD_SUBKEYUSE : DEFAULT_STD_KEYUSE;
|
||||
nbits = for_subkey? DEFAULT_STD_SUBKEYSIZE : DEFAULT_STD_KEYSIZE;
|
||||
curve = for_subkey? DEFAULT_STD_SUBCURVE : DEFAULT_STD_CURVE;
|
||||
}
|
||||
else if (!strcmp (algostr, "future-default"))
|
||||
{
|
||||
algo = for_subkey? FUTURE_STD_SUBALGO : FUTURE_STD_ALGO;
|
||||
use = for_subkey? FUTURE_STD_SUBKEYUSE : FUTURE_STD_KEYUSE;
|
||||
nbits = for_subkey? FUTURE_STD_SUBKEYSIZE : FUTURE_STD_KEYSIZE;
|
||||
curve = for_subkey? FUTURE_STD_SUBCURVE : FUTURE_STD_CURVE;
|
||||
}
|
||||
else if (*algostr == '&' && strlen (algostr) == 41)
|
||||
if (algostr && *algostr == '&' && strlen (algostr) == 41)
|
||||
{
|
||||
/* Take algo from existing key. */
|
||||
algo = check_keygrip (ctrl, algostr+1);
|
||||
/* FIXME: We need the curve name as well. */
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
}
|
||||
else if (!strncmp (algostr, "rsa", 3))
|
||||
{
|
||||
algo = PUBKEY_ALGO_RSA;
|
||||
use = for_subkey? DEFAULT_STD_SUBKEYUSE : DEFAULT_STD_KEYUSE;
|
||||
if (algostr[3])
|
||||
nbits = atoi (algostr + 3);
|
||||
}
|
||||
else if (!strncmp (algostr, "elg", 3))
|
||||
{
|
||||
algo = PUBKEY_ALGO_ELGAMAL_E;
|
||||
use = PUBKEY_USAGE_ENC;
|
||||
if (algostr[3])
|
||||
nbits = atoi (algostr + 3);
|
||||
}
|
||||
else if (!strncmp (algostr, "dsa", 3))
|
||||
{
|
||||
algo = PUBKEY_ALGO_DSA;
|
||||
use = PUBKEY_USAGE_SIG;
|
||||
if (algostr[3])
|
||||
nbits = atoi (algostr + 3);
|
||||
}
|
||||
else if ((curve = openpgp_is_curve_supported (algostr, &algo)))
|
||||
{
|
||||
if (!algo)
|
||||
{
|
||||
algo = PUBKEY_ALGO_ECDH; /* Default ECC algorithm. */
|
||||
eccalgo = 1; /* Remember - we may need to fix it up. */
|
||||
}
|
||||
|
||||
if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA)
|
||||
use = PUBKEY_USAGE_SIG;
|
||||
else
|
||||
use = PUBKEY_USAGE_ENC;
|
||||
}
|
||||
else
|
||||
return gpg_error (GPG_ERR_UNKNOWN_CURVE);
|
||||
err = parse_key_parameter_string (algostr, for_subkey? 1 : 0,
|
||||
&algo, &nbits, &use, &curve,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Parse the usage string. */
|
||||
if (!usagestr || !*usagestr
|
||||
|| !strcmp (usagestr, "default") || !strcmp (usagestr, "-"))
|
||||
; /* Keep default usage */
|
||||
; /* Keep usage from parse_key_parameter_string. */
|
||||
else if ((wantuse = parse_usagestr (usagestr)) != -1)
|
||||
{
|
||||
use = wantuse;
|
||||
if (eccalgo && !(use & PUBKEY_USAGE_ENC))
|
||||
algo = PUBKEY_ALGO_ECDSA; /* Switch from ECDH to ECDSA. */
|
||||
}
|
||||
use = wantuse;
|
||||
else
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
@ -4567,7 +4829,9 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
|
||||
if (!for_subkey)
|
||||
use |= PUBKEY_USAGE_CERT;
|
||||
|
||||
/* Check that usage is possible. */
|
||||
/* Check that usage is possible. NB: We have the same check in
|
||||
* parse_key_parameter_string but need it here again in case the
|
||||
* separate usage value has been given. */
|
||||
if (/**/((use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH|PUBKEY_USAGE_CERT))
|
||||
&& !pubkey_get_nsig (algo))
|
||||
|| ((use & PUBKEY_USAGE_ENC)
|
||||
@ -4580,17 +4844,6 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
|
||||
if (expire == (u32)-1 )
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
/* Make sure the keysize is in the allowed range. */
|
||||
get_keysize_range (algo, &min, &def, &max);
|
||||
if (!nbits)
|
||||
nbits = def;
|
||||
else if (nbits < min)
|
||||
nbits = min;
|
||||
else if (nbits > max)
|
||||
nbits = max;
|
||||
|
||||
nbits = fixup_keysize (nbits, algo, 1);
|
||||
|
||||
if (curve)
|
||||
{
|
||||
*r_curve = xtrystrdup (curve);
|
||||
|
@ -120,6 +120,8 @@ struct
|
||||
const char *agent_program;
|
||||
const char *dirmngr_program;
|
||||
|
||||
const char *def_new_key_algo;
|
||||
|
||||
/* Options to be passed to the gpg-agent */
|
||||
session_env_t session_env;
|
||||
char *lc_ctype;
|
||||
|
@ -3454,7 +3454,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
|
||||
|
||||
memcpy (curve_name, tok, toklen);
|
||||
curve_name[toklen] = 0;
|
||||
curve = openpgp_is_curve_supported (curve_name, NULL);
|
||||
curve = openpgp_is_curve_supported (curve_name, NULL, NULL);
|
||||
xfree (curve_name);
|
||||
}
|
||||
else if (tok && toklen == 5 && !memcmp (tok, "flags", 5))
|
||||
|
Loading…
x
Reference in New Issue
Block a user