On 5/29/19 10:19 AM, Renaud Allard wrote:
On 5/29/19 9:58 AM, Florian Obser wrote:On Wed, May 22, 2019 at 01:33:11PM +0200, Renaud Allard wrote:The key needs to be generated manually i.e.: openssl ecparam -genkey -name secp384r1 -out privkey.pemwhy not let acme-client generate the key?
Here is a more complete diff where you can use the -D switch to generate a ECDSA key instead of the RSA one.
Index: acme-client.1 =================================================================== RCS file: /cvs/src/usr.sbin/acme-client/acme-client.1,v retrieving revision 1.29 diff -u -p -r1.29 acme-client.1 --- acme-client.1 3 Feb 2019 20:39:35 -0000 1.29 +++ acme-client.1 3 Jun 2019 09:13:54 -0000 @@ -79,7 +79,9 @@ The options are as follows: .It Fl A Create a new RSA account key if one does not already exist. .It Fl D -Create a new RSA domain key if one does not already exist. +Create a new (RSA) domain key if one does not already exist. +.It Fl E +Switch the new domain key algorithm to ECDSA instead of RSA. .It Fl F Force certificate renewal, even if it's too soon. .It Fl f Ar configfile Index: ecdsa.h =================================================================== RCS file: ecdsa.h diff -N ecdsa.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ecdsa.h 3 Jun 2019 09:13:54 -0000 @@ -0,0 +1,22 @@ +/* $Id: rsa.h,v 1.1 2016/08/31 22:01:42 florian Exp $ */ +/* + * Copyright (c) 2019 Renaud Allard <ren...@allard.it> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef ECDSA_H +#define ECDSA_H + +EVP_PKEY *ec_key_create(FILE *, const char *); + +#endif /* ! ECDSA_H */ Index: extern.h =================================================================== RCS file: /cvs/src/usr.sbin/acme-client/extern.h,v retrieving revision 1.10 diff -u -p -r1.10 extern.h --- extern.h 31 Jan 2019 15:55:48 -0000 1.10 +++ extern.h 3 Jun 2019 09:13:54 -0000 @@ -18,6 +18,7 @@ #define EXTERN_H #include "parse.h" +#include "stdbool.h" #define MAX_SERVERS_DNS 8 @@ -252,6 +253,11 @@ char *json_fmt_signed(const char *, * Should we print debugging messages? */ int verbose; + +/* + * Should we switch to ecdsa? + */ +bool ecdsa; /* * What component is the process within (COMP__MAX for none)? Index: keyproc.c =================================================================== RCS file: /cvs/src/usr.sbin/acme-client/keyproc.c,v retrieving revision 1.11 diff -u -p -r1.11 keyproc.c --- keyproc.c 29 Jul 2018 20:22:02 -0000 1.11 +++ keyproc.c 3 Jun 2019 09:13:55 -0000 @@ -31,6 +31,7 @@ #include "extern.h" #include "rsa.h" +#include "ecdsa.h" /* * This was lifted more or less directly from demos/x509/mkreq.c of the @@ -114,9 +115,15 @@ keyproc(int netsock, const char *keyfile } if (newkey) { - if ((pkey = rsa_key_create(f, keyfile)) == NULL) - goto out; - dodbg("%s: generated RSA domain key", keyfile); + if (ecdsa) { + if ((pkey = ec_key_create(f, keyfile)) == NULL) + goto out; + dodbg("%s: generated ECDSA domain key", keyfile); + } else { + if ((pkey = rsa_key_create(f, keyfile)) == NULL) + goto out; + dodbg("%s: generated RSA domain key", keyfile); + } } else { if ((pkey = rsa_key_load(f, keyfile)) == NULL) goto out; Index: main.c =================================================================== RCS file: /cvs/src/usr.sbin/acme-client/main.c,v retrieving revision 1.45 diff -u -p -r1.45 main.c --- main.c 9 Mar 2019 18:07:40 -0000 1.45 +++ main.c 3 Jun 2019 09:13:55 -0000 @@ -49,6 +49,7 @@ main(int argc, char *argv[]) int popts = 0; pid_t pids[COMP__MAX]; extern int verbose; + extern bool ecdsa; extern enum comp proccomp; size_t i, altsz, ne; @@ -57,7 +58,7 @@ main(int argc, char *argv[]) struct domain_c *domain = NULL; struct altname_c *ac; - while ((c = getopt(argc, argv, "ADFnrvf:")) != -1) + while ((c = getopt(argc, argv, "ADEFnrvf:")) != -1) switch (c) { case 'A': popts |= ACME_OPT_NEWACCT; @@ -65,6 +66,10 @@ main(int argc, char *argv[]) case 'D': popts |= ACME_OPT_NEWDKEY; break; + case 'E': + ecdsa = true; + popts |= ACME_OPT_DKEYEC; + break; case 'F': force = 1; break; @@ -180,6 +185,10 @@ main(int argc, char *argv[]) != -1) { dodbg("%s: domain key exists (not creating)", domain->key); popts &= ~ACME_OPT_NEWDKEY; + } + + if (popts & ACME_OPT_DKEYEC) { + ecdsa = true; } if (access(chngdir, R_OK) == -1) { Index: parse.h =================================================================== RCS file: /cvs/src/usr.sbin/acme-client/parse.h,v retrieving revision 1.9 diff -u -p -r1.9 parse.h --- parse.h 27 Nov 2017 16:53:04 -0000 1.9 +++ parse.h 3 Jun 2019 09:13:55 -0000 @@ -61,6 +61,7 @@ struct keyfile { #define ACME_OPT_NEWACCT 0x00000002 #define ACME_OPT_NEWDKEY 0x00000004 #define ACME_OPT_CHECK 0x00000008 +#define ACME_OPT_DKEYEC 0x00000016 struct acme_conf { int opts; Index: rsa.c =================================================================== RCS file: /cvs/src/usr.sbin/acme-client/rsa.c,v retrieving revision 1.7 diff -u -p -r1.7 rsa.c --- rsa.c 28 Jul 2018 15:25:23 -0000 1.7 +++ rsa.c 3 Jun 2019 09:13:55 -0000 @@ -1,5 +1,6 @@ /* $Id: rsa.c,v 1.7 2018/07/28 15:25:23 tb Exp $ */ /* + * Copyright (c) 2019 Renaud Allard <ren...@allard.it> * Copyright (c) 2016 Kristaps Dzonsons <krist...@bsd.lv> * * Permission to use, copy, modify, and distribute this software for any @@ -22,13 +23,18 @@ #include <openssl/evp.h> #include <openssl/pem.h> #include <openssl/rsa.h> +#include <openssl/ecdsa.h> +#include <openssl/ec.h> +#include <openssl/obj_mac.h> #include "rsa.h" +#include "ecdsa.h" /* - * Default number of bits when creating a new key. + * Default number of bits when creating a new RSA key. */ #define KBITS 4096 +#define ECCTYPE NID_secp384r1 /* * Create an RSA key with the default KBITS number of bits. @@ -61,6 +67,7 @@ rsa_key_create(FILE *f, const char *fnam goto out; warnx("%s: PEM_write_PrivateKey", fname); + err: EVP_PKEY_free(pkey); pkey = NULL; @@ -69,6 +76,60 @@ out: return pkey; } +EVP_PKEY * +ec_key_create(FILE *f, const char *fname) +{ + EC_KEY *eckey = NULL; + EVP_PKEY *pkey = NULL; + + if ((eckey = EC_KEY_new()) == NULL ) { + warnx("EC_KEY_new"); + goto err; + } else if ((eckey = EC_KEY_new_by_curve_name(ECCTYPE)) == NULL ) { + warnx("EC_GROUP_new_by_curve_name"); + goto err; + } + + if (!EC_KEY_generate_key(eckey)) { + warnx("EC_KEY_generate_key"); + goto err; + } + + /* set OPENSSL_EC_NAMED_CURVE to be able to load the key */ + + EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE); + + /* Serialise the key to the disc in EC format */ + + if (!PEM_write_ECPrivateKey(f, eckey, NULL, NULL, 0, NULL, NULL)) { + warnx("PEM_write_ECPrivateKey"); + goto err; + } + + /* Convert the EC key into a PKEY structure */ + + if ((pkey=EVP_PKEY_new()) == NULL) { + warnx("EVP_PKEY_new"); + goto err; + } + if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { + warnx("EVP_PKEY_assign_EC_KEY"); + goto err; + } + + goto out; + + warnx("%s: PEM_write_ECPrivateKey", fname); + +err: + EC_KEY_free(eckey); + EVP_PKEY_free(pkey); + pkey = NULL; +out: + return pkey; +} + + EVP_PKEY * rsa_key_load(FILE *f, const char *fname) @@ -79,7 +140,8 @@ rsa_key_load(FILE *f, const char *fname) if (pkey == NULL) { warnx("%s: PEM_read_PrivateKey", fname); return NULL; - } else if (EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA) + } else if (EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA || + EVP_PKEY_type(pkey->type) == EVP_PKEY_EC ) return pkey; warnx("%s: unsupported key type", fname);
smime.p7s
Description: S/MIME Cryptographic Signature