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.pem

why 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);

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to