From 288ea30c4962f301046e68ebfee23e5f00c43d74 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Apr 13 2017 13:51:54 +0000 Subject: Provide option to specify the EC curve, add EC default key size The default RSA key size is 2048 which wasn't translated into an equivalent EC key size which resulted in always using the 521-bit curve. Add an EC default key size of 256 as a correlation to the RSA default (without adding a new curve). The new option will allow one to specify the supported EC curves. https://pagure.io/certmonger/issue/73 Signed-off-by: Rob Crittenden --- diff --git a/configure.ac b/configure.ac index c1d37d9..9512213 100644 --- a/configure.ac +++ b/configure.ac @@ -699,8 +699,11 @@ if ! ${configure_dist_target_only:-false} ; then AC_DEFINE_UNQUOTED(CM_DEFAULT_RSA_EXPONENT,0x10001,[Define to the default RSA key exponent.]) AC_DEFINE_UNQUOTED(CM_DIGEST_MAX,(512/8),[Define to the maximum size (in bytes) of supported digests.]) CM_DEFAULT_PUBKEY_SIZE=2048 + CM_DEFAULT_EC_PUBKEY_SIZE=256 AC_DEFINE_UNQUOTED(CM_DEFAULT_PUBKEY_SIZE,$CM_DEFAULT_PUBKEY_SIZE,[Define to the default public key size.]) + AC_DEFINE_UNQUOTED(CM_DEFAULT_EC_PUBKEY_SIZE,$CM_DEFAULT_EC_PUBKEY_SIZE,[Define to the default EC public key size.]) AC_SUBST(CM_DEFAULT_PUBKEY_SIZE) + AC_SUBST(CM_DEFAULT_EC_PUBKEY_SIZE) CM_MINIMUM_RSA_KEY_SIZE=512 CM_MINIMUM_DSA_KEY_SIZE=512 CM_MINIMUM_EC_KEY_SIZE=256 diff --git a/src/getcert-request.1.in b/src/getcert-request.1.in index ed9dd6a..ff0ce2e 100644 --- a/src/getcert-request.1.in +++ b/src/getcert-request.1.in @@ -61,7 +61,8 @@ type of the keys to be generated. If not specified, a reasonable default \fB\-g\fR BITS In case a new key pair needs to be generated, this option specifies the size of the key. If not specified, a reasonable default (currently -@CM_DEFAULT_PUBKEY_SIZE@ bits) will be used. +@CM_DEFAULT_PUBKEY_SIZE@ bits for RSA, @CM_DEFAULT_EC_PUBKEY_SIZE bits for EC) +will be used. .SH TRACKING OPTIONS .TP diff --git a/src/getcert.c b/src/getcert.c index 36edeb6..065f6c8 100644 --- a/src/getcert.c +++ b/src/getcert.c @@ -746,6 +746,7 @@ request(const char *argv0, int argc, const char **argv) char **anchor_dbs = NULL, **anchor_files = NULL; char *pin = NULL, *pinfile = NULL, *cpass = NULL, *cpassfile = NULL; int keysize = 0, auto_renew = 1, verbose = 0, ku = 0, kubit, c, i, j; + int ec_curve = 0; char *ca = DEFAULT_CA, *subject = NULL, **eku = NULL, *oid, *id = NULL; char *profile = NULL, *issuer = NULL, kustring[16]; char **principal = NULL, **dns = NULL, **email = NULL, **ipaddr = NULL; @@ -783,6 +784,9 @@ request(const char *argv0, int argc, const char **argv) {"id", 'I', POPT_ARG_STRING, NULL, 'I', _("nickname to assign to the request"), HELP_TYPE_ID}, {"key-type", 'G', POPT_ARG_STRING, NULL, 'G', _("type of key to be generated if one is not already in place"), NULL}, {"key-size", 'g', POPT_ARG_STRING, NULL, 'g', _("size of key to be generated if one is not already in place"), HELP_TYPE_KEYSIZE}, +#ifdef CM_ENABLE_EC + {"ec-curve", 'V', POPT_ARG_STRING, NULL, 'V', _("EC curve to use for key if one is not already in place"), NULL}, +#endif {"renew", 'r', POPT_ARG_NONE, NULL, 'r', _("attempt to renew the certificate when expiration nears (default)"), NULL}, {"no-renew", 'R', POPT_ARG_NONE, NULL, 'R', _("don't attempt to renew the certificate when expiration nears"), NULL}, #ifndef FORCE_CA @@ -902,8 +906,33 @@ request(const char *argv0, int argc, const char **argv) keytype = talloc_strdup(globals.tctx, poptarg); break; case 'g': + if (ec_curve) { + printf(_("Use only one of -g and -V\n")); + return 1; + } keysize = atoi(poptarg); break; +#ifdef CM_ENABLE_EC + case 'V': + if (keysize) { + printf(_("Use only one of -g and -V\n")); + return 1; + } + if (strcasecmp(poptarg, "secp256r1") == 0) + keysize = 256; + else if (strcasecmp(poptarg, "secp384r1") == 0) + keysize = 384; + else if (strcasecmp(poptarg, "secp521r1") == 0) + keysize = 521; + else { + printf(_("No support for curve \"%s\"\n"), + poptarg); + printf(_("Supported curves:")); + printf(" secp256r1, secp384r1, secp521r1\n"); + return 1; + } + break; +#endif case 'I': id = talloc_strdup(globals.tctx, poptarg); break; @@ -2486,6 +2515,7 @@ rekey_or_resubmit(const char *argv0, const char *category, int argc, char *cert_owner = NULL, *cert_perms = NULL; char *keytype = NULL; int keysize = 0; + int ec_curve = 0; dbus_bool_t b; char *p; int verbose = 0, ku = 0, kubit, c, i, j, waitreq = 0, timeout = -1; @@ -2505,6 +2535,7 @@ rekey_or_resubmit(const char *argv0, const char *category, int argc, {"new-id", 'I', POPT_ARG_STRING, NULL, 'I', _("new nickname to give to tracking request"), HELP_TYPE_ID}, {"key-type", 'G', POPT_ARG_STRING, NULL, 'G', _("type of new key to be generated"), NULL}, {"key-size", 'g', POPT_ARG_STRING, NULL, 'g', _("size of new key to be generated"), HELP_TYPE_KEYSIZE}, + {"ec-curve", 'V', POPT_ARG_STRING, NULL, 'V', _("EC curve for new key to be generated"), NULL}, {"pinfile", 'p', POPT_ARG_STRING, NULL, 'p', _("file which holds the private key encryption PIN"), HELP_TYPE_FILENAME}, {"pin", 'P', POPT_ARG_STRING, NULL, 'P', _("private key encryption PIN"), NULL}, {"key-owner", 'o', POPT_ARG_STRING, NULL, 'o', _("owner information for private key"), HELP_TYPE_USER}, @@ -2632,8 +2663,35 @@ rekey_or_resubmit(const char *argv0, const char *category, int argc, keytype = talloc_strdup(globals.tctx, poptarg); break; case 'g': +#ifdef CM_ENABLE_EC + if (ec_curve) { + printf(_("Use only one of -g and -V\n")); + return 1; + } +#endif keysize = atoi(poptarg); break; +#ifdef CM_ENABLE_EC + case 'V': + if (keysize) { + printf(_("Use only one of -g and -V\n")); + return 1; + } + if (strcasecmp(poptarg, "secp256r1") == 0) + keysize = 256; + else if (strcasecmp(poptarg, "secp384r1") == 0) + keysize = 384; + else if (strcasecmp(poptarg, "secp521r1") == 0) + keysize = 521; + else { + printf(_("No support for curve \"%s\"\n"), + poptarg); + printf(_("Supported curves:")); + printf(" secp256r1, secp384r1, secp521r1\n"); + return 1; + } + break; +#endif case 'N': subject = talloc_strdup(globals.tctx, poptarg); break; @@ -4807,6 +4865,9 @@ help(const char *twopartcmd, const char *category) N_(" -I NAME nickname to assign to the request\n"), N_(" -G TYPE type of key to be generated if one is not already in place\n"), N_(" -g SIZE size of key to be generated if one is not already in place\n"), +#ifdef CM_ENABLE_EC + N_(" -V CURVE EC curve to use for key if one is not already in place\n"), +#endif N_(" -r attempt to renew the certificate when expiration nears (default)\n"), N_(" -R don't attempt to renew the certificate when expiration nears\n"), #ifndef FORCE_CA diff --git a/src/keygen-n.c b/src/keygen-n.c index 08f0049..b1b69ce 100644 --- a/src/keygen-n.c +++ b/src/keygen-n.c @@ -234,7 +234,12 @@ cm_keygen_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, } cm_requested_key_size = entry->cm_key_type.cm_key_gen_size; if (cm_requested_key_size <= 0) { - cm_requested_key_size = CM_DEFAULT_PUBKEY_SIZE; +#ifdef CM_ENABLE_EC + if (cm_key_algorithm == cm_key_ecdsa) + cm_requested_key_size = CM_DEFAULT_EC_PUBKEY_SIZE; + else +#endif + cm_requested_key_size = CM_DEFAULT_PUBKEY_SIZE; } /* Convert our key type to a mechanism. */ switch (cm_key_algorithm) { @@ -407,6 +412,11 @@ next_slot: } /* Select an initial key size. */ if (cm_requested_key_size == 0) { +#ifdef CM_ENABLE_EC + if (cm_key_algorithm == cm_key_ecdsa) + cm_requested_key_size = CM_DEFAULT_EC_PUBKEY_SIZE; + else +#endif cm_requested_key_size = CM_DEFAULT_PUBKEY_SIZE; } cm_key_size = cm_requested_key_size;