[patch] use acme-client to sign certificated with ecdsa keys

classic Classic list List threaded Threaded
30 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2
Hello,

First, sorry for double posting to misc@.

This is a short patch to let acme-client accept ECDSA keys now that
letsencrypt accepts signing certificates with those keys. This
functionality is present in certbot, so it might be a good idea to let
acme-client accept that too.
The key needs to be generated manually
i.e.: openssl ecparam -genkey -name secp384r1 -out privkey.pem

Best Regards


acme-client-ec.diff (639 bytes) Download Attachment
smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Florian Obser-2
On Wed, May 22, 2019 at 01:33:11PM +0200, Renaud Allard wrote:
> Hello,
>
> First, sorry for double posting to misc@.
>
> This is a short patch to let acme-client accept ECDSA keys now that
> letsencrypt accepts signing certificates with those keys. This functionality
> is present in certbot, so it might be a good idea to let acme-client accept
> that too.

thanks

> 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?

>
> Best Regards
>





--
I'm not entirely sure you are real.

Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2


On 5/29/19 9:58 AM, Florian Obser wrote:

> On Wed, May 22, 2019 at 01:33:11PM +0200, Renaud Allard wrote:
>> Hello,
>>
>> First, sorry for double posting to misc@.
>>
>> This is a short patch to let acme-client accept ECDSA keys now that
>> letsencrypt accepts signing certificates with those keys. This functionality
>> is present in certbot, so it might be a good idea to let acme-client accept
>> that too.
>
> thanks
>
>> 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?
I prefer to first enable testing for everyone to be able to spot the
eventual problems with those certs. For example, opensmtpd and relayd
still don't support ecdsa certs because they to don't have a privsep
engine for that yet, so you certainly don't want ecdsa to be the default
at the moment.

But, yes, I plan to make a patch to enable generating ecdsa keys. It
will mainly be useful when Letsencrypt will allow signing with ecdsa too.


smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2


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.




acme-client-ec.diff (7K) Download Attachment
smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2


On 6/3/19 11:18 AM, Renaud Allard wrote:

>
>
> 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.
>
I obviously meant -E switch :)


smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2


On 6/3/19 11:53 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 -E switch to
>> generate a ECDSA key instead of the RSA one.
I refined a little bit the patch to not put ecdsa functions into rsa.c.
So I renamed rsa.c to key.c and removed the rsa references to functions
which apply to both rsa and ecdsa.



acme-client-ec.diff (16K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Gilles Chehade-7
On Tue, Jun 04, 2019 at 03:54:11PM +0200, Renaud Allard wrote:

>
>
> On 6/3/19 11:53 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 -E switch to
> > > generate a ECDSA key instead of the RSA one.
>
> I refined a little bit the patch to not put ecdsa functions into rsa.c. So I
> renamed rsa.c to key.c and removed the rsa references to functions which
> apply to both rsa and ecdsa.
>

reads, builds and works fine for me

a couple comments inlined


> 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 4 Jun 2019 13:50:28 -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.12
> diff -u -p -r1.12 acctproc.c
> --- acctproc.c 28 Jul 2018 15:25:23 -0000 1.12
> +++ acctproc.c 4 Jun 2019 13:50:28 -0000
> @@ -82,8 +82,8 @@ op_thumb_rsa(EVP_PKEY *pkey)
>   warnx("bn2string");
>   else if ((exp = bn2string(r->e)) == NULL)
>   warnx("bn2string");
> - else if ((json = json_fmt_thumb_rsa(exp, mod)) == NULL)
> - warnx("json_fmt_thumb_rsa");
> + else if ((json = json_fmt_thumb_key(exp, mod)) == NULL)
> + warnx("json_fmt_thumb_key");
>  
>   free(exp);
>   free(mod);
> @@ -175,10 +175,10 @@ op_sign_rsa(char **head, char **prot, EV
>   warnx("bn2string");
>   else if ((exp = bn2string(r->e)) == NULL)
>   warnx("bn2string");
> - else if ((*head = json_fmt_header_rsa(exp, mod)) == NULL)
> - warnx("json_fmt_header_rsa");
> - else if ((*prot = json_fmt_protected_rsa(exp, mod, nonce)) == NULL)
> - warnx("json_fmt_protected_rsa");
> + else if ((*head = json_fmt_header_key(exp, mod)) == NULL)
> + warnx("json_fmt_header_key");
> + else if ((*prot = json_fmt_protected_key(exp, mod, nonce)) == NULL)
> + warnx("json_fmt_protected_key");
>   else
>   rc = 1;
>  
> @@ -338,7 +338,7 @@ 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;
>   doddbg("%s: loaded RSA account key", acctkey);
>   }
> 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 4 Jun 2019 13:50:28 -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.

why is RSA in parenthesis here ?

> +.It Fl E
> +Switch the new domain key algorithm to ECDSA instead of RSA.

the E option should be added to the SYNOPSIS too

>  .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 4 Jun 2019 13:50:28 -0000
> @@ -0,0 +1,22 @@
> +/* $Id: rsa.h,v 1.1 2016/08/31 22:01:42 florian Exp $ */
> +/*
> + * Copyright (c) 2019 Renaud Allard <[hidden email]>
> + *
> + * 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 4 Jun 2019 13:50:28 -0000
> @@ -18,6 +18,7 @@
>  #define EXTERN_H
>  
>  #include "parse.h"
> +#include "stdbool.h"
>  
>  #define MAX_SERVERS_DNS 8
>  
> @@ -240,11 +241,11 @@ char *json_fmt_challenge(const char *,
>  char *json_fmt_newauthz(const char *);
>  char *json_fmt_newcert(const char *);
>  char *json_fmt_newreg(const char *);
> -char *json_fmt_protected_rsa(const char *,
> +char *json_fmt_protected_key(const char *,
>   const char *, const char *);
>  char *json_fmt_revokecert(const char *);
> -char *json_fmt_header_rsa(const char *, const char *);
> -char *json_fmt_thumb_rsa(const char *, const char *);
> +char *json_fmt_header_key(const char *, const char *);
> +char *json_fmt_thumb_key(const char *, const char *);
>  char *json_fmt_signed(const char *,
>   const char *, const char *, const char *);
>  
> @@ -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: json.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/acme-client/json.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 json.c
> --- json.c 31 Jan 2019 15:55:48 -0000 1.11
> +++ json.c 4 Jun 2019 13:50:28 -0000
> @@ -589,7 +589,7 @@ json_fmt_newcert(const char *cert)
>   * Header component of json_fmt_signed().
>   */
>  char *
> -json_fmt_header_rsa(const char *exp, const char *mod)
> +json_fmt_header_key(const char *exp, const char *mod)
>  {
>   int c;
>   char *p;
> @@ -611,7 +611,7 @@ json_fmt_header_rsa(const char *exp, con
>   * Protected component of json_fmt_signed().
>   */
>  char *
> -json_fmt_protected_rsa(const char *exp, const char *mod, const char *nce)
> +json_fmt_protected_key(const char *exp, const char *mod, const char *nce)
>  {
>   int c;
>   char *p;
> @@ -661,7 +661,7 @@ json_fmt_signed(const char *header, cons
>   * However, it's in the form of a JSON string, so do it here.
>   */
>  char *
> -json_fmt_thumb_rsa(const char *exp, const char *mod)
> +json_fmt_thumb_key(const char *exp, const char *mod)
>  {
>   int c;
>   char *p;
> Index: key.c
> ===================================================================
> RCS file: key.c
> diff -N key.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ key.c 4 Jun 2019 13:50:28 -0000
> @@ -0,0 +1,150 @@
> +/* $Id: rsa.c,v 1.7 2018/07/28 15:25:23 tb Exp $ */
> +/*
> + * Copyright (c) 2019 Renaud Allard <[hidden email]>
> + * Copyright (c) 2016 Kristaps Dzonsons <[hidden email]>
> + *
> + * 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 "rsa.h"
> +#include "ecdsa.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;
> + }
> +
> + goto out;
> +
> + warnx("%s: PEM_write_ECPrivateKey", fname);
> +
> +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: 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 4 Jun 2019 13:50:28 -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,11 +115,17 @@ 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);
>   }
> 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 4 Jun 2019 13:50:28 -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 4 Jun 2019 13:50:28 -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: 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 <[hidden email]>
> - *
> - * 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: /cvs/src/usr.sbin/acme-client/rsa.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 rsa.h
> --- rsa.h 31 Aug 2016 22:01:42 -0000 1.1
> +++ rsa.h 4 Jun 2019 13:50:28 -0000
> @@ -18,6 +18,6 @@
>  #define RSA_H
>  
>  EVP_PKEY *rsa_key_create(FILE *, const char *);
> -EVP_PKEY *rsa_key_load(FILE *, const char *);
> +EVP_PKEY *key_load(FILE *, const char *);
>  
>  #endif /* ! RSA_H */


--
Gilles Chehade       @poolpOrg

https://www.poolp.org                 tip me: https://paypal.me/poolpOrg

Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2


On 6/5/19 8:20 AM, Gilles Chehade wrote:

> On Tue, Jun 04, 2019 at 03:54:11PM +0200, Renaud Allard wrote:
>>
>>
>> On 6/3/19 11:53 AM, Renaud Allard wrote:
>>>>>
>>>>> On 5/29/19 9:58 AM, Florian Obser wrote:
>>>>>> why not let acme-client generate the key?
>>>>>
>>>>
>>>> Here is a more complete diff where you can use the -E switch to
>>>> generate a ECDSA key instead of the RSA one.
>>
>> I refined a little bit the patch to not put ecdsa functions into rsa.c. So I
>> renamed rsa.c to key.c and removed the rsa references to functions which
>> apply to both rsa and ecdsa.
>>
>
> reads, builds and works fine for me
>
> a couple comments inlined
>
I removed the parenthesis and used another wording, removed the RSA from
a "Load RSA key" as it might not be RSA and added E to the SYNOPSYS.


acme-client-ec.diff (16K) Download Attachment
smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2


On 6/5/19 8:39 AM, Renaud Allard wrote:

>
>
> On 6/5/19 8:20 AM, Gilles Chehade wrote:
>> On Tue, Jun 04, 2019 at 03:54:11PM +0200, Renaud Allard wrote:
>>>
>>>
>>> On 6/3/19 11:53 AM, Renaud Allard wrote:
>>>>>>
>>>>>> On 5/29/19 9:58 AM, Florian Obser wrote:
>>>>>>> why not let acme-client generate the key?
>>>>>>
>>>>>
>>>>> Here is a more complete diff where you can use the -E switch to
>>>>> generate a ECDSA key instead of the RSA one.
>>>
>>> I refined a little bit the patch to not put ecdsa functions into
>>> rsa.c. So I
>>> renamed rsa.c to key.c and removed the rsa references to functions which
>>> apply to both rsa and ecdsa.
>>>
>>
>> reads, builds and works fine for me
>>
>> a couple comments inlined
>>
>
> I removed the parenthesis and used another wording, removed the RSA from
> a "Load RSA key" as it might not be RSA and added E to the SYNOPSYS.
>
For completion, just in case you are wondering why I choose secp384r1
instead of secp521r1. It is because letsencrypt doesn't allow 521 bits
keys. They return "Invalid key in certificate request :: ECDSA curve
P-521 not allowed"


smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Gilles Chehade-7
In reply to this post by Renaud Allard-2
On Wed, Jun 05, 2019 at 08:39:51AM +0200, Renaud Allard wrote:

>
>
> On 6/5/19 8:20 AM, Gilles Chehade wrote:
> > On Tue, Jun 04, 2019 at 03:54:11PM +0200, Renaud Allard wrote:
> > >
> > >
> > > On 6/3/19 11:53 AM, Renaud Allard wrote:
> > > > > >
> > > > > > On 5/29/19 9:58 AM, Florian Obser wrote:
> > > > > > > why not let acme-client generate the key?
> > > > > >
> > > > >
> > > > > Here is a more complete diff where you can use the -E switch to
> > > > > generate a ECDSA key instead of the RSA one.
> > >
> > > I refined a little bit the patch to not put ecdsa functions into rsa.c. So I
> > > renamed rsa.c to key.c and removed the rsa references to functions which
> > > apply to both rsa and ecdsa.
> > >
> >
> > reads, builds and works fine for me
> >
> > a couple comments inlined
> >
>
> I removed the parenthesis and used another wording, removed the RSA from a
> "Load RSA key" as it might not be RSA and added E to the SYNOPSYS.
>

ok gilles@

> 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 5 Jun 2019 06:37:00 -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.12
> diff -u -p -r1.12 acctproc.c
> --- acctproc.c 28 Jul 2018 15:25:23 -0000 1.12
> +++ acctproc.c 5 Jun 2019 06:37:00 -0000
> @@ -82,8 +82,8 @@ op_thumb_rsa(EVP_PKEY *pkey)
>   warnx("bn2string");
>   else if ((exp = bn2string(r->e)) == NULL)
>   warnx("bn2string");
> - else if ((json = json_fmt_thumb_rsa(exp, mod)) == NULL)
> - warnx("json_fmt_thumb_rsa");
> + else if ((json = json_fmt_thumb_key(exp, mod)) == NULL)
> + warnx("json_fmt_thumb_key");
>  
>   free(exp);
>   free(mod);
> @@ -175,10 +175,10 @@ op_sign_rsa(char **head, char **prot, EV
>   warnx("bn2string");
>   else if ((exp = bn2string(r->e)) == NULL)
>   warnx("bn2string");
> - else if ((*head = json_fmt_header_rsa(exp, mod)) == NULL)
> - warnx("json_fmt_header_rsa");
> - else if ((*prot = json_fmt_protected_rsa(exp, mod, nonce)) == NULL)
> - warnx("json_fmt_protected_rsa");
> + else if ((*head = json_fmt_header_key(exp, mod)) == NULL)
> + warnx("json_fmt_header_key");
> + else if ((*prot = json_fmt_protected_key(exp, mod, nonce)) == NULL)
> + warnx("json_fmt_protected_key");
>   else
>   rc = 1;
>  
> @@ -338,7 +338,7 @@ 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;
>   doddbg("%s: loaded RSA account key", acctkey);
>   }
> 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 5 Jun 2019 06:37:00 -0000
> @@ -22,7 +22,7 @@
>  .Nd ACME client
>  .Sh SYNOPSIS
>  .Nm acme-client
> -.Op Fl ADFnrv
> +.Op Fl ADEFnrv
>  .Op Fl f Ar configfile
>  .Ar domain
>  .Sh DESCRIPTION
> @@ -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 domain key if one does not already exist. Defaults to RSA.
> +.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 5 Jun 2019 06:37:00 -0000
> @@ -0,0 +1,22 @@
> +/* $Id: rsa.h,v 1.1 2016/08/31 22:01:42 florian Exp $ */
> +/*
> + * Copyright (c) 2019 Renaud Allard <[hidden email]>
> + *
> + * 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 5 Jun 2019 06:37:00 -0000
> @@ -18,6 +18,7 @@
>  #define EXTERN_H
>  
>  #include "parse.h"
> +#include "stdbool.h"
>  
>  #define MAX_SERVERS_DNS 8
>  
> @@ -240,11 +241,11 @@ char *json_fmt_challenge(const char *,
>  char *json_fmt_newauthz(const char *);
>  char *json_fmt_newcert(const char *);
>  char *json_fmt_newreg(const char *);
> -char *json_fmt_protected_rsa(const char *,
> +char *json_fmt_protected_key(const char *,
>   const char *, const char *);
>  char *json_fmt_revokecert(const char *);
> -char *json_fmt_header_rsa(const char *, const char *);
> -char *json_fmt_thumb_rsa(const char *, const char *);
> +char *json_fmt_header_key(const char *, const char *);
> +char *json_fmt_thumb_key(const char *, const char *);
>  char *json_fmt_signed(const char *,
>   const char *, const char *, const char *);
>  
> @@ -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: json.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/acme-client/json.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 json.c
> --- json.c 31 Jan 2019 15:55:48 -0000 1.11
> +++ json.c 5 Jun 2019 06:37:00 -0000
> @@ -589,7 +589,7 @@ json_fmt_newcert(const char *cert)
>   * Header component of json_fmt_signed().
>   */
>  char *
> -json_fmt_header_rsa(const char *exp, const char *mod)
> +json_fmt_header_key(const char *exp, const char *mod)
>  {
>   int c;
>   char *p;
> @@ -611,7 +611,7 @@ json_fmt_header_rsa(const char *exp, con
>   * Protected component of json_fmt_signed().
>   */
>  char *
> -json_fmt_protected_rsa(const char *exp, const char *mod, const char *nce)
> +json_fmt_protected_key(const char *exp, const char *mod, const char *nce)
>  {
>   int c;
>   char *p;
> @@ -661,7 +661,7 @@ json_fmt_signed(const char *header, cons
>   * However, it's in the form of a JSON string, so do it here.
>   */
>  char *
> -json_fmt_thumb_rsa(const char *exp, const char *mod)
> +json_fmt_thumb_key(const char *exp, const char *mod)
>  {
>   int c;
>   char *p;
> Index: key.c
> ===================================================================
> RCS file: key.c
> diff -N key.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ key.c 5 Jun 2019 06:37:00 -0000
> @@ -0,0 +1,150 @@
> +/* $Id: rsa.c,v 1.7 2018/07/28 15:25:23 tb Exp $ */
> +/*
> + * Copyright (c) 2019 Renaud Allard <[hidden email]>
> + * Copyright (c) 2016 Kristaps Dzonsons <[hidden email]>
> + *
> + * 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 "rsa.h"
> +#include "ecdsa.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;
> + }
> +
> + goto out;
> +
> + warnx("%s: PEM_write_ECPrivateKey", fname);
> +
> +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: 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 5 Jun 2019 06:37:00 -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,13 +115,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.45
> diff -u -p -r1.45 main.c
> --- main.c 9 Mar 2019 18:07:40 -0000 1.45
> +++ main.c 5 Jun 2019 06:37:00 -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 5 Jun 2019 06:37:00 -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: 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 <[hidden email]>
> - *
> - * 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: /cvs/src/usr.sbin/acme-client/rsa.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 rsa.h
> --- rsa.h 31 Aug 2016 22:01:42 -0000 1.1
> +++ rsa.h 5 Jun 2019 06:37:00 -0000
> @@ -18,6 +18,6 @@
>  #define RSA_H
>  
>  EVP_PKEY *rsa_key_create(FILE *, const char *);
> -EVP_PKEY *rsa_key_load(FILE *, const char *);
> +EVP_PKEY *key_load(FILE *, const char *);
>  
>  #endif /* ! RSA_H */




--
Gilles Chehade       @poolpOrg

https://www.poolp.org                 tip me: https://paypal.me/poolpOrg

Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Florian Obser
On Wed, Jun 05, 2019 at 05:37:51PM +0200, Gilles Chehade wrote:

> On Wed, Jun 05, 2019 at 08:39:51AM +0200, Renaud Allard wrote:
> >
> >
> > On 6/5/19 8:20 AM, Gilles Chehade wrote:
> > > On Tue, Jun 04, 2019 at 03:54:11PM +0200, Renaud Allard wrote:
> > > >
> > > >
> > > > On 6/3/19 11:53 AM, Renaud Allard wrote:
> > > > > > >
> > > > > > > On 5/29/19 9:58 AM, Florian Obser wrote:
> > > > > > > > why not let acme-client generate the key?
> > > > > > >
> > > > > >
> > > > > > Here is a more complete diff where you can use the -E switch to
> > > > > > generate a ECDSA key instead of the RSA one.
> > > >
> > > > I refined a little bit the patch to not put ecdsa functions into rsa.c. So I
> > > > renamed rsa.c to key.c and removed the rsa references to functions which
> > > > apply to both rsa and ecdsa.
> > > >
> > >
> > > reads, builds and works fine for me
> > >
> > > a couple comments inlined
> > >
> >
> > I removed the parenthesis and used another wording, removed the RSA from a
> > "Load RSA key" as it might not be RSA and added E to the SYNOPSYS.
> >
>
> ok gilles@

We don't do bool in base as far as I know, just use an int.

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.

I'd also like to get rid of most of the flags and it feels like RSA
vs. ECDSA should be handled in the config file?

>
> > 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 5 Jun 2019 06:37:00 -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.12
> > diff -u -p -r1.12 acctproc.c
> > --- acctproc.c 28 Jul 2018 15:25:23 -0000 1.12
> > +++ acctproc.c 5 Jun 2019 06:37:00 -0000
> > @@ -82,8 +82,8 @@ op_thumb_rsa(EVP_PKEY *pkey)
> >   warnx("bn2string");
> >   else if ((exp = bn2string(r->e)) == NULL)
> >   warnx("bn2string");
> > - else if ((json = json_fmt_thumb_rsa(exp, mod)) == NULL)
> > - warnx("json_fmt_thumb_rsa");
> > + else if ((json = json_fmt_thumb_key(exp, mod)) == NULL)
> > + warnx("json_fmt_thumb_key");
> >  
> >   free(exp);
> >   free(mod);
> > @@ -175,10 +175,10 @@ op_sign_rsa(char **head, char **prot, EV
> >   warnx("bn2string");
> >   else if ((exp = bn2string(r->e)) == NULL)
> >   warnx("bn2string");
> > - else if ((*head = json_fmt_header_rsa(exp, mod)) == NULL)
> > - warnx("json_fmt_header_rsa");
> > - else if ((*prot = json_fmt_protected_rsa(exp, mod, nonce)) == NULL)
> > - warnx("json_fmt_protected_rsa");
> > + else if ((*head = json_fmt_header_key(exp, mod)) == NULL)
> > + warnx("json_fmt_header_key");
> > + else if ((*prot = json_fmt_protected_key(exp, mod, nonce)) == NULL)
> > + warnx("json_fmt_protected_key");
> >   else
> >   rc = 1;
> >  
> > @@ -338,7 +338,7 @@ 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;
> >   doddbg("%s: loaded RSA account key", acctkey);
> >   }
> > 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 5 Jun 2019 06:37:00 -0000
> > @@ -22,7 +22,7 @@
> >  .Nd ACME client
> >  .Sh SYNOPSIS
> >  .Nm acme-client
> > -.Op Fl ADFnrv
> > +.Op Fl ADEFnrv
> >  .Op Fl f Ar configfile
> >  .Ar domain
> >  .Sh DESCRIPTION
> > @@ -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 domain key if one does not already exist. Defaults to RSA.
> > +.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 5 Jun 2019 06:37:00 -0000
> > @@ -0,0 +1,22 @@
> > +/* $Id: rsa.h,v 1.1 2016/08/31 22:01:42 florian Exp $ */
> > +/*
> > + * Copyright (c) 2019 Renaud Allard <[hidden email]>
> > + *
> > + * 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 5 Jun 2019 06:37:00 -0000
> > @@ -18,6 +18,7 @@
> >  #define EXTERN_H
> >  
> >  #include "parse.h"
> > +#include "stdbool.h"
> >  
> >  #define MAX_SERVERS_DNS 8
> >  
> > @@ -240,11 +241,11 @@ char *json_fmt_challenge(const char *,
> >  char *json_fmt_newauthz(const char *);
> >  char *json_fmt_newcert(const char *);
> >  char *json_fmt_newreg(const char *);
> > -char *json_fmt_protected_rsa(const char *,
> > +char *json_fmt_protected_key(const char *,
> >   const char *, const char *);
> >  char *json_fmt_revokecert(const char *);
> > -char *json_fmt_header_rsa(const char *, const char *);
> > -char *json_fmt_thumb_rsa(const char *, const char *);
> > +char *json_fmt_header_key(const char *, const char *);
> > +char *json_fmt_thumb_key(const char *, const char *);
> >  char *json_fmt_signed(const char *,
> >   const char *, const char *, const char *);
> >  
> > @@ -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: json.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/acme-client/json.c,v
> > retrieving revision 1.11
> > diff -u -p -r1.11 json.c
> > --- json.c 31 Jan 2019 15:55:48 -0000 1.11
> > +++ json.c 5 Jun 2019 06:37:00 -0000
> > @@ -589,7 +589,7 @@ json_fmt_newcert(const char *cert)
> >   * Header component of json_fmt_signed().
> >   */
> >  char *
> > -json_fmt_header_rsa(const char *exp, const char *mod)
> > +json_fmt_header_key(const char *exp, const char *mod)
> >  {
> >   int c;
> >   char *p;
> > @@ -611,7 +611,7 @@ json_fmt_header_rsa(const char *exp, con
> >   * Protected component of json_fmt_signed().
> >   */
> >  char *
> > -json_fmt_protected_rsa(const char *exp, const char *mod, const char *nce)
> > +json_fmt_protected_key(const char *exp, const char *mod, const char *nce)
> >  {
> >   int c;
> >   char *p;
> > @@ -661,7 +661,7 @@ json_fmt_signed(const char *header, cons
> >   * However, it's in the form of a JSON string, so do it here.
> >   */
> >  char *
> > -json_fmt_thumb_rsa(const char *exp, const char *mod)
> > +json_fmt_thumb_key(const char *exp, const char *mod)
> >  {
> >   int c;
> >   char *p;
> > Index: key.c
> > ===================================================================
> > RCS file: key.c
> > diff -N key.c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ key.c 5 Jun 2019 06:37:00 -0000
> > @@ -0,0 +1,150 @@
> > +/* $Id: rsa.c,v 1.7 2018/07/28 15:25:23 tb Exp $ */
> > +/*
> > + * Copyright (c) 2019 Renaud Allard <[hidden email]>
> > + * Copyright (c) 2016 Kristaps Dzonsons <[hidden email]>
> > + *
> > + * 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 "rsa.h"
> > +#include "ecdsa.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;
> > + }
> > +
> > + goto out;
> > +
> > + warnx("%s: PEM_write_ECPrivateKey", fname);
> > +
> > +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: 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 5 Jun 2019 06:37:00 -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,13 +115,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.45
> > diff -u -p -r1.45 main.c
> > --- main.c 9 Mar 2019 18:07:40 -0000 1.45
> > +++ main.c 5 Jun 2019 06:37:00 -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 5 Jun 2019 06:37:00 -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: 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 <[hidden email]>
> > - *
> > - * 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: /cvs/src/usr.sbin/acme-client/rsa.h,v
> > retrieving revision 1.1
> > diff -u -p -r1.1 rsa.h
> > --- rsa.h 31 Aug 2016 22:01:42 -0000 1.1
> > +++ rsa.h 5 Jun 2019 06:37:00 -0000
> > @@ -18,6 +18,6 @@
> >  #define RSA_H
> >  
> >  EVP_PKEY *rsa_key_create(FILE *, const char *);
> > -EVP_PKEY *rsa_key_load(FILE *, const char *);
> > +EVP_PKEY *key_load(FILE *, const char *);
> >  
> >  #endif /* ! RSA_H */
>
>
>
>
> --
> Gilles Chehade       @poolpOrg
>
> https://www.poolp.org                 tip me: https://paypal.me/poolpOrg
>

--
I'm not entirely sure you are real.

Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2


On 6/6/19 10:10 AM, Florian Obser wrote:

> On Wed, Jun 05, 2019 at 05:37:51PM +0200, Gilles Chehade wrote:
>> On Wed, Jun 05, 2019 at 08:39:51AM +0200, Renaud Allard wrote:
>>>
>>>
>>> On 6/5/19 8:20 AM, Gilles Chehade wrote:
>>>> On Tue, Jun 04, 2019 at 03:54:11PM +0200, Renaud Allard wrote:
>>>>>
>>>>>
>>>>> On 6/3/19 11:53 AM, Renaud Allard wrote:
>>>>>>>>
>>>>>>>> On 5/29/19 9:58 AM, Florian Obser wrote:
>>>>>>>>> why not let acme-client generate the key?
>>>>>>>>
>>>>>>>
>>>>>>> Here is a more complete diff where you can use the -E switch to
>>>>>>> generate a ECDSA key instead of the RSA one.
>>>>>
>>>>> I refined a little bit the patch to not put ecdsa functions into rsa.c. So I
>>>>> renamed rsa.c to key.c and removed the rsa references to functions which
>>>>> apply to both rsa and ecdsa.
>>>>>
>>>>
>>>> reads, builds and works fine for me
>>>>
>>>> a couple comments inlined
>>>>
>>>
>>> I removed the parenthesis and used another wording, removed the RSA from a
>>> "Load RSA key" as it might not be RSA and added E to the SYNOPSYS.
>>>
>>
>> ok gilles@
>
> We don't do bool in base as far as I know, just use an int.
>
No problem, that's a trivial change.

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

>
> I'd also like to get rid of most of the flags and it feels like RSA
> vs. ECDSA should be handled in the config file?
>

I think the flags A,D,v and E could indeed belong to the config file.



smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2


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.


acme-client-ec.diff (14K) Download Attachment
smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2


On 6/7/19 10:40 AM, 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.
>
Sorry, former patch was missing ecdsa.h
This one is correct

Comments? OK?


acme-client-ec.diff (15K) Download Attachment
smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Florian Obser-2
In reply to this post by Renaud Allard-2
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.


> 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 7 Jun 2019 08:37:56 -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.13
> diff -u -p -r1.13 acctproc.c
> --- acctproc.c 7 Jun 2019 08:07:52 -0000 1.13
> +++ acctproc.c 7 Jun 2019 08:37:56 -0000
> @@ -82,8 +82,8 @@ op_thumb_rsa(EVP_PKEY *pkey)
>   warnx("bn2string");
>   else if ((exp = bn2string(r->e)) == NULL)
>   warnx("bn2string");
> - else if ((json = json_fmt_thumb_rsa(exp, mod)) == NULL)
> - warnx("json_fmt_thumb_rsa");
> + else if ((json = json_fmt_thumb_key(exp, mod)) == NULL)
> + warnx("json_fmt_thumb_key");

keep the _rsa name, this is the account key, not the domain key.

>  
>   free(exp);
>   free(mod);
> @@ -173,8 +173,8 @@ op_sign_rsa(char **prot, EVP_PKEY *pkey,
>   warnx("bn2string");
>   else if ((exp = bn2string(r->e)) == NULL)
>   warnx("bn2string");
> - else if ((*prot = json_fmt_protected_rsa(exp, mod, nonce, url)) == NULL)
> - warnx("json_fmt_protected_rsa");
> + else if ((*prot = json_fmt_protected_key(exp, mod, nonce, url)) == NULL)
> + warnx("json_fmt_protected_key");

keep the _rsa name, this is the account key, not the domain key.

>   else
>   rc = 1;
>  
> @@ -349,7 +349,7 @@ 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)

we need a check here that this is an RSA key for now since we don't
support ECDSA account keys yet

>   goto out;
>   doddbg("%s: loaded RSA account key", acctkey);
>   }
> Index: acme-client.1
> ===================================================================
> RCS file: /cvs/src/usr.sbin/acme-client/acme-client.1,v
> retrieving revision 1.30
> diff -u -p -r1.30 acme-client.1
> --- acme-client.1 7 Jun 2019 08:07:52 -0000 1.30
> +++ acme-client.1 7 Jun 2019 08:37:56 -0000
> @@ -22,7 +22,7 @@
>  .Nd ACME client
>  .Sh SYNOPSIS
>  .Nm acme-client
> -.Op Fl ADFnrv
> +.Op Fl ADEFnrv
>  .Op Fl f Ar configfile
>  .Ar domain
>  .Sh DESCRIPTION
> @@ -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 domain key if one does not already exist. Defaults to RSA.
> +.It Fl E
> +Switch the new domain key algorithm to ECDSA instead of RSA.

could you try to tackle moving this to the config file instead of a flag?

>  .It Fl F
>  Force certificate renewal, even if it's too soon.
>  .It Fl f Ar configfile
> Index: extern.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/acme-client/extern.h,v
> retrieving revision 1.11
> diff -u -p -r1.11 extern.h
> --- extern.h 7 Jun 2019 08:07:52 -0000 1.11
> +++ extern.h 7 Jun 2019 08:37:57 -0000
> @@ -263,18 +263,23 @@ char *json_fmt_newcert(const char *);
>  char *json_fmt_chkacc(void);
>  char *json_fmt_newacc(void);
>  char *json_fmt_neworder(const char *const *, size_t);
> -char *json_fmt_protected_rsa(const char *,
> +char *json_fmt_protected_key(const char *,

keep the _rsa name, this is the account key, not the domain key.

>   const char *, const char *, const char *);
>  char *json_fmt_protected_kid(const char *, const char *,
>   const char *);
>  char *json_fmt_revokecert(const char *);
> -char *json_fmt_thumb_rsa(const char *, const char *);
> +char *json_fmt_thumb_key(const char *, const char *);

keep the _rsa name, this is the account key, not the domain key.

>  char *json_fmt_signed(const char *, const char *, const char *);
>  
>  /*
>   * Should we print debugging messages?
>   */
>  int verbose;
> +
> +/*
> + * Should we switch to ecdsa?
> + */
> +int ecdsa;
>  
>  /*
>   * What component is the process within (COMP__MAX for none)?
> Index: json.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/acme-client/json.c,v
> retrieving revision 1.12
> diff -u -p -r1.12 json.c
> --- json.c 7 Jun 2019 08:07:52 -0000 1.12
> +++ json.c 7 Jun 2019 08:37:57 -0000
> @@ -708,7 +708,7 @@ json_fmt_newcert(const char *cert)
>   * Protected component of json_fmt_signed().
>   */
>  char *
> -json_fmt_protected_rsa(const char *exp, const char *mod, const char *nce,
> +json_fmt_protected_key(const char *exp, const char *mod, const char *nce,

keep the _rsa name, this is the account key, not the domain key.

>      const char *url)
>  {
>   int c;
> @@ -781,7 +781,7 @@ json_fmt_signed(const char *protected, c
>   * However, it's in the form of a JSON string, so do it here.
>   */
>  char *
> -json_fmt_thumb_rsa(const char *exp, const char *mod)
> +json_fmt_thumb_key(const char *exp, const char *mod)

keep the _rsa name, this is the account key, not the domain key.

>  {
>   int c;
>   char *p;
> Index: key.c
> ===================================================================
> RCS file: key.c
> diff -N key.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ key.c 7 Jun 2019 08:37:57 -0000
> @@ -0,0 +1,150 @@
> +/* $Id: rsa.c,v 1.7 2018/07/28 15:25:23 tb Exp $ */
> +/*
> + * Copyright (c) 2019 Renaud Allard <[hidden email]>
> + * Copyright (c) 2016 Kristaps Dzonsons <[hidden email]>
> + *
> + * 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 "rsa.h"
> +#include "ecdsa.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;
> + }
> +
> + goto out;
> +
> + warnx("%s: PEM_write_ECPrivateKey", fname);

this is unreachable

> +
> +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: 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 7 Jun 2019 08:37:57 -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,13 +115,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.46
> diff -u -p -r1.46 main.c
> --- main.c 7 Jun 2019 08:07:52 -0000 1.46
> +++ main.c 7 Jun 2019 08:37:57 -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;
>  
> @@ -57,13 +58,16 @@ 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;
>   break;
>   case 'D':
>   popts |= ACME_OPT_NEWDKEY;
> + break;
> + case 'E':
> + ecdsa = 1;

it would be awesome to have this in the config file.
I can help you if you get stuck there.

I would add it to the end for "domain key", with rsa the default.

So this would be rsa:

domain example.com {
        alternative names { secure.example.com }
        domain key "/etc/ssl/private/example.com.key"
        domain full chain certificate "/etc/ssl/example.com.fullchain.pem"
        sign with letsencrypt
}

so would this:

        domain key "/etc/ssl/private/example.com.key" RSA

and ecdsa:

        domain key "/etc/ssl/private/example.com.key" ECDSA

make RSA/ECDSA proper tokens in parse.y, don't try to strcmp it.

>   break;
>   case 'F':
>   force = 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 7 Jun 2019 08:37:57 -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: 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 <[hidden email]>
> - *
> - * 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: /cvs/src/usr.sbin/acme-client/rsa.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 rsa.h
> --- rsa.h 31 Aug 2016 22:01:42 -0000 1.1
> +++ rsa.h 7 Jun 2019 08:37:57 -0000
> @@ -18,6 +18,6 @@
>  #define RSA_H
>  
>  EVP_PKEY *rsa_key_create(FILE *, const char *);
> -EVP_PKEY *rsa_key_load(FILE *, const char *);
> +EVP_PKEY *key_load(FILE *, const char *);
>  
>  #endif /* ! RSA_H */




--
I'm not entirely sure you are real.

Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2


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.
>
True, it makes no sense to put 2 header files for just that.
Here it is with key.h



acme-client-ec.diff (16K) Download Attachment
smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2
In reply to this post by Florian Obser-2


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.
>
Here is a patch without the flag.
I know you told me not to strncmp the keytype, but I don't see how to
produce an understandable error if I use tokens and without making
repetitions in the code.




acme-client-ec.diff (15K) Download Attachment
smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2
In reply to this post by Renaud Allard-2


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?

acme-client-ec.diff (15K) Download Attachment
smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Renaud Allard-2


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?

acme-client-ec.diff (15K) Download Attachment
smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [patch] use acme-client to sign certificated with ecdsa keys

Gilles Chehade-7
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?

I don't have an openbsd at hands right now to test this version of
the diff but I tested an earlier version and you took into account
my comments so ... ok by me


> 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 <[hidden email]>
> + * Copyright (c) 2016 Kristaps Dzonsons <[hidden email]>
> + *
> + * 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 <[hidden email]>
> + * Copyright (c) 2016 Kristaps Dzonsons <[hidden email]>
> + *
> + * 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 <[hidden email]>
> - *
> - * 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 <[hidden email]>
> - *
> - * 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 */




--
Gilles Chehade       @poolpOrg

https://www.poolp.org                 tip me: https://paypal.me/poolpOrg

12