On 6/11/19 10:17 AM, Renaud Allard wrote:

Hello,

Here is a patch with ecdsa and rsa in %token after the domain key name

OK? comments?

I just made a small modification in the formatting of acme.conf man page, putting keytype as an arg. And also a cleaner key.h

OK?
Index: Makefile
===================================================================
RCS file: /cvs/src/usr.sbin/acme-client/Makefile,v
retrieving revision 1.8
diff -u -p -r1.8 Makefile
--- Makefile	3 Jul 2017 22:21:47 -0000	1.8
+++ Makefile	11 Jun 2019 11:35:24 -0000
@@ -2,7 +2,7 @@
 PROG=		acme-client
 SRCS=		acctproc.c base64.c certproc.c chngproc.c dbg.c dnsproc.c
 SRCS+=		fileproc.c http.c jsmn.c json.c keyproc.c main.c netproc.c
-SRCS+=		parse.y revokeproc.c rsa.c util.c
+SRCS+=		parse.y revokeproc.c key.c util.c
 
 MAN=		acme-client.1 acme-client.conf.5
 
Index: acctproc.c
===================================================================
RCS file: /cvs/src/usr.sbin/acme-client/acctproc.c,v
retrieving revision 1.14
diff -u -p -r1.14 acctproc.c
--- acctproc.c	8 Jun 2019 07:52:55 -0000	1.14
+++ acctproc.c	11 Jun 2019 11:35:24 -0000
@@ -29,7 +29,7 @@
 #include <openssl/err.h>
 
 #include "extern.h"
-#include "rsa.h"
+#include "key.h"
 
 /*
  * Converts a BIGNUM to the form used in JWK.
@@ -352,7 +352,9 @@ acctproc(int netsock, const char *acctke
 			goto out;
 		dodbg("%s: generated RSA account key", acctkey);
 	} else {
-		if ((pkey = rsa_key_load(f, acctkey)) == NULL)
+		if ((pkey = key_load(f, acctkey)) == NULL)
+			goto out;
+		if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) 
 			goto out;
 		doddbg("%s: loaded RSA account key", acctkey);
 	}
Index: acme-client.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/acme-client/acme-client.conf.5,v
retrieving revision 1.17
diff -u -p -r1.17 acme-client.conf.5
--- acme-client.conf.5	8 Jan 2019 06:46:29 -0000	1.17
+++ acme-client.conf.5	11 Jun 2019 11:35:24 -0000
@@ -109,8 +109,10 @@ Specify a list of alternative names for 
 The common name is included automatically if this option is present,
 but there is no automatic conversion/inclusion between "www." and
 plain domain name forms.
-.It Ic domain key Ar file
+.It Ic domain key Ar file Op Ar keytype
 The private key file for which the certificate will be obtained.
+.Ar keytype
+can be rsa or ecdsa. Defaults to rsa.
 .It Ic domain certificate Ar file
 The filename of the certificate that will be issued.
 This is optional if
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/acme-client/extern.h,v
retrieving revision 1.12
diff -u -p -r1.12 extern.h
--- extern.h	8 Jun 2019 07:52:55 -0000	1.12
+++ extern.h	11 Jun 2019 11:35:24 -0000
@@ -276,6 +276,11 @@ char		*json_fmt_signed(const char *, con
 int		 verbose;
 
 /*
+ * Should we switch to ecdsa?
+ */
+int		ecdsa;
+
+/*
  * What component is the process within (COMP__MAX for none)?
  */
 enum comp	 proccomp;
Index: key.c
===================================================================
RCS file: key.c
diff -N key.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ key.c	11 Jun 2019 11:35:24 -0000
@@ -0,0 +1,149 @@
+/*	$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
+ * 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.
+ */
+
+#include <err.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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 "key.h"
+
+/*
+ * 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.
+ */
+EVP_PKEY *
+rsa_key_create(FILE *f, const char *fname)
+{
+	EVP_PKEY_CTX	*ctx = NULL;
+	EVP_PKEY	*pkey = NULL;
+
+	/* First, create the context and the key. */
+
+	if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) {
+		warnx("EVP_PKEY_CTX_new_id");
+		goto err;
+	} else if (EVP_PKEY_keygen_init(ctx) <= 0) {
+		warnx("EVP_PKEY_keygen_init");
+		goto err;
+	} else if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, KBITS) <= 0) {
+		warnx("EVP_PKEY_set_rsa_keygen_bits");
+		goto err;
+	} else if (EVP_PKEY_keygen(ctx, &pkey) <= 0) {
+		warnx("EVP_PKEY_keygen");
+		goto err;
+	}
+
+	/* Serialise the key to the disc. */
+
+	if (PEM_write_PrivateKey(f, pkey, NULL, NULL, 0, NULL, NULL))
+		goto out;
+
+	warnx("%s: PEM_write_PrivateKey", fname);
+
+err:
+	EVP_PKEY_free(pkey);
+	pkey = NULL;
+out:
+	EVP_PKEY_CTX_free(ctx);
+	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;
+	}
+
+	warnx("%s: PEM_write_ECPrivateKey", fname);
+
+	goto out;
+
+err:
+	EC_KEY_free(eckey);
+	EVP_PKEY_free(pkey);
+	pkey = NULL;
+out:
+	return pkey;
+}
+
+
+
+EVP_PKEY *
+key_load(FILE *f, const char *fname)
+{
+	EVP_PKEY	*pkey;
+
+	pkey = PEM_read_PrivateKey(f, NULL, NULL, NULL);
+	if (pkey == NULL) {
+		warnx("%s: PEM_read_PrivateKey", fname);
+		return NULL;
+	} 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);
+	EVP_PKEY_free(pkey);
+	return NULL;
+}
Index: key.h
===================================================================
RCS file: key.h
diff -N key.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ key.h	11 Jun 2019 11:35:24 -0000
@@ -0,0 +1,25 @@
+/*	$Id: rsa.h,v 1.1 2016/08/31 22:01:42 florian 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
+ * 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 KEY_H
+#define KEY_H
+
+EVP_PKEY	*rsa_key_create(FILE *, const char *);
+EVP_PKEY	*ec_key_create(FILE *, const char *);
+EVP_PKEY	*key_load(FILE *, const char *);
+
+#endif /* ! KEY_H */
Index: keyproc.c
===================================================================
RCS file: /cvs/src/usr.sbin/acme-client/keyproc.c,v
retrieving revision 1.12
diff -u -p -r1.12 keyproc.c
--- keyproc.c	8 Jun 2019 07:52:55 -0000	1.12
+++ keyproc.c	11 Jun 2019 11:35:25 -0000
@@ -30,7 +30,7 @@
 #include <openssl/x509v3.h>
 
 #include "extern.h"
-#include "rsa.h"
+#include "key.h"
 
 /*
  * This was lifted more or less directly from demos/x509/mkreq.c of the
@@ -117,13 +117,19 @@ 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)
+		if ((pkey = key_load(f, keyfile)) == NULL)
 			goto out;
-		doddbg("%s: loaded RSA domain key", keyfile);
+		doddbg("%s: loaded domain key", keyfile);
 	}
 
 	fclose(f);
Index: main.c
===================================================================
RCS file: /cvs/src/usr.sbin/acme-client/main.c,v
retrieving revision 1.47
diff -u -p -r1.47 main.c
--- main.c	8 Jun 2019 07:52:55 -0000	1.47
+++ main.c	11 Jun 2019 11:35:25 -0000
@@ -49,6 +49,7 @@ main(int argc, char *argv[])
 	int		  popts = 0;
 	pid_t		  pids[COMP__MAX];
 	extern int	  verbose;
+	extern int	  ecdsa;
 	extern enum comp  proccomp;
 	size_t		  i, altsz, ne;
 
@@ -145,6 +146,10 @@ main(int argc, char *argv[])
 		authority = authority_find(conf, auth);
 		if (authority == NULL)
 			errx(EXIT_FAILURE, "authority %s not found", auth);
+	}
+
+	if (domain->keytype == 1) {
+		ecdsa = 1;
 	}
 
 	acctkey = authority->account;
Index: parse.h
===================================================================
RCS file: /cvs/src/usr.sbin/acme-client/parse.h,v
retrieving revision 1.10
diff -u -p -r1.10 parse.h
--- parse.h	8 Jun 2019 07:52:55 -0000	1.10
+++ parse.h	11 Jun 2019 11:35:25 -0000
@@ -38,6 +38,7 @@ struct domain_c {
 	TAILQ_ENTRY(domain_c)	 entry;
 	TAILQ_HEAD(, altname_c)	altname_list;
 	int			altname_count;
+	int		       	keytype;
 	char		       	*domain;
 	char		       	*key;
 	char		       	*cert;
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/acme-client/parse.y,v
retrieving revision 1.34
diff -u -p -r1.34 parse.y
--- parse.y	8 Jun 2019 07:52:55 -0000	1.34
+++ parse.y	11 Jun 2019 11:35:25 -0000
@@ -38,6 +38,7 @@
 #include <unistd.h>
 
 #include "parse.h"
+#include "extern.h"
 
 TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
 static struct file {
@@ -99,10 +100,11 @@ typedef struct {
 %}
 
 %token	AUTHORITY URL API ACCOUNT
-%token	DOMAIN ALTERNATIVE NAMES CERT FULL CHAIN KEY SIGN WITH CHALLENGEDIR
+%token	DOMAIN ALTERNATIVE NAMES CERT FULL CHAIN KEY SIGN WITH CHALLENGEDIR KEYTYPE
 %token	YES NO
 %token	INCLUDE
 %token	ERROR
+%token	RSA ECDSA
 %token	<v.string>	STRING
 %token	<v.number>	NUMBER
 %type	<v.string>	string
@@ -258,12 +260,21 @@ domain		: DOMAIN STRING {
 		}
 		;
 
+keytype		: RSA { 
+			domain->keytype = 0;
+		}
+		| ECDSA {
+			domain->keytype = 1;
+		}
+		| /* nothing */
+		;
+
 domainopts_l	: domainopts_l domainoptsl nl
 		| domainoptsl optnl
 		;
 
 domainoptsl	: ALTERNATIVE NAMES '{' altname_l '}'
-		| DOMAIN KEY STRING {
+		| DOMAIN KEY STRING keytype {
 			char *s;
 			if (domain->key != NULL) {
 				yyerror("duplicate key");
@@ -427,10 +438,12 @@ lookup(char *s)
 		{"chain",		CHAIN},
 		{"challengedir",	CHALLENGEDIR},
 		{"domain",		DOMAIN},
+		{"ecdsa",		ECDSA},
 		{"full",		FULL},
 		{"include",		INCLUDE},
 		{"key",			KEY},
 		{"names",		NAMES},
+		{"rsa",			RSA},
 		{"sign",		SIGN},
 		{"url",			URL},
 		{"with",		WITH},
Index: rsa.c
===================================================================
RCS file: rsa.c
diff -N rsa.c
--- rsa.c	28 Jul 2018 15:25:23 -0000	1.7
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,88 +0,0 @@
-/*	$Id: rsa.c,v 1.7 2018/07/28 15:25:23 tb Exp $ */
-/*
- * Copyright (c) 2016 Kristaps Dzonsons <krist...@bsd.lv>
- *
- * 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.
- */
-
-#include <err.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <openssl/evp.h>
-#include <openssl/pem.h>
-#include <openssl/rsa.h>
-
-#include "rsa.h"
-
-/*
- * Default number of bits when creating a new key.
- */
-#define	KBITS 4096
-
-/*
- * Create an RSA key with the default KBITS number of bits.
- */
-EVP_PKEY *
-rsa_key_create(FILE *f, const char *fname)
-{
-	EVP_PKEY_CTX	*ctx = NULL;
-	EVP_PKEY	*pkey = NULL;
-
-	/* First, create the context and the key. */
-
-	if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) {
-		warnx("EVP_PKEY_CTX_new_id");
-		goto err;
-	} else if (EVP_PKEY_keygen_init(ctx) <= 0) {
-		warnx("EVP_PKEY_keygen_init");
-		goto err;
-	} else if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, KBITS) <= 0) {
-		warnx("EVP_PKEY_set_rsa_keygen_bits");
-		goto err;
-	} else if (EVP_PKEY_keygen(ctx, &pkey) <= 0) {
-		warnx("EVP_PKEY_keygen");
-		goto err;
-	}
-
-	/* Serialise the key to the disc. */
-
-	if (PEM_write_PrivateKey(f, pkey, NULL, NULL, 0, NULL, NULL))
-		goto out;
-
-	warnx("%s: PEM_write_PrivateKey", fname);
-err:
-	EVP_PKEY_free(pkey);
-	pkey = NULL;
-out:
-	EVP_PKEY_CTX_free(ctx);
-	return pkey;
-}
-
-
-EVP_PKEY *
-rsa_key_load(FILE *f, const char *fname)
-{
-	EVP_PKEY	*pkey;
-
-	pkey = PEM_read_PrivateKey(f, NULL, NULL, NULL);
-	if (pkey == NULL) {
-		warnx("%s: PEM_read_PrivateKey", fname);
-		return NULL;
-	} else if (EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA)
-		return pkey;
-
-	warnx("%s: unsupported key type", fname);
-	EVP_PKEY_free(pkey);
-	return NULL;
-}
Index: rsa.h
===================================================================
RCS file: rsa.h
diff -N rsa.h
--- rsa.h	31 Aug 2016 22:01:42 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,23 +0,0 @@
-/*	$Id: rsa.h,v 1.1 2016/08/31 22:01:42 florian Exp $ */
-/*
- * Copyright (c) 2016 Kristaps Dzonsons <krist...@bsd.lv>
- *
- * 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 RSA_H
-#define RSA_H
-
-EVP_PKEY	*rsa_key_create(FILE *, const char *);
-EVP_PKEY	*rsa_key_load(FILE *, const char *);
-
-#endif /* ! RSA_H */

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

Reply via email to