kore

Kore is a web application platform for writing scalable, concurrent web based processes in C or Python.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

acme.c (44121B)



      1 /*
      2  * Copyright (c) 2019-2022 Joris Vink <joris@coders.se>
      3  *
      4  * Permission to use, copy, modify, and distribute this software for any
      5  * purpose with or without fee is hereby granted, provided that the above
      6  * copyright notice and this permission notice appear in all copies.
      7  *
      8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 /*
     18  * ACMEv2 protocol implementation.
     19  *
     20  * The acme process is responsible for talking to the acme servers, parsing
     21  * their JSON responses and requesting signed data / a csr from the keymgr
     22  * process.
     23  *
     24  * The acme process does not hold your account or domain keys, so anything
     25  * that needs to be signed is sent to the keymgr process instead.
     26  */
     27 
     28 #include <sys/types.h>
     29 #include <sys/stat.h>
     30 
     31 #include <openssl/sha.h>
     32 
     33 #include <stdio.h>
     34 #include <stdlib.h>
     35 
     36 #include "kore.h"
     37 #include "acme.h"
     38 #include "curl.h"
     39 
     40 #define ACME_CREATE_ACCOUNT	0
     41 #define ACME_RESOLVE_ACCOUNT	1
     42 
     43 #define ACME_STATUS_PENDING	1
     44 #define ACME_STATUS_PROCESSING	2
     45 #define ACME_STATUS_VALID	3
     46 #define ACME_STATUS_INVALID	4
     47 #define ACME_STATUS_READY	5
     48 #define ACME_STATUS_EXPIRED	6
     49 #define ACME_STATUS_REVOKED	7
     50 
     51 /*
     52  * The default provider is letsencrypt, can be overwritten via the config
     53  * file its acme_provider setting.
     54  */
     55 #define ACME_DEFAULT_PROVIDER	"https://acme-v02.api.letsencrypt.org/directory"
     56 
     57 #if defined(__linux__)
     58 #include "seccomp.h"
     59 
     60 /*
     61  * The syscalls our acme worker is allowed to perform, only.
     62  *
     63  * Since we drop all previously loaded seccomp rules to apply our own
     64  * we will have to reinclude the ones curl does.
     65  */
     66 static struct sock_filter filter_acme[] = {
     67 	KORE_SYSCALL_ALLOW(prctl),
     68 #if defined(SYS_poll)
     69 	KORE_SYSCALL_ALLOW(poll),
     70 #endif
     71 	KORE_SYSCALL_ALLOW(ppoll),
     72 	KORE_SYSCALL_ALLOW(sendto),
     73 	KORE_SYSCALL_ALLOW(recvfrom),
     74 #if defined(SYS_epoll_wait)
     75 	KORE_SYSCALL_ALLOW(epoll_wait),
     76 #endif
     77 	KORE_SYSCALL_ALLOW(epoll_pwait),
     78 	KORE_SYSCALL_ALLOW(recvmsg),
     79 	KORE_SYSCALL_ALLOW(sendmsg),
     80 	KORE_SYSCALL_ALLOW(sendmmsg),
     81 	KORE_SYSCALL_ALLOW(getpeername),
     82 
     83 	KORE_SYSCALL_ALLOW(gettid),
     84 	KORE_SYSCALL_ALLOW(exit),
     85 
     86 	KORE_SYSCALL_ALLOW(brk),
     87 #if defined(SYS_mmap)
     88 	KORE_SYSCALL_ALLOW(mmap),
     89 #endif
     90 #if defined(SYS_mmap2)
     91 	KORE_SYSCALL_ALLOW(mmap2),
     92 #endif
     93 	KORE_SYSCALL_ALLOW(ioctl),
     94 	KORE_SYSCALL_ALLOW(uname),
     95 	KORE_SYSCALL_ALLOW(munmap),
     96 	KORE_SYSCALL_ALLOW(madvise),
     97 	KORE_SYSCALL_ALLOW(faccessat),
     98 	KORE_SYSCALL_ALLOW(newfstatat),
     99 	KORE_SYSCALL_ALLOW(clock_gettime),
    100 
    101 	KORE_SYSCALL_ALLOW(bind),
    102 	KORE_SYSCALL_ALLOW(ioctl),
    103 	KORE_SYSCALL_ALLOW(connect),
    104 	KORE_SYSCALL_ALLOW(getsockopt),
    105 	KORE_SYSCALL_ALLOW(socketpair),
    106 	KORE_SYSCALL_ALLOW(getsockname),
    107 	KORE_SYSCALL_ALLOW_ARG(socket, 0, AF_INET),
    108 	KORE_SYSCALL_ALLOW_ARG(socket, 0, AF_INET6),
    109 	KORE_SYSCALL_ALLOW_ARG(socket, 0, AF_UNIX),
    110 	KORE_SYSCALL_ALLOW_ARG(socket, 0, AF_NETLINK),
    111 
    112 	KORE_SYSCALL_ALLOW(clone),
    113 	KORE_SYSCALL_ALLOW(membarrier),
    114 	KORE_SYSCALL_ALLOW(set_robust_list),
    115 #if defined(SYS_clone3)
    116 	KORE_SYSCALL_ALLOW(clone3),
    117 #endif
    118 #if defined(SYS_rseq)
    119 	KORE_SYSCALL_ALLOW(rseq),
    120 #endif
    121 };
    122 #endif
    123 
    124 struct acme_request {
    125 	struct kore_curl	curl;
    126 };
    127 
    128 struct acme_sign_op {
    129 	u_int32_t			id;
    130 	struct kore_timer		*t;
    131 	void				*udata;
    132 	char				*nonce;
    133 	char				*payload;
    134 	char				*protected;
    135 	void				(*cb)(struct acme_sign_op *,
    136 					    struct kore_buf *);
    137 	LIST_ENTRY(acme_sign_op)	list;
    138 };
    139 
    140 #define ACME_AUTH_STATE_DOWNLOAD		1
    141 #define ACME_AUTH_STATE_CHALLENGE		2
    142 
    143 struct acme_auth {
    144 	char				*url;
    145 	struct acme_order		*order;
    146 	int				status;
    147 	struct acme_challenge		*challenge;
    148 	LIST_ENTRY(acme_auth)		list;
    149 };
    150 
    151 #define ACME_ORDER_STATE_RUNNING		1
    152 #define ACME_ORDER_STATE_ERROR			2
    153 #define ACME_ORDER_STATE_CANCELLED		3
    154 #define ACME_ORDER_STATE_UPDATE			4
    155 #define ACME_ORDER_STATE_UPDATE_AUTH		5
    156 #define ACME_ORDER_STATE_WAITING		6
    157 #define ACME_ORDER_STATE_FETCH_CERT		7
    158 #define ACME_ORDER_STATE_COMPLETE		8
    159 #define ACME_ORDER_TICK				1000
    160 #define ACME_ORDER_TIMEOUT			240000
    161 
    162 #define ACME_ORDER_CSR_REQUESTED		0x1000
    163 
    164 struct acme_order {
    165 	int				state;
    166 	int				status;
    167 	int				flags;
    168 	int				auths;
    169 	u_int64_t			start;
    170 	char				*id;
    171 	char				*final;
    172 	char				*domain;
    173 	char				*certloc;
    174 	struct acme_auth		*curauth;
    175 	LIST_HEAD(, acme_auth)		auth;
    176 	LIST_ENTRY(acme_order)		list;
    177 };
    178 
    179 static LIST_HEAD(, acme_order)		orders;
    180 
    181 #define ACME_FLAG_CHALLENGE_CREATED	0x0001
    182 #define ACME_CHALLENGE_TOKEN_MAXLEN	64
    183 
    184 struct acme_challenge {
    185 	int		status;
    186 	int		flags;
    187 	char		*url;
    188 	char		*type;
    189 	char		*token;
    190 	char		*error_type;
    191 	char		*error_detail;
    192 	int		(*process)(struct acme_order *,
    193 			    struct acme_challenge *);
    194 };
    195 
    196 static LIST_HEAD(, acme_sign_op)	signops;
    197 
    198 static int	acme_status_type(const char *);
    199 static int	acme_request_run(struct acme_request *);
    200 static void	acme_request_cleanup(struct acme_request *);
    201 static void	acme_request_prepare(struct acme_request *,
    202 		    int, const char *, const void *, size_t);
    203 static void	acme_request_json(struct kore_buf *, const char *,
    204 		    const char *, const char *);
    205 
    206 static char	*acme_nonce_fetch(void);
    207 static char	*acme_thumbprint_component(void);
    208 static char	*acme_base64url(const void *, size_t);
    209 static char	*acme_protected_component(const char *, const char *);
    210 static void	acme_keymgr_key_req(const char *, const void *, size_t, int);
    211 
    212 static void	acme_parse_directory(void);
    213 static void	acme_directory_set(struct kore_json *, const char *, char **);
    214 
    215 static void	acme_sign_expire(void *, u_int64_t);
    216 static void	acme_sign_result(struct kore_msg *, const void *);
    217 static void	acme_sign_submit(struct kore_json_item *, const char *, void *,
    218 		    void (*cb)(struct acme_sign_op *, struct kore_buf *));
    219 
    220 static void	acme_rsakey_exp(struct kore_msg *, const void *);
    221 static void	acme_rsakey_mod(struct kore_msg *, const void *);
    222 
    223 static void	acme_account_reg(int);
    224 static void	acme_account_create(struct kore_msg *, const void *);
    225 static void	acme_account_resolve(struct kore_msg *, const void *);
    226 static void	acme_generic_submit(struct acme_sign_op *, struct kore_buf *);
    227 static void	acme_account_reg_submit(struct acme_sign_op *,
    228 		    struct kore_buf *);
    229 
    230 static void	acme_order_retry(const char *);
    231 static void	acme_order_process(void *, u_int64_t);
    232 static void	acme_order_update(struct acme_order *);
    233 static void	acme_order_update_submit(struct acme_sign_op *,
    234 		    struct kore_buf *);
    235 static void	acme_order_request_csr(struct acme_order *);
    236 static void	acme_order_fetch_certificate(struct acme_order *);
    237 static void	acme_order_fetch_certificate_submit(struct acme_sign_op *,
    238 		    struct kore_buf *);
    239 static void	acme_order_create(struct kore_msg *, const void *);
    240 static void	acme_order_remove(struct acme_order *, const char *);
    241 static void	acme_order_csr_response(struct kore_msg *, const void *);
    242 static void	acme_order_create_submit(struct acme_sign_op *,
    243 		    struct kore_buf *);
    244 
    245 static void	acme_order_auth_log_error(struct acme_order *);
    246 static void	acme_order_auth_deactivate(struct acme_order *);
    247 static int	acme_order_auth_process(struct acme_order *,
    248 		    struct acme_auth *);
    249 static void	acme_order_auth_update(struct acme_order *,
    250 		    struct acme_auth *);
    251 static void	acme_order_auth_update_submit(struct acme_sign_op *,
    252 		    struct kore_buf *);
    253 
    254 static int	acme_challenge_tls_alpn_01(struct acme_order *,
    255 		    struct acme_challenge *);
    256 static void	acme_challenge_tls_alpn_01_create(struct acme_order *,
    257 		    struct acme_challenge *);
    258 
    259 static void	acme_challenge_respond(struct acme_order *,
    260 		    const char *, const char *);
    261 
    262 static int		signop_id = 0;
    263 static char		*rsakey_n = NULL;
    264 static char		*rsakey_e = NULL;
    265 static char		*nonce_url = NULL;
    266 static char		*order_url = NULL;
    267 static char		*revoke_url = NULL;
    268 static char		*account_id = NULL;
    269 static char		*account_url = NULL;
    270 
    271 struct kore_privsep	acme_privsep;
    272 int			acme_domains = 0;
    273 char			*acme_email = NULL;
    274 char			*acme_provider = NULL;
    275 u_int32_t		acme_request_timeout = 8;
    276 
    277 void
    278 kore_acme_init(void)
    279 {
    280 	acme_provider = kore_strdup(ACME_DEFAULT_PROVIDER);
    281 }
    282 
    283 void
    284 kore_acme_run(void)
    285 {
    286 	int		quit;
    287 	u_int64_t	now, netwait;
    288 
    289 	quit = 0;
    290 
    291 	kore_server_closeall();
    292 	kore_module_cleanup();
    293 
    294 	net_init();
    295 	kore_timer_init();
    296 	kore_connection_init();
    297 	kore_platform_event_init();
    298 	kore_msg_worker_init();
    299 
    300 	kore_msg_register(KORE_ACME_RSAKEY_E, acme_rsakey_exp);
    301 	kore_msg_register(KORE_ACME_RSAKEY_N, acme_rsakey_mod);
    302 	kore_msg_register(KORE_ACME_SIGN_RESULT, acme_sign_result);
    303 	kore_msg_register(KORE_ACME_ORDER_CREATE, acme_order_create);
    304 	kore_msg_register(KORE_ACME_ACCOUNT_CREATE, acme_account_create);
    305 	kore_msg_register(KORE_ACME_ACCOUNT_RESOLVE, acme_account_resolve);
    306 	kore_msg_register(KORE_ACME_CSR_RESPONSE, acme_order_csr_response);
    307 
    308 #if defined(__linux__)
    309 	/* Drop all enabled seccomp filters, and add only ours. */
    310 	kore_seccomp_drop();
    311 	kore_seccomp_filter("acme", filter_acme, KORE_FILTER_LEN(filter_acme));
    312 #endif
    313 #if defined(KORE_USE_PYTHON)
    314 	kore_msg_unregister(KORE_PYTHON_SEND_OBJ);
    315 #endif
    316 	kore_worker_privsep();
    317 
    318 #if defined(__OpenBSD__)
    319 	if (unveil("/etc/ssl/", "r") == -1)
    320 		fatal("unveil: %s", errno_s);
    321 	if (pledge("stdio inet dns rpath", NULL) == -1)
    322 		fatal("pledge acme process: %s", errno_s);
    323 #endif
    324 
    325 	http_init();
    326 
    327 	LIST_INIT(&orders);
    328 	LIST_INIT(&signops);
    329 
    330 	kore_worker_started();
    331 	acme_parse_directory();
    332 
    333 	while (quit != 1) {
    334 		now = kore_time_ms();
    335 		netwait = kore_timer_next_run(now);
    336 		kore_platform_event_wait(netwait);
    337 
    338 		if (sig_recv != 0) {
    339 			switch (sig_recv) {
    340 			case SIGQUIT:
    341 			case SIGINT:
    342 			case SIGTERM:
    343 				quit = 1;
    344 				break;
    345 			default:
    346 				break;
    347 			}
    348 			sig_recv = 0;
    349 		}
    350 
    351 		if (quit)
    352 			break;
    353 
    354 		now = kore_time_ms();
    355 		kore_timer_run(now);
    356 		kore_connection_prune(KORE_CONNECTION_PRUNE_DISCONNECT);
    357 	}
    358 
    359 	kore_platform_event_cleanup();
    360 	kore_connection_cleanup();
    361 	net_cleanup();
    362 }
    363 
    364 void
    365 kore_acme_get_paths(const char *domain, char **key, char **cert)
    366 {
    367 	int		len;
    368 	char		path[MAXPATHLEN];
    369 
    370 	len = snprintf(path, sizeof(path), "%s/%s/fullchain.pem",
    371 	    KORE_ACME_CERTDIR, domain);
    372 	if (len == -1 || (size_t)len >= sizeof(path))
    373 		fatal("failed to create certfile path");
    374 
    375 	*cert = kore_strdup(path);
    376 
    377 	len = snprintf(path, sizeof(path), "%s/%s/key.pem",
    378 	    KORE_ACME_CERTDIR, domain);
    379 	if (len == -1 || (size_t)len >= sizeof(path))
    380 		fatal("failed to create certkey path");
    381 
    382 	*key = kore_strdup(path);
    383 }
    384 
    385 static void
    386 acme_parse_directory(void)
    387 {
    388 	struct acme_request	req;
    389 	size_t			len;
    390 	struct kore_json	json;
    391 	const u_int8_t		*body;
    392 
    393 	acme_request_prepare(&req, HTTP_METHOD_GET, acme_provider, NULL, 0);
    394 
    395 	if (!acme_request_run(&req)) {
    396 		acme_request_cleanup(&req);
    397 		return;
    398 	}
    399 
    400 	if (req.curl.http.status != HTTP_STATUS_OK) {
    401 		kore_log(LOG_NOTICE,
    402 		    "request to '%s' failed: got %ld - expected 200",
    403 		    req.curl.url, req.curl.http.status);
    404 		acme_request_cleanup(&req);
    405 		return;
    406 	}
    407 
    408 	kore_curl_response_as_bytes(&req.curl, &body, &len);
    409 
    410 	kore_json_init(&json, body, len);
    411 
    412 	if (!kore_json_parse(&json)) {
    413 		kore_log(LOG_NOTICE,
    414 		    "failed to parse directory payload from ACME server (%s)",
    415 		    kore_json_strerror());
    416 		goto cleanup;
    417 	}
    418 
    419 	acme_directory_set(&json, "newNonce", &nonce_url);
    420 	acme_directory_set(&json, "newOrder", &order_url);
    421 	acme_directory_set(&json, "newAccount", &account_url);
    422 	acme_directory_set(&json, "revokeCert", &revoke_url);
    423 
    424 cleanup:
    425 	kore_json_cleanup(&json);
    426 	acme_request_cleanup(&req);
    427 }
    428 
    429 static char *
    430 acme_nonce_fetch(void)
    431 {
    432 	struct acme_request	req;
    433 	char			*ret;
    434 	const char		*nonce;
    435 
    436 	ret = NULL;
    437 	acme_request_prepare(&req, HTTP_METHOD_HEAD, nonce_url, NULL, 0);
    438 
    439 	if (!acme_request_run(&req))
    440 		goto cleanup;
    441 
    442 	if (req.curl.http.status != HTTP_STATUS_OK) {
    443 		kore_log(LOG_NOTICE,
    444 		    "request to '%s' failed: got %ld - expected 200",
    445 		    req.curl.url, req.curl.http.status);
    446 		goto cleanup;
    447 	}
    448 
    449 	if (!kore_curl_http_get_header(&req.curl, "replay-nonce", &nonce)) {
    450 		kore_log(LOG_NOTICE, "new-nonce: no replay-nonce header found");
    451 		goto cleanup;
    452 	}
    453 
    454 	ret = kore_strdup(nonce);
    455 
    456 cleanup:
    457 	acme_request_cleanup(&req);
    458 
    459 	return (ret);
    460 }
    461 
    462 static void
    463 acme_account_create(struct kore_msg *msg, const void *data)
    464 {
    465 	acme_account_reg(ACME_CREATE_ACCOUNT);
    466 }
    467 
    468 static void
    469 acme_account_resolve(struct kore_msg *msg, const void *data)
    470 {
    471 	acme_account_reg(ACME_RESOLVE_ACCOUNT);
    472 }
    473 
    474 static void
    475 acme_account_reg(int resolve_only)
    476 {
    477 	int			len;
    478 	char			mail[1024];
    479 	struct kore_json_item	*json, *contact;
    480 
    481 	if (account_url == NULL)
    482 		return;
    483 
    484 	kore_free(account_id);
    485 	account_id = NULL;
    486 
    487 	kore_log(LOG_INFO, "%s account with ACME provider",
    488 	    resolve_only ? "resolving" : "creating");
    489 
    490 	json = kore_json_create_object(NULL, NULL);
    491 	kore_json_create_literal(json, "termsOfServiceAgreed", KORE_JSON_TRUE);
    492 
    493 	if (acme_email) {
    494 		len = snprintf(mail, sizeof(mail), "mailto:%s", acme_email);
    495 		if (len == -1 || (size_t)len >= sizeof(mail))
    496 			fatalx("mail contact '%s' too large", acme_email);
    497 
    498 		contact = kore_json_create_array(json, "contact");
    499 		kore_json_create_string(contact, NULL, mail);
    500 	}
    501 
    502 	if (resolve_only) {
    503 		kore_json_create_literal(json,
    504 		    "onlyReturnExisting", KORE_JSON_TRUE);
    505 	}
    506 
    507 	acme_sign_submit(json, account_url, NULL, acme_account_reg_submit);
    508 	kore_json_item_free(json);
    509 }
    510 
    511 static void
    512 acme_account_reg_submit(struct acme_sign_op *op, struct kore_buf *payload)
    513 {
    514 	struct acme_request	req;
    515 	const char		*header;
    516 
    517 	acme_request_prepare(&req, HTTP_METHOD_POST, account_url,
    518 	    payload->data, payload->offset);
    519 
    520 	if (!acme_request_run(&req))
    521 		goto cleanup;
    522 
    523 	switch (req.curl.http.status) {
    524 	case HTTP_STATUS_OK:
    525 	case HTTP_STATUS_CREATED:
    526 		break;
    527 	default:
    528 		kore_log(LOG_NOTICE,
    529 		    "request to '%s' failed: status %ld - body '%s'",
    530 		    req.curl.url, req.curl.http.status,
    531 		    kore_curl_response_as_string(&req.curl));
    532 		goto cleanup;
    533 	}
    534 
    535 	if (!kore_curl_http_get_header(&req.curl, "location", &header)) {
    536 		kore_log(LOG_NOTICE, "new-acct: no location header found");
    537 		goto cleanup;
    538 	}
    539 
    540 	account_id = kore_strdup(header);
    541 	kore_log(LOG_INFO, "account_id =  %s", account_id);
    542 	kore_msg_send(KORE_WORKER_KEYMGR, KORE_ACME_PROC_READY, NULL, 0);
    543 
    544 cleanup:
    545 	acme_request_cleanup(&req);
    546 }
    547 
    548 static void
    549 acme_order_create(struct kore_msg *msg, const void *data)
    550 {
    551 	char			*domain;
    552 	struct kore_json_item	*json, *identifiers, *identifier;
    553 
    554 	domain = kore_calloc(1, msg->length + 1);
    555 	memcpy(domain, data, msg->length);
    556 	domain[msg->length] = '\0';
    557 
    558 	kore_log(LOG_INFO, "[%s] creating order", domain);
    559 
    560 	json = kore_json_create_object(NULL, NULL);
    561 	identifiers = kore_json_create_array(json, "identifiers");
    562 
    563 	identifier = kore_json_create_object(identifiers, NULL);
    564 	kore_json_create_string(identifier, "type", "dns");
    565 	kore_json_create_string(identifier, "value", domain);
    566 
    567 	acme_sign_submit(json, order_url, domain, acme_order_create_submit);
    568 	kore_json_item_free(json);
    569 }
    570 
    571 static void
    572 acme_order_create_submit(struct acme_sign_op *op, struct kore_buf *payload)
    573 {
    574 	struct acme_request		req;
    575 	size_t				len;
    576 	struct kore_json		json;
    577 	int				stval;
    578 	const u_int8_t			*body;
    579 	struct acme_auth		*auth;
    580 	struct acme_order		*order;
    581 	const char			*header;
    582 	const char			*domain;
    583 	struct kore_json_item		*item, *array, *final, *status;
    584 
    585 	order = NULL;
    586 	domain = op->udata;
    587 	acme_request_prepare(&req, HTTP_METHOD_POST, order_url,
    588 	    payload->data, payload->offset);
    589 
    590 	if (!acme_request_run(&req)) {
    591 		acme_request_cleanup(&req);
    592 		acme_order_retry(domain);
    593 		return;
    594 	}
    595 
    596 	if (req.curl.http.status != HTTP_STATUS_CREATED) {
    597 		kore_log(LOG_NOTICE,
    598 		    "[%s] - request to '%s' failed: status %ld - body '%s'",
    599 		    domain, req.curl.url, req.curl.http.status,
    600 		    kore_curl_response_as_string(&req.curl));
    601 		acme_request_cleanup(&req);
    602 		acme_order_retry(domain);
    603 		return;
    604 	}
    605 
    606 	if (!kore_curl_http_get_header(&req.curl, "location", &header)) {
    607 		kore_log(LOG_NOTICE,
    608 		    "[%s] new-order: no order id found", domain);
    609 		acme_request_cleanup(&req);
    610 		acme_order_retry(domain);
    611 		return;
    612 	}
    613 
    614 	kore_curl_response_as_bytes(&req.curl, &body, &len);
    615 	kore_json_init(&json, body, len);
    616 
    617 	if (!kore_json_parse(&json)) {
    618 		kore_log(LOG_NOTICE,
    619 		    "[%s] failed to parse order payload from ACME server (%s)",
    620 		    domain, kore_json_strerror());
    621 		goto cleanup;
    622 	}
    623 
    624 	array = kore_json_find_array(json.root, "authorizations");
    625 	if (array == NULL) {
    626 		kore_log(LOG_NOTICE, "[%s] body has no 'authorizations' array",
    627 		    domain);
    628 		goto cleanup;
    629 	}
    630 
    631 	if (TAILQ_EMPTY(&array->data.items)) {
    632 		kore_log(LOG_NOTICE, "[%s] no authoritization URLs in payload",
    633 		    domain);
    634 		goto cleanup;
    635 	}
    636 
    637 	if ((status = kore_json_find_string(json.root, "status")) == NULL) {
    638 		kore_log(LOG_NOTICE, "[%s] order has no 'status' string",
    639 		    domain);
    640 		goto cleanup;
    641 	}
    642 
    643 	if ((final = kore_json_find_string(json.root, "finalize")) == NULL) {
    644 		kore_log(LOG_NOTICE, "[%s] order has no 'finalize' string",
    645 		    domain);
    646 		goto cleanup;
    647 	}
    648 
    649 	if ((stval = acme_status_type(status->data.string)) == -1) {
    650 		kore_log(LOG_NOTICE, "[%s] order has invalid status",
    651 		    domain);
    652 		goto cleanup;
    653 	}
    654 
    655 	order = kore_calloc(1, sizeof(*order));
    656 	LIST_INSERT_HEAD(&orders, order, list);
    657 
    658 	LIST_INIT(&order->auth);
    659 
    660 	order->status = stval;
    661 	order->start = kore_time_ms();
    662 	order->id = kore_strdup(header);
    663 	order->domain = kore_strdup(domain);
    664 	order->state = ACME_ORDER_STATE_UPDATE;
    665 	order->final = kore_strdup(final->data.string);
    666 
    667 	kore_timer_add(acme_order_process, ACME_ORDER_TICK,
    668 	    order, KORE_TIMER_ONESHOT);
    669 
    670 	TAILQ_FOREACH(item, &array->data.items, list) {
    671 		if (item->type != KORE_JSON_TYPE_STRING)
    672 			continue;
    673 
    674 		auth = kore_calloc(1, sizeof(*auth));
    675 		auth->order = order;
    676 		auth->url = kore_strdup(item->data.string);
    677 		LIST_INSERT_HEAD(&order->auth, auth, list);
    678 	}
    679 
    680 	order->curauth = LIST_FIRST(&order->auth);
    681 	kore_log(LOG_INFO, "[%s] order_id =  %s", order->domain, order->id);
    682 
    683 cleanup:
    684 	if (order == NULL)
    685 		acme_order_retry(domain);
    686 
    687 	kore_json_cleanup(&json);
    688 	acme_request_cleanup(&req);
    689 }
    690 
    691 static void
    692 acme_order_update(struct acme_order *order)
    693 {
    694 	acme_sign_submit(NULL, order->id, order, acme_order_update_submit);
    695 }
    696 
    697 static void
    698 acme_order_update_submit(struct acme_sign_op *op, struct kore_buf *payload)
    699 {
    700 	struct acme_request		req;
    701 	size_t				len;
    702 	struct kore_json		json;
    703 	struct acme_order		*order;
    704 	const u_int8_t			*body;
    705 	int				stval, ret;
    706 	struct kore_json_item		*status, *cert;
    707 
    708 	order = op->udata;
    709 	op->udata = NULL;
    710 
    711 	acme_request_prepare(&req, HTTP_METHOD_POST, order->id,
    712 	    payload->data, payload->offset);
    713 
    714 	if (!acme_request_run(&req)) {
    715 		acme_request_cleanup(&req);
    716 		order->state = ACME_ORDER_STATE_ERROR;
    717 		return;
    718 	}
    719 
    720 	if (req.curl.http.status != HTTP_STATUS_OK) {
    721 		kore_log(LOG_NOTICE,
    722 		    "[%s] - request to '%s' failed: status %ld - body '%s'",
    723 		    order->domain, req.curl.url, req.curl.http.status,
    724 		    kore_curl_response_as_string(&req.curl));
    725 		acme_request_cleanup(&req);
    726 		order->state = ACME_ORDER_STATE_ERROR;
    727 		return;
    728 	}
    729 
    730 	ret = KORE_RESULT_ERROR;
    731 	kore_curl_response_as_bytes(&req.curl, &body, &len);
    732 
    733 	kore_json_init(&json, body, len);
    734 
    735 	if (!kore_json_parse(&json)) {
    736 		kore_log(LOG_NOTICE,
    737 		    "[%s] failed to parse order payload from ACME server (%s)",
    738 		    order->domain, kore_json_strerror());
    739 		goto cleanup;
    740 	}
    741 
    742 	if ((status = kore_json_find_string(json.root, "status")) == NULL) {
    743 		kore_log(LOG_NOTICE, "[%s] order has no 'status' string",
    744 		    order->domain);
    745 		goto cleanup;
    746 	}
    747 
    748 	if ((stval = acme_status_type(status->data.string)) == -1) {
    749 		kore_log(LOG_NOTICE, "[%s] order has invalid status",
    750 		    order->domain);
    751 		goto cleanup;
    752 	}
    753 
    754 	order->status = stval;
    755 
    756 	if (order->status == ACME_STATUS_VALID) {
    757 		cert = kore_json_find_string(json.root, "certificate");
    758 		if (cert == NULL) {
    759 			kore_log(LOG_NOTICE,
    760 			    "[%s] order has 'certificate' member",
    761 			    order->domain);
    762 			goto cleanup;
    763 		}
    764 
    765 		order->certloc = kore_strdup(cert->data.string);
    766 	}
    767 
    768 	ret = KORE_RESULT_OK;
    769 
    770 cleanup:
    771 	if (ret == KORE_RESULT_ERROR)
    772 		order->state = ACME_ORDER_STATE_ERROR;
    773 	else
    774 		order->state = ACME_ORDER_STATE_UPDATE_AUTH;
    775 
    776 	kore_json_cleanup(&json);
    777 	acme_request_cleanup(&req);
    778 }
    779 
    780 /*
    781  * We currently don't care why an order may have failed, (rate-limited,
    782  * auth failed, etc).
    783  *
    784  * It would be neat if we could obey that a bit better.
    785  */
    786 static void
    787 acme_order_retry(const char *domain)
    788 {
    789 	u_int32_t	retry_after;
    790 
    791 	/* arbitrary number */
    792 	retry_after = 60000;
    793 
    794 	acme_keymgr_key_req(domain, &retry_after, sizeof(retry_after),
    795 	    KORE_ACME_ORDER_FAILED);
    796 }
    797 
    798 /*
    799  * Process an order, step by step.
    800  *
    801  * This callback is called every second to check on an active order.
    802  * It will first update the order if required, and updated any of its
    803  * active awuthoritizations to get the latest data.
    804  */
    805 static void
    806 acme_order_process(void *udata, u_int64_t now)
    807 {
    808 	struct acme_auth	*auth;
    809 	struct acme_order	*order = udata;
    810 
    811 	if ((now - order->start) >= ACME_ORDER_TIMEOUT) {
    812 		acme_order_auth_deactivate(order);
    813 		acme_order_remove(order, "order ran too long");
    814 		return;
    815 	}
    816 
    817 	switch (order->state) {
    818 	case ACME_ORDER_STATE_WAITING:
    819 		break;
    820 	case ACME_ORDER_STATE_UPDATE:
    821 		acme_order_update(order);
    822 		order->state = ACME_ORDER_STATE_WAITING;
    823 		break;
    824 	case ACME_ORDER_STATE_UPDATE_AUTH:
    825 		order->auths = 0;
    826 		LIST_FOREACH(auth, &order->auth, list) {
    827 			acme_order_auth_update(order, auth);
    828 			order->auths++;
    829 		}
    830 		order->state = ACME_ORDER_STATE_WAITING;
    831 		break;
    832 	case ACME_ORDER_STATE_CANCELLED:
    833 		acme_order_remove(order, "cancelled");
    834 		order = NULL;
    835 		break;
    836 	case ACME_ORDER_STATE_COMPLETE:
    837 		acme_order_remove(order, "completed");
    838 		order = NULL;
    839 		break;
    840 	case ACME_ORDER_STATE_FETCH_CERT:
    841 		acme_order_fetch_certificate(order);
    842 		order->state = ACME_ORDER_STATE_WAITING;
    843 		break;
    844 	case ACME_ORDER_STATE_RUNNING:
    845 		switch (order->status) {
    846 		case ACME_STATUS_PENDING:
    847 			if (!acme_order_auth_process(order, order->curauth)) {
    848 				acme_order_auth_log_error(order);
    849 				acme_order_remove(order, "cancelled");
    850 				order = NULL;
    851 			}
    852 			break;
    853 		case ACME_STATUS_READY:
    854 			acme_order_request_csr(order);
    855 			break;
    856 		case ACME_STATUS_PROCESSING:
    857 			kore_log(LOG_INFO, "[%s] waiting for certificate",
    858 			    order->domain);
    859 			break;
    860 		case ACME_STATUS_VALID:
    861 			kore_log(LOG_INFO, "[%s] certificate available",
    862 			    order->domain);
    863 			order->state = ACME_ORDER_STATE_FETCH_CERT;
    864 			break;
    865 		case ACME_STATUS_INVALID:
    866 			kore_log(LOG_INFO, "[%s] order authorization failed",
    867 			    order->domain);
    868 			acme_order_auth_log_error(order);
    869 			acme_order_remove(order, "authorization failure");
    870 			order = NULL;
    871 			break;
    872 		default:
    873 			acme_order_auth_deactivate(order);
    874 			acme_order_remove(order, "unknown status");
    875 			order = NULL;
    876 			break;
    877 		}
    878 		break;
    879 	case ACME_ORDER_STATE_ERROR:
    880 		acme_order_auth_deactivate(order);
    881 		acme_order_remove(order, "error");
    882 		order = NULL;
    883 		break;
    884 	default:
    885 		fatal("%s: invalid order state %d", __func__, order->state);
    886 	}
    887 
    888 	if (order != NULL) {
    889 		/* Do not go back to update if we are ready for the cert. */
    890 		if (order->state != ACME_ORDER_STATE_FETCH_CERT)
    891 			order->state = ACME_ORDER_STATE_UPDATE;
    892 
    893 		kore_timer_add(acme_order_process, ACME_ORDER_TICK,
    894 		    order, KORE_TIMER_ONESHOT);
    895 	}
    896 }
    897 
    898 static void
    899 acme_order_remove(struct acme_order *order, const char *reason)
    900 {
    901 	struct acme_auth	*auth;
    902 
    903 	LIST_REMOVE(order, list);
    904 
    905 	while ((auth = LIST_FIRST(&order->auth)) != NULL) {
    906 		LIST_REMOVE(auth, list);
    907 
    908 		if (auth->challenge != NULL) {
    909 			kore_free(auth->challenge->error_detail);
    910 			kore_free(auth->challenge->error_type);
    911 			kore_free(auth->challenge->token);
    912 			kore_free(auth->challenge->type);
    913 			kore_free(auth->challenge->url);
    914 			kore_free(auth->challenge);
    915 		}
    916 
    917 		kore_free(auth->url);
    918 		kore_free(auth);
    919 	}
    920 
    921 	kore_log(LOG_INFO, "[%s] order removed (%s)", order->domain, reason);
    922 
    923 	if (strcmp(reason, "completed"))
    924 		acme_order_retry(order->domain);
    925 
    926 	kore_free(order->domain);
    927 	kore_free(order->final);
    928 	kore_free(order->id);
    929 	kore_free(order);
    930 }
    931 
    932 static void
    933 acme_order_fetch_certificate(struct acme_order *order)
    934 {
    935 	acme_sign_submit(NULL, order->certloc, order,
    936 	    acme_order_fetch_certificate_submit);
    937 }
    938 
    939 static void
    940 acme_order_fetch_certificate_submit(struct acme_sign_op *op,
    941     struct kore_buf *payload)
    942 {
    943 	struct acme_request	req;
    944 	size_t			len;
    945 	const u_int8_t		*body;
    946 	struct acme_order	*order;
    947 
    948 	order = op->udata;
    949 	op->udata = NULL;
    950 
    951 	acme_request_prepare(&req, HTTP_METHOD_POST, order->certloc,
    952 	    payload->data, payload->offset);
    953 
    954 	if (!acme_request_run(&req)) {
    955 		acme_request_cleanup(&req);
    956 		order->state = ACME_ORDER_STATE_CANCELLED;
    957 		return;
    958 	}
    959 
    960 	if (req.curl.http.status != HTTP_STATUS_OK) {
    961 		kore_log(LOG_NOTICE,
    962 		    "[%s] request to '%s' failed: got %ld - expected 200",
    963 		    order->domain, order->certloc, req.curl.http.status);
    964 		acme_request_cleanup(&req);
    965 		order->state = ACME_ORDER_STATE_CANCELLED;
    966 		return;
    967 	}
    968 
    969 	kore_curl_response_as_bytes(&req.curl, &body, &len);
    970 
    971 	kore_log(LOG_INFO, "got %zu bytes of cert data", len);
    972 	acme_keymgr_key_req(order->domain, body, len, KORE_ACME_INSTALL_CERT);
    973 
    974 	acme_request_cleanup(&req);
    975 	order->state = ACME_ORDER_STATE_COMPLETE;
    976 }
    977 
    978 static void
    979 acme_order_request_csr(struct acme_order *order)
    980 {
    981 	if (order->flags & ACME_ORDER_CSR_REQUESTED)
    982 		return;
    983 
    984 	kore_log(LOG_INFO, "[%s] requesting CSR", order->domain);
    985 
    986 	order->flags |= ACME_ORDER_CSR_REQUESTED;
    987 	acme_keymgr_key_req(order->domain, NULL, 0, KORE_ACME_CSR_REQUEST);
    988 }
    989 
    990 static void
    991 acme_order_csr_response(struct kore_msg *msg, const void *data)
    992 {
    993 	const struct kore_x509_msg	*req;
    994 	struct kore_json_item		*json;
    995 	struct acme_order		*order;
    996 	char				*b64, *url;
    997 
    998 	if (!kore_worker_keymgr_response_verify(msg, data, NULL))
    999 		return;
   1000 
   1001 	req = (const struct kore_x509_msg *)data;
   1002 
   1003 	LIST_FOREACH(order, &orders, list) {
   1004 		if (!strcmp(order->domain, req->domain))
   1005 			break;
   1006 	}
   1007 
   1008 	if (order == NULL) {
   1009 		kore_log(LOG_NOTICE, "[%s] csr received but no order active",
   1010 		    req->domain);
   1011 		return;
   1012 	}
   1013 
   1014 	url = kore_strdup(order->final);
   1015 	b64 = acme_base64url(req->data, req->data_len);
   1016 
   1017 	json = kore_json_create_object(NULL, NULL);
   1018 	kore_json_create_string(json, "csr", b64);
   1019 	acme_sign_submit(json, url, url, acme_generic_submit);
   1020 
   1021 	kore_json_item_free(json);
   1022 	kore_free(b64);
   1023 }
   1024 
   1025 static void
   1026 acme_order_auth_deactivate(struct acme_order *order)
   1027 {
   1028 	struct acme_request	req;
   1029 	struct acme_auth	*auth;
   1030 
   1031 	LIST_FOREACH(auth, &order->auth, list) {
   1032 		acme_request_prepare(&req, HTTP_METHOD_GET, auth->url, NULL, 0);
   1033 
   1034 		if (!acme_request_run(&req)) {
   1035 			kore_log(LOG_NOTICE,
   1036 			    "[%s:auth] failed to deactivate %s", order->domain,
   1037 			    auth->url);
   1038 		} else {
   1039 			kore_log(LOG_NOTICE, "[%s:auth] deactivated %s",
   1040 			    order->domain, auth->url);
   1041 		}
   1042 
   1043 		acme_request_cleanup(&req);
   1044 	}
   1045 }
   1046 
   1047 static void
   1048 acme_order_auth_log_error(struct acme_order *order)
   1049 {
   1050 	struct acme_auth	*auth;
   1051 
   1052 	LIST_FOREACH(auth, &order->auth, list) {
   1053 		if (auth->challenge->status == ACME_STATUS_PENDING ||
   1054 		    auth->challenge->status == ACME_STATUS_VALID ||
   1055 		    auth->challenge->status == ACME_STATUS_PROCESSING)
   1056 			continue;
   1057 
   1058 		kore_log(LOG_INFO, "[%s:auth:challenge] %s = %s (%s)",
   1059 		    order->domain, auth->challenge->type,
   1060 		    auth->challenge->error_type, auth->challenge->error_detail);
   1061 	}
   1062 }
   1063 
   1064 static int
   1065 acme_order_auth_process(struct acme_order *order, struct acme_auth *auth)
   1066 {
   1067 	int		ret;
   1068 
   1069 	if (auth == NULL)
   1070 		return (KORE_RESULT_OK);
   1071 
   1072 	ret = KORE_RESULT_ERROR;
   1073 	kore_log(LOG_INFO, "[%s] processing authentication", order->domain);
   1074 
   1075 	switch (auth->status) {
   1076 	case ACME_STATUS_PENDING:
   1077 		ret = auth->challenge->process(order, auth->challenge);
   1078 		break;
   1079 	case ACME_STATUS_VALID:
   1080 	case ACME_STATUS_PROCESSING:
   1081 		ret = KORE_RESULT_OK;
   1082 		break;
   1083 	case ACME_STATUS_INVALID:
   1084 		kore_log(LOG_NOTICE, "[%s:auth] authorization invalid",
   1085 		    order->domain);
   1086 		break;
   1087 	case ACME_STATUS_EXPIRED:
   1088 		kore_log(LOG_NOTICE, "[%s:auth] authorization expired",
   1089 		    order->domain);
   1090 		break;
   1091 	case ACME_STATUS_REVOKED:
   1092 		kore_log(LOG_NOTICE, "[%s:auth] authorization revoked",
   1093 		    order->domain);
   1094 		break;
   1095 	default:
   1096 		kore_log(LOG_NOTICE, "[%s:auth] invalid auth status %d",
   1097 		    order->domain, auth->status);
   1098 		break;
   1099 	}
   1100 
   1101 	if (ret == KORE_RESULT_OK)
   1102 		order->curauth = LIST_NEXT(order->curauth, list);
   1103 
   1104 	return (ret);
   1105 }
   1106 
   1107 static void
   1108 acme_order_auth_update(struct acme_order *order, struct acme_auth *auth)
   1109 {
   1110 	acme_sign_submit(NULL, auth->url, auth, acme_order_auth_update_submit);
   1111 }
   1112 
   1113 static void
   1114 acme_order_auth_update_submit(struct acme_sign_op *op, struct kore_buf *payload)
   1115 {
   1116 	const char			*p;
   1117 	struct acme_request		req;
   1118 	size_t				len;
   1119 	struct kore_json		json;
   1120 	const u_int8_t			*body;
   1121 	struct acme_auth		*auth;
   1122 	struct acme_order		*order;
   1123 	struct acme_challenge		*challenge;
   1124 	int				ret, stval;
   1125 	struct kore_json_item		*status, *type, *url, *token;
   1126 	struct kore_json_item		*array, *object, *err, *detail;
   1127 
   1128 	ret = KORE_RESULT_ERROR;
   1129 	memset(&json, 0, sizeof(json));
   1130 
   1131 	auth = op->udata;
   1132 	order = auth->order;
   1133 
   1134 	op->udata = NULL;
   1135 
   1136 	acme_request_prepare(&req, HTTP_METHOD_POST, auth->url,
   1137 	    payload->data, payload->offset);
   1138 
   1139 	if (!acme_request_run(&req))
   1140 		goto cleanup;
   1141 
   1142 	if (req.curl.http.status != HTTP_STATUS_OK) {
   1143 		kore_log(LOG_NOTICE,
   1144 		    "[%s:auth] request to '%s' failed: got %ld - expected 200",
   1145 		    order->domain, auth->url, req.curl.http.status);
   1146 		goto cleanup;
   1147 	}
   1148 
   1149 	kore_curl_response_as_bytes(&req.curl, &body, &len);
   1150 
   1151 	kore_json_init(&json, body, len);
   1152 
   1153 	if (!kore_json_parse(&json)) {
   1154 		kore_log(LOG_NOTICE,
   1155 		    "[%s:auth] failed to parse payload from ACME server (%s)",
   1156 		    order->domain, kore_json_strerror());
   1157 		goto cleanup;
   1158 	}
   1159 
   1160 	kore_log(LOG_INFO, "[%s:auth] %s updated", order->domain, auth->url);
   1161 
   1162 	if ((status = kore_json_find_string(json.root, "status")) == NULL) {
   1163 		kore_log(LOG_NOTICE, "[%s:auth] payload has no 'status' string",
   1164 		    order->domain);
   1165 		goto cleanup;
   1166 	}
   1167 
   1168 	if ((array = kore_json_find_array(json.root, "challenges")) == NULL) {
   1169 		kore_log(LOG_NOTICE,
   1170 		    "[%s:auth] payload has no 'challenges' array",
   1171 		    order->domain);
   1172 		goto cleanup;
   1173 	}
   1174 
   1175 	if (TAILQ_EMPTY(&array->data.items)) {
   1176 		kore_log(LOG_NOTICE,
   1177 		    "[%s:auth] no challenges URLs in challenge array",
   1178 		    order->domain);
   1179 		goto cleanup;
   1180 	}
   1181 
   1182 	if ((stval = acme_status_type(status->data.string)) == -1) {
   1183 		kore_log(LOG_NOTICE, "[%s] auth has invalid status",
   1184 		    order->domain);
   1185 		goto cleanup;
   1186 	}
   1187 
   1188 	auth->status = stval;
   1189 
   1190 	TAILQ_FOREACH(object, &array->data.items, list) {
   1191 		if (object->type != KORE_JSON_TYPE_OBJECT)
   1192 			continue;
   1193 
   1194 		if ((type = kore_json_find_string(object, "type")) == NULL) {
   1195 			kore_log(LOG_NOTICE,
   1196 			    "[%s:auth:challenge] no type", order->domain);
   1197 			continue;
   1198 		}
   1199 
   1200 		/*
   1201 		 * We only support tls-alpn-01 for now, we ignore the rest.
   1202 		 */
   1203 		if (strcmp(type->data.string, "tls-alpn-01"))
   1204 			continue;
   1205 
   1206 		url = kore_json_find_string(object, "url");
   1207 		token = kore_json_find_string(object, "token");
   1208 		status = kore_json_find_string(object, "status");
   1209 
   1210 		if (url == NULL || token == NULL || status == NULL) {
   1211 			kore_log(LOG_NOTICE,
   1212 			    "[%s:auth:challenge] missing members",
   1213 			    order->domain);
   1214 			continue;
   1215 		}
   1216 
   1217 		if (strlen(token->data.string) > ACME_CHALLENGE_TOKEN_MAXLEN) {
   1218 			kore_log(LOG_NOTICE,
   1219 			    "[%s:auth:challenge] invalid token length",
   1220 			    order->domain);
   1221 			continue;
   1222 		}
   1223 
   1224 		for (p = token->data.string; *p != '\0'; p++) {
   1225 			if ((*p >= 'a' && *p <= 'z') ||
   1226 			    (*p >= 'A' && *p <= 'Z') ||
   1227 			    (*p >= '0' && *p <= '9') || *p == '_' || *p == '-')
   1228 				continue;
   1229 			break;
   1230 		}
   1231 
   1232 		if (*p != '\0') {
   1233 			kore_log(LOG_NOTICE,
   1234 			    "[%s:auth:challenge] invalid token",
   1235 			    order->domain);
   1236 			continue;
   1237 		}
   1238 
   1239 		if ((stval = acme_status_type(status->data.string)) == -1) {
   1240 			kore_log(LOG_NOTICE,
   1241 			    "[%s:auth:challenge] invalid challenge status",
   1242 			    order->domain);
   1243 			continue;
   1244 		}
   1245 
   1246 		if (auth->challenge == NULL) {
   1247 			challenge = kore_calloc(1, sizeof(*challenge));
   1248 
   1249 			challenge->url = kore_strdup(url->data.string);
   1250 			challenge->process = acme_challenge_tls_alpn_01;
   1251 			challenge->token = kore_strdup(token->data.string);
   1252 			challenge->type = kore_strdup(type->data.string);
   1253 
   1254 			auth->challenge = challenge;
   1255 		} else {
   1256 			challenge = auth->challenge;
   1257 		}
   1258 
   1259 		challenge->status = stval;
   1260 
   1261 		if (challenge->status == ACME_STATUS_INVALID &&
   1262 		    (err = kore_json_find_object(object, "error")) != NULL) {
   1263 			type = kore_json_find_string(err, "type");
   1264 			detail = kore_json_find_string(err, "detail");
   1265 
   1266 			if (type == NULL || detail == NULL) {
   1267 				kore_log(LOG_NOTICE,
   1268 				    "[%s:auth:challenge] error missing fields",
   1269 				    order->domain);
   1270 			} else {
   1271 				kore_free(challenge->error_type);
   1272 				kore_free(challenge->error_detail);
   1273 
   1274 				challenge->error_type =
   1275 				    kore_strdup(type->data.string);
   1276 				challenge->error_detail =
   1277 				    kore_strdup(detail->data.string);
   1278 			}
   1279 		}
   1280 
   1281 		break;
   1282 	}
   1283 
   1284 	if (auth->challenge == NULL) {
   1285 		kore_log(LOG_NOTICE,
   1286 		    "[%s:auth] no supported challenges found", order->domain);
   1287 		goto cleanup;
   1288 	}
   1289 
   1290 	ret = KORE_RESULT_OK;
   1291 
   1292 cleanup:
   1293 	if (ret != KORE_RESULT_OK) {
   1294 		order->state = ACME_ORDER_STATE_CANCELLED;
   1295 	} else {
   1296 		order->auths--;
   1297 		if (order->auths == 0) {
   1298 			kore_log(LOG_INFO,
   1299 			    "[%s:auth] authentications done", order->domain);
   1300 			order->state = ACME_ORDER_STATE_RUNNING;
   1301 		}
   1302 	}
   1303 
   1304 	kore_json_cleanup(&json);
   1305 	acme_request_cleanup(&req);
   1306 }
   1307 
   1308 static int
   1309 acme_challenge_tls_alpn_01(struct acme_order *order,
   1310     struct acme_challenge *challenge)
   1311 {
   1312 	int			ret;
   1313 
   1314 	ret = KORE_RESULT_RETRY;
   1315 
   1316 	switch (challenge->status) {
   1317 	case ACME_STATUS_PENDING:
   1318 		acme_challenge_tls_alpn_01_create(order, challenge);
   1319 		break;
   1320 	case ACME_STATUS_PROCESSING:
   1321 		kore_log(LOG_INFO,
   1322 		    "[%s:auth:challenge:tls-alpn-01] processing",
   1323 		    order->domain);
   1324 		break;
   1325 	case ACME_STATUS_VALID:
   1326 		kore_log(LOG_INFO,
   1327 		    "[%s:auth:challenge:tls-alpn-01] valid",
   1328 		    order->domain);
   1329 		ret = KORE_RESULT_OK;
   1330 		break;
   1331 	default:
   1332 		kore_log(LOG_NOTICE,
   1333 		    "[%s:auth:challenge:tls-alpn-01] invalid (%d)",
   1334 		    order->domain, challenge->status);
   1335 		ret = KORE_RESULT_ERROR;
   1336 		break;
   1337 	}
   1338 
   1339 	return (ret);
   1340 }
   1341 
   1342 static void
   1343 acme_challenge_tls_alpn_01_create(struct acme_order *order,
   1344     struct acme_challenge *challenge)
   1345 {
   1346 	struct kore_buf		auth;
   1347 	char			*thumb;
   1348 	u_int8_t		digest[SHA256_DIGEST_LENGTH];
   1349 
   1350 	if (challenge->flags & ACME_FLAG_CHALLENGE_CREATED) {
   1351 		kore_log(LOG_INFO,
   1352 		    "[%s:auth:challenge:tls-alpn-01] pending keymgr",
   1353 		    order->domain);
   1354 		return;
   1355 	}
   1356 
   1357 	challenge->flags |= ACME_FLAG_CHALLENGE_CREATED;
   1358 
   1359 	kore_log(LOG_INFO,
   1360 	    "[%s:auth:challenge:tls-alpn-01] requested from keymgr",
   1361 	    order->domain);
   1362 
   1363 	thumb = acme_thumbprint_component();
   1364 
   1365 	kore_buf_init(&auth, 128);
   1366 	kore_buf_appendf(&auth, "%s.%s", challenge->token, thumb);
   1367 	(void)SHA256(auth.data, auth.offset, digest);
   1368 
   1369 	kore_buf_cleanup(&auth);
   1370 	kore_free(thumb);
   1371 
   1372 	acme_keymgr_key_req(order->domain, digest, sizeof(digest),
   1373 	    KORE_ACME_CHALLENGE_CERT);
   1374 
   1375 	/* XXX - this maybe too fast, keymgr may not have had time. */
   1376 	acme_challenge_respond(order, challenge->url, "tls-alpn-01");
   1377 }
   1378 
   1379 static void
   1380 acme_challenge_respond(struct acme_order *order, const char *url,
   1381     const char *name)
   1382 {
   1383 	struct kore_json_item	*json;
   1384 	char			*copy;
   1385 
   1386 	kore_log(LOG_INFO, "[%s:auth:challenge:%s] submitting challenge",
   1387 	    order->domain, name);
   1388 
   1389 	copy = kore_strdup(url);
   1390 
   1391 	json = kore_json_create_object(NULL, NULL);
   1392 	acme_sign_submit(json, url, copy, acme_generic_submit);
   1393 	kore_json_item_free(json);
   1394 }
   1395 
   1396 static void
   1397 acme_generic_submit(struct acme_sign_op *op, struct kore_buf *payload)
   1398 {
   1399 	struct acme_request	req;
   1400 
   1401 	acme_request_prepare(&req, HTTP_METHOD_POST, op->udata,
   1402 	    payload->data, payload->offset);
   1403 
   1404 	if (!acme_request_run(&req))
   1405 		goto cleanup;
   1406 
   1407 	if (req.curl.http.status != HTTP_STATUS_OK) {
   1408 		kore_log(LOG_NOTICE,
   1409 		    "request to '%s' failed: status %ld - body '%s'",
   1410 		    req.curl.url, req.curl.http.status,
   1411 		    kore_curl_response_as_string(&req.curl));
   1412 		goto cleanup;
   1413 	}
   1414 
   1415 	kore_log(LOG_INFO, "submitted %zu bytes to %s",
   1416 	    payload->offset, req.curl.url);
   1417 
   1418 cleanup:
   1419 	acme_request_cleanup(&req);
   1420 }
   1421 
   1422 static void
   1423 acme_request_prepare(struct acme_request *req, int method,
   1424     const char *url, const void *data, size_t len)
   1425 {
   1426 	memset(req, 0, sizeof(*req));
   1427 
   1428 	if (!kore_curl_init(&req->curl, url, KORE_CURL_SYNC))
   1429 		fatal("failed to initialize request to '%s'", url);
   1430 
   1431 	/* Override default timeout. */
   1432 	curl_easy_setopt(req->curl.handle,
   1433 	    CURLOPT_TIMEOUT, acme_request_timeout);
   1434 
   1435 	kore_curl_http_setup(&req->curl, method, data, len);
   1436 	kore_curl_http_set_header(&req->curl, "content-type",
   1437 	    "application/jose+json");
   1438 }
   1439 
   1440 static void
   1441 acme_request_json(struct kore_buf *buf, const char *payload,
   1442     const char *protected, const char *sig)
   1443 {
   1444 	struct kore_json_item	*json;
   1445 
   1446 	json = kore_json_create_object(NULL, NULL);
   1447 
   1448 	kore_json_create_string(json, "signature", sig);
   1449 	kore_json_create_string(json, "payload", payload);
   1450 	kore_json_create_string(json, "protected", protected);
   1451 
   1452 	kore_json_item_tobuf(json, buf);
   1453 	kore_json_item_free(json);
   1454 }
   1455 
   1456 static int
   1457 acme_request_run(struct acme_request *req)
   1458 {
   1459 	size_t				len;
   1460 	struct kore_json		json;
   1461 	const u_int8_t			*body;
   1462 	struct kore_json_item		*detail;
   1463 
   1464 	kore_curl_run(&req->curl);
   1465 
   1466 	if (!kore_curl_success(&req->curl)) {
   1467 		kore_log(LOG_NOTICE, "request to '%s' failed: %s",
   1468 		    req->curl.url, kore_curl_strerror(&req->curl));
   1469 		return (KORE_RESULT_ERROR);
   1470 	}
   1471 
   1472 	if (req->curl.http.status == HTTP_STATUS_BAD_REQUEST) {
   1473 		kore_curl_response_as_bytes(&req->curl, &body, &len);
   1474 		kore_json_init(&json, body, len);
   1475 
   1476 		if (!kore_json_parse(&json)) {
   1477 			detail = NULL;
   1478 		} else {
   1479 			detail = kore_json_find_string(json.root, "detail");
   1480 		}
   1481 
   1482 		if (detail != NULL) {
   1483 			kore_log(LOG_NOTICE,
   1484 			    "request to '%s' failed with 400 - detail: %s",
   1485 			    req->curl.url, detail->data.string);
   1486 		} else {
   1487 			kore_log(LOG_NOTICE,
   1488 			    "request to '%s' failed with 400 - body: %.*s",
   1489 			    req->curl.url, (int)len, (const char *)body);
   1490 		}
   1491 
   1492 		kore_json_cleanup(&json);
   1493 		return (KORE_RESULT_ERROR);
   1494 	}
   1495 
   1496 	return (KORE_RESULT_OK);
   1497 }
   1498 
   1499 static void
   1500 acme_request_cleanup(struct acme_request *req)
   1501 {
   1502 	kore_curl_cleanup(&req->curl);
   1503 }
   1504 
   1505 static void
   1506 acme_directory_set(struct kore_json *json, const char *name, char **out)
   1507 {
   1508 	struct kore_json_item	*item;
   1509 
   1510 	if ((item = kore_json_find_string(json->root, name)) == NULL) {
   1511 		kore_log(LOG_NOTICE, "directory has missing '%s' URI", name);
   1512 		return;
   1513 	}
   1514 
   1515 	*out = kore_strdup(item->data.string);
   1516 }
   1517 
   1518 static void
   1519 acme_sign_submit(struct kore_json_item *json, const char *url, void *udata,
   1520     void (*cb)(struct acme_sign_op *, struct kore_buf *))
   1521 {
   1522 	struct acme_sign_op	*op;
   1523 	struct kore_buf		buf;
   1524 	char			*nonce;
   1525 
   1526 	if ((nonce = acme_nonce_fetch()) == NULL) {
   1527 		kore_log(LOG_ERR, "failed to fetch nonce from servers");
   1528 		return;
   1529 	}
   1530 
   1531 	kore_buf_init(&buf, 1024);
   1532 
   1533 	if (json != NULL)
   1534 		kore_json_item_tobuf(json, &buf);
   1535 
   1536 	op = kore_calloc(1, sizeof(*op));
   1537 	LIST_INSERT_HEAD(&signops, op, list);
   1538 
   1539 	op->cb = cb;
   1540 	op->udata = udata;
   1541 	op->nonce = nonce;
   1542 	op->id = signop_id++;
   1543 	op->payload = acme_base64url(buf.data, buf.offset);
   1544 	op->protected = acme_protected_component(op->nonce, url);
   1545 	op->t = kore_timer_add(acme_sign_expire, 30000, op, KORE_TIMER_ONESHOT);
   1546 
   1547 	kore_buf_reset(&buf);
   1548 	kore_buf_append(&buf, &op->id, sizeof(op->id));
   1549 	kore_buf_appendf(&buf, "%s.%s", op->protected, op->payload);
   1550 
   1551 	kore_msg_send(KORE_WORKER_KEYMGR, KORE_ACME_SIGN, buf.data, buf.offset);
   1552 	kore_buf_cleanup(&buf);
   1553 }
   1554 
   1555 static void
   1556 acme_sign_expire(void *udata, u_int64_t now)
   1557 {
   1558 	struct acme_sign_op	*op = udata;
   1559 
   1560 	kore_log(LOG_NOTICE, "signop %u expired (no answer)", op->id);
   1561 
   1562 	LIST_REMOVE(op, list);
   1563 
   1564 	kore_free(op->protected);
   1565 	kore_free(op->payload);
   1566 	kore_free(op->udata);
   1567 	kore_free(op->nonce);
   1568 	kore_free(op);
   1569 }
   1570 
   1571 static void
   1572 acme_sign_result(struct kore_msg *msg, const void *data)
   1573 {
   1574 	u_int32_t		id;
   1575 	struct kore_buf		buf;
   1576 	struct acme_sign_op	*op;
   1577 	char			*sig;
   1578 	const u_int8_t		*ptr;
   1579 
   1580 	if (msg->length < sizeof(id))
   1581 		fatal("%s: invalid length (%zu)", __func__, msg->length);
   1582 
   1583 	ptr = data;
   1584 	memcpy(&id, ptr, sizeof(id));
   1585 
   1586 	ptr += sizeof(id);
   1587 	msg->length -= sizeof(id);
   1588 
   1589 	LIST_FOREACH(op, &signops, list) {
   1590 		if (op->id == id)
   1591 			break;
   1592 	}
   1593 
   1594 	if (op == NULL) {
   1595 		kore_log(LOG_NOTICE,
   1596 		    "received KORE_ACME_SIGN_RESULT for unknown op: %u", id);
   1597 		return;
   1598 	}
   1599 
   1600 	kore_timer_remove(op->t);
   1601 	LIST_REMOVE(op, list);
   1602 
   1603 	sig = kore_malloc(msg->length + 1);
   1604 	memcpy(sig, ptr, msg->length);
   1605 	sig[msg->length] = '\0';
   1606 
   1607 	kore_buf_init(&buf, 1024);
   1608 	acme_request_json(&buf, op->payload, op->protected, sig);
   1609 
   1610 	op->cb(op, &buf);
   1611 
   1612 	kore_free(op->protected);
   1613 	kore_free(op->payload);
   1614 	kore_free(op->udata);
   1615 	kore_free(op->nonce);
   1616 	kore_free(op);
   1617 
   1618 	kore_free(sig);
   1619 	kore_buf_cleanup(&buf);
   1620 }
   1621 
   1622 static char *
   1623 acme_protected_component(const char *nonce, const char *url)
   1624 {
   1625 	char			*b64;
   1626 	struct kore_buf		payload;
   1627 	struct kore_json_item	*root, *jwk;
   1628 
   1629 	root = kore_json_create_object(NULL, NULL);
   1630 
   1631 	kore_json_create_string(root, "url", url);
   1632 	kore_json_create_string(root, "alg", "RS256");
   1633 	kore_json_create_string(root, "nonce", nonce);
   1634 
   1635 	if (account_id == NULL) {
   1636 		jwk = kore_json_create_object(root, "jwk");
   1637 		kore_json_create_string(jwk, "kty", "RSA");
   1638 		kore_json_create_string(jwk, "e", rsakey_e);
   1639 		kore_json_create_string(jwk, "n", rsakey_n);
   1640 	} else {
   1641 		kore_json_create_string(root, "kid", account_id);
   1642 	}
   1643 
   1644 	kore_buf_init(&payload, 128);
   1645 	kore_json_item_tobuf(root, &payload);
   1646 
   1647 	b64 = acme_base64url(payload.data, payload.offset);
   1648 
   1649 	kore_json_item_free(root);
   1650 	kore_buf_cleanup(&payload);
   1651 
   1652 	return (b64);
   1653 }
   1654 
   1655 static char *
   1656 acme_thumbprint_component(void)
   1657 {
   1658 	struct kore_json_item	*json;
   1659 	struct kore_buf		payload;
   1660 	u_int8_t		digest[SHA256_DIGEST_LENGTH];
   1661 
   1662 	json = kore_json_create_object(NULL, NULL);
   1663 
   1664 	/* Order matters here, see RFC7638. */
   1665 	kore_json_create_string(json, "e", rsakey_e);
   1666 	kore_json_create_string(json, "kty", "RSA");
   1667 	kore_json_create_string(json, "n", rsakey_n);
   1668 
   1669 	kore_buf_init(&payload, 128);
   1670 	kore_json_item_tobuf(json, &payload);
   1671 
   1672 	(void)SHA256(payload.data, payload.offset, digest);
   1673 
   1674 	kore_json_item_free(json);
   1675 	kore_buf_cleanup(&payload);
   1676 
   1677 	return (acme_base64url(digest, sizeof(digest)));
   1678 }
   1679 
   1680 static char *
   1681 acme_base64url(const void *data, size_t len)
   1682 {
   1683 	char		*b64;
   1684 
   1685 	if (!kore_base64url_encode(data, len, &b64, KORE_BASE64_RAW)) {
   1686 		fatal("%s: failed to encode base64url data of %zu bytes",
   1687 		    __func__, len);
   1688 	}
   1689 
   1690 	return (b64);
   1691 }
   1692 
   1693 static void
   1694 acme_keymgr_key_req(const char *domain, const void *data, size_t len, int msg)
   1695 {
   1696 	struct kore_keyreq	req;
   1697 	struct kore_buf		buf;
   1698 
   1699 	memset(&req, 0, sizeof(req));
   1700 	req.data_len = len;
   1701 
   1702 	if (kore_strlcpy(req.domain, domain, sizeof(req.domain)) >=
   1703 	    sizeof(req.domain))
   1704 		fatal("%s: domain truncated", __func__);
   1705 
   1706 	kore_buf_init(&buf, sizeof(req) + len);
   1707 	kore_buf_append(&buf, &req, sizeof(req));
   1708 
   1709 	if (data != NULL)
   1710 		kore_buf_append(&buf, data, len);
   1711 
   1712 	kore_msg_send(KORE_WORKER_KEYMGR, msg, buf.data, buf.offset);
   1713 	kore_buf_cleanup(&buf);
   1714 }
   1715 
   1716 static int
   1717 acme_status_type(const char *status)
   1718 {
   1719 	int	type;
   1720 
   1721 	if (!strcmp(status, "pending")) {
   1722 		type = ACME_STATUS_PENDING;
   1723 	} else if (!strcmp(status, "processing")) {
   1724 		type = ACME_STATUS_PROCESSING;
   1725 	} else if (!strcmp(status, "valid")) {
   1726 		type = ACME_STATUS_VALID;
   1727 	} else if (!strcmp(status, "invalid")) {
   1728 		type = ACME_STATUS_INVALID;
   1729 	} else if (!strcmp(status, "ready")) {
   1730 		type = ACME_STATUS_READY;
   1731 	} else if (!strcmp(status, "expired")) {
   1732 		type = ACME_STATUS_EXPIRED;
   1733 	} else if (!strcmp(status, "revoked")) {
   1734 		type = ACME_STATUS_REVOKED;
   1735 	} else {
   1736 		type = -1;
   1737 	}
   1738 
   1739 	return (type);
   1740 }
   1741 
   1742 static void
   1743 acme_rsakey_exp(struct kore_msg *msg, const void *data)
   1744 {
   1745 	kore_free(rsakey_e);
   1746 	rsakey_e = kore_calloc(1, msg->length + 1);
   1747 	memcpy(rsakey_e, data, msg->length);
   1748 	rsakey_e[msg->length] = '\0';
   1749 }
   1750 
   1751 static void
   1752 acme_rsakey_mod(struct kore_msg *msg, const void *data)
   1753 {
   1754 	kore_free(rsakey_n);
   1755 	rsakey_n = kore_calloc(1, msg->length + 1);
   1756 	memcpy(rsakey_n, data, msg->length);
   1757 	rsakey_n[msg->length] = '\0';
   1758 }