diff options
author | 2016-09-01 12:17:00 +0000 | |
---|---|---|
committer | 2016-09-01 12:17:00 +0000 | |
commit | a8bb3d0cfc471b8af701e1abcbd864812b60cea3 (patch) | |
tree | 01b8a85f77e0ed9ddfb5c28e12f73137d3948954 | |
parent | sync (diff) | |
download | wireguard-openbsd-a8bb3d0cfc471b8af701e1abcbd864812b60cea3.tar.xz wireguard-openbsd-a8bb3d0cfc471b8af701e1abcbd864812b60cea3.zip |
Implement table driven selection to which ACME authorities we can
talk.
Suggest by and OK deraadt, OK benno.
(Later on deraadt and benno discussed if this should be handled with a
config file. This seems to be good enough for now. We can do a config
file later.)
-rw-r--r-- | usr.sbin/acme-client/acme-client.1 | 20 | ||||
-rw-r--r-- | usr.sbin/acme-client/extern.h | 13 | ||||
-rw-r--r-- | usr.sbin/acme-client/main.c | 38 | ||||
-rw-r--r-- | usr.sbin/acme-client/netproc.c | 9 |
4 files changed, 60 insertions, 20 deletions
diff --git a/usr.sbin/acme-client/acme-client.1 b/usr.sbin/acme-client/acme-client.1 index d1d17ff361d..228ef7ad696 100644 --- a/usr.sbin/acme-client/acme-client.1 +++ b/usr.sbin/acme-client/acme-client.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: acme-client.1,v 1.5 2016/09/01 10:15:28 jmc Exp $ +.\" $OpenBSD: acme-client.1,v 1.6 2016/09/01 12:17:00 florian Exp $ .\" .\" Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv> .\" @@ -22,12 +22,13 @@ .Nd ACME client .Sh SYNOPSIS .Nm acme-client -.Op Fl bFmNnrsv +.Op Fl bFmNnrv .Op Fl a Ar agreement .Op Fl C Ar challengedir .Op Fl c Ar certdir .Op Fl f Ar accountkey .Op Fl k Ar domainkey +.Op Fl s Ar authority .Ar domain .Op Ar altnames .Sh DESCRIPTION @@ -122,8 +123,19 @@ Create a new 4096-bit RSA domain key if one does not already exist. Create a new 4096-bit RSA account key if one does not already exist. .It Fl r Revoke the X509 certificate found in the certificates. -.It Fl s -Use a staging server instead of the real thing. +.It Fl s Ar authority +ACME +.Ar authority +to talk to. +Currently the following authorities are available: +.Bl -tag +.It Cm letsencrypt +Let's Encrypt authority +.It Cm letsencrypt-staging +Let's Encrypt staging authority +.El +The default is +.Cm letsencrypt . .It Fl v Verbose operation. Specify twice to also trace communication and data transfers. diff --git a/usr.sbin/acme-client/extern.h b/usr.sbin/acme-client/extern.h index e240495b216..55d0153af6a 100644 --- a/usr.sbin/acme-client/extern.h +++ b/usr.sbin/acme-client/extern.h @@ -1,4 +1,4 @@ -/* $Id: extern.h,v 1.4 2016/09/01 00:25:57 deraadt Exp $ */ +/* $Id: extern.h,v 1.5 2016/09/01 12:17:00 florian Exp $ */ /* * Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -26,6 +26,9 @@ #define FCHAIN_PEM "fullchain.pem" #define FCHAIN_BAK "fullchain.pem~" +#ifndef nitems +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) +#endif /* * Requests to and from acctproc. @@ -142,6 +145,14 @@ enum comm { COMM__MAX }; +struct authority { + char *name; + char *agreement; + char *caurl; +}; + +extern struct authority authorities[]; + /* * This contains the URI and token of an ACME-issued challenge. * A challenge consists of a token, which we must present on the diff --git a/usr.sbin/acme-client/main.c b/usr.sbin/acme-client/main.c index c390ba103d9..a690f0467a7 100644 --- a/usr.sbin/acme-client/main.c +++ b/usr.sbin/acme-client/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.8 2016/09/01 00:35:22 florian Exp $ */ +/* $Id: main.c,v 1.9 2016/09/01 12:17:00 florian Exp $ */ /* * Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -27,14 +27,22 @@ #include "extern.h" -#define AGREEMENT "https://letsencrypt.org" \ - "/documents/LE-SA-v1.1.1-August-1-2016.pdf" #define SSL_DIR "/etc/ssl/acme" #define SSL_PRIV_DIR "/etc/ssl/acme/private" #define ETC_DIR "/etc/acme" #define WWW_DIR "/var/www/acme" #define PRIVKEY_FILE "privkey.pem" +struct authority authorities[] = { +#define DEFAULT_AUTHORITY 0 + {"letsencrypt", + "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf", + "https://acme-v01.api.letsencrypt.org/directory"}, + {"letsencrypt-staging", + "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf", + "https://acme-staging.api.letsencrypt.org/directory"}, +}; + /* * This isn't RFC1035 compliant, but does the bare minimum in making * sure that we don't get bogus domain names on the command line, which @@ -80,7 +88,7 @@ main(int argc, char *argv[]) rvk_fds[2]; pid_t pids[COMP__MAX]; int c, rc, newacct, remote, revocate, force, - staging, multidir, newkey, backup; + multidir, newkey, backup, authority; extern int verbose; extern enum comp proccomp; size_t i, altsz, ne; @@ -88,11 +96,12 @@ main(int argc, char *argv[]) alts = NULL; newacct = remote = revocate = verbose = force = - multidir = staging = newkey = backup = 0; + multidir = newkey = backup = 0; + authority = DEFAULT_AUTHORITY; certdir = keyfile = acctkey = chngdir = NULL; - agreement = AGREEMENT; + agreement = NULL; - while (-1 != (c = getopt(argc, argv, "bFmnNrstva:f:c:C:k:"))) + while (-1 != (c = getopt(argc, argv, "bFmnNrs:tva:f:c:C:k:"))) switch (c) { case ('a'): agreement = optarg; @@ -136,7 +145,15 @@ main(int argc, char *argv[]) revocate = 1; break; case ('s'): - staging = 1; + authority = -1; + for (i = 0; i < nitems(authorities); i++) { + if (strcmp(authorities[i].name, optarg) == 0) { + authority = i; + break; + } + } + if (-1 == authority) + errx(EXIT_FAILURE, "unknown acme authority"); break; case ('t'): /* @@ -152,6 +169,9 @@ main(int argc, char *argv[]) goto usage; } + if (NULL == agreement) + agreement = authorities[authority].agreement; + argc -= optind; argv += optind; if (0 == argc) @@ -287,7 +307,7 @@ main(int argc, char *argv[]) c = netproc(key_fds[1], acct_fds[1], chng_fds[1], cert_fds[1], dns_fds[1], rvk_fds[1], - newacct, revocate, staging, + newacct, revocate, authority, (const char *const *)alts, altsz, agreement); free(alts); diff --git a/usr.sbin/acme-client/netproc.c b/usr.sbin/acme-client/netproc.c index 85ad87b7fcb..9b9fa8cbd76 100644 --- a/usr.sbin/acme-client/netproc.c +++ b/usr.sbin/acme-client/netproc.c @@ -1,4 +1,4 @@ -/* $Id: netproc.c,v 1.5 2016/09/01 00:35:22 florian Exp $ */ +/* $Id: netproc.c,v 1.6 2016/09/01 12:17:00 florian Exp $ */ /* * Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -26,9 +26,6 @@ #include "http.h" #include "extern.h" -#define URL_REAL_CA "https://acme-v01.api.letsencrypt.org/directory" -#define URL_STAGE_CA "https://acme-staging.api.letsencrypt.org/directory" - #define RETRY_DELAY 5 #define RETRY_MAX 10 @@ -580,7 +577,7 @@ dofullchain(struct conn *c, const char *addr) */ int netproc(int kfd, int afd, int Cfd, int cfd, int dfd, int rfd, - int newacct, int revocate, int staging, + int newacct, int revocate, int authority, const char *const *alts, size_t altsz, const char *agreement) { int rc; @@ -651,7 +648,7 @@ netproc(int kfd, int afd, int Cfd, int cfd, int dfd, int rfd, c.dfd = dfd; c.fd = afd; - c.na = staging ? URL_STAGE_CA : URL_REAL_CA; + c.na = authorities[authority].caurl; /* * Look up the domain of the ACME server. |