I had a look yesterday and it looks mostly OK. Something came up and I won't be around the next days.
Someone can put it and and we can tweak it in tree or we wait a few days. On Tue, Jun 11, 2019 at 01:37:24PM +0200, Renaud Allard wrote: > > > 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 */ -- I'm not entirely sure you are real.