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 */
smime.p7s
Description: S/MIME Cryptographic Signature