summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorflorian <florian@openbsd.org>2016-09-01 12:17:00 +0000
committerflorian <florian@openbsd.org>2016-09-01 12:17:00 +0000
commita8bb3d0cfc471b8af701e1abcbd864812b60cea3 (patch)
tree01b8a85f77e0ed9ddfb5c28e12f73137d3948954
parentsync (diff)
downloadwireguard-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.120
-rw-r--r--usr.sbin/acme-client/extern.h13
-rw-r--r--usr.sbin/acme-client/main.c38
-rw-r--r--usr.sbin/acme-client/netproc.c9
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.