On 6/7/19 2:38 PM, Renaud Allard wrote:
On 6/7/19 2:28 PM, Florian Obser wrote:On Fri, Jun 07, 2019 at 10:40:36AM +0200, Renaud Allard wrote:On 6/6/19 10:46 AM, Renaud Allard wrote:On 6/6/19 10:10 AM, Florian Obser wrote:I currently don't have time to review this. I'm busy switching acme-client to the rfc 8555 / letsencrypt v2 api. Doesn't look like this conflicts too badly with my work, but I'd appreciate it if we could hold this off for a bit and rebase it ontop of the v2 work.OK, let's wait till your v2 is done. People have the patch already if they want to try out ecdsa in the meantime.Here is the patch after the v2 change. I also changed ecdsa to int instead of bool as requested.you forgot to include ecdsa.h this time around, but I found it in one of the earlier diffs. It is a bit silly though, just skip it, rename rsa.h to key.h and add your ecdsa.h content there.
Hello, Here is a patch with ecdsa and rsa in %token after the domain key name OK? comments?
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 08:15:13 -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 08:15:13 -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 08:15:13 -0000 @@ -109,8 +109,9 @@ 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. +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 08:15:13 -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 08:15:14 -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 08:15:14 -0000 @@ -0,0 +1,31 @@ +/* $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 RSA_H +#define RSA_H + +EVP_PKEY *rsa_key_create(FILE *, const char *); +EVP_PKEY *key_load(FILE *, const char *); + +#endif /* ! RSA_H */ + +#ifndef ECDSA_H +#define ECDSA_H + +EVP_PKEY *ec_key_create(FILE *, const char *); + +#endif /* ! ECDSA_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 08:15:14 -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 08:15:14 -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 08:15:14 -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 08:15:14 -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 */
smime.p7s
Description: S/MIME Cryptographic Signature