keymgr_openssl.c (34328B)
1 /*
2 * Copyright (c) 2017-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 * The kore keymgr process is responsible for managing certificates
19 * and their matching private keys.
20 *
21 * It is the only process in Kore that holds the private keys (the workers
22 * do not have a copy of them in memory).
23 *
24 * When a worker requires the private key for signing it will send a message
25 * to the keymgr with the to-be-signed data (KORE_MSG_KEYMGR_REQ). The keymgr
26 * will perform the signing and respond with a KORE_MSG_KEYMGR_RESP message.
27 *
28 * The keymgr can transparently reload the private keys and certificates
29 * for a configured domain when it receives a SIGUSR1. It it reloads them
30 * it will send the newly loaded certificate chains to the worker processes
31 * which will update their TLS contexts accordingly.
32 *
33 * If ACME is turned on the keymgr will also hold all account and domain
34 * keys and will initiate the process of acquiring new certificates against
35 * the ACME provider that is configured if those certificates do not exist
36 * or are expired (or are expiring soon).
37 */
38
39 #include <sys/types.h>
40 #include <sys/mman.h>
41 #include <sys/stat.h>
42
43 #include <openssl/err.h>
44 #include <openssl/evp.h>
45 #include <openssl/rsa.h>
46 #include <openssl/rand.h>
47 #include <openssl/pem.h>
48 #include <openssl/sha.h>
49 #include <openssl/x509.h>
50 #include <openssl/x509v3.h>
51
52 #include <ctype.h>
53 #include <fcntl.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <stdint.h>
57 #include <signal.h>
58 #include <unistd.h>
59
60 #include "kore.h"
61
62 #if defined(KORE_USE_ACME)
63 #include "acme.h"
64 #endif
65
66 /*
67 * Disable deprecated declaration warnings if we're building against
68 * OpenSSL 3 as they marked all low-level APIs as deprecated.
69 *
70 * Work is being done to replace these, but for now let things build.
71 */
72 #if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
73 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
74 #endif
75
76 #define RAND_TMP_FILE "rnd.tmp"
77 #define RAND_POLL_INTERVAL (1800 * 1000)
78 #define RAND_FILE_SIZE 1024
79
80 #if defined(__linux__)
81 #include "seccomp.h"
82
83 /* The syscalls our keymgr is allowed to perform, only. */
84 static struct sock_filter filter_keymgr[] = {
85 /* Deny these, but with EACCESS instead of dying. */
86 KORE_SYSCALL_DENY(ioctl, EACCES),
87
88 /* Entropy handling. */
89 #if defined(SYS_unlink)
90 KORE_SYSCALL_ALLOW(unlink),
91 #endif
92 #if defined(SYS_rename)
93 KORE_SYSCALL_ALLOW(rename),
94 #endif
95
96 /* Required to deal with private keys and certs. */
97 #if defined(SYS_open)
98 KORE_SYSCALL_ALLOW(open),
99 #endif
100 KORE_SYSCALL_ALLOW(read),
101 KORE_SYSCALL_ALLOW(lseek),
102 KORE_SYSCALL_ALLOW(write),
103 KORE_SYSCALL_ALLOW(close),
104 #if defined(SYS_stat)
105 KORE_SYSCALL_ALLOW(stat),
106 #endif
107 KORE_SYSCALL_ALLOW(fstat),
108 #if defined(SYS_stat64)
109 KORE_SYSCALL_ALLOW(stat64),
110 #endif
111 #if defined(SYS_fstat64)
112 KORE_SYSCALL_ALLOW(fstat64),
113 #endif
114 #if defined(SYS_newfstatat)
115 KORE_SYSCALL_ALLOW(newfstatat),
116 #endif
117 KORE_SYSCALL_ALLOW(futex),
118 KORE_SYSCALL_ALLOW(writev),
119 KORE_SYSCALL_ALLOW(openat),
120 #if defined(SYS_access)
121 KORE_SYSCALL_ALLOW(access),
122 #endif
123 KORE_SYSCALL_ALLOW(faccessat),
124
125 /* Net related. */
126 #if defined(SYS_poll)
127 KORE_SYSCALL_ALLOW(poll),
128 #endif
129 #if defined(SYS_send)
130 KORE_SYSCALL_ALLOW(send),
131 #endif
132 KORE_SYSCALL_ALLOW(sendto),
133 #if defined(SYS_recv)
134 KORE_SYSCALL_ALLOW(recv),
135 #endif
136 KORE_SYSCALL_ALLOW(recvfrom),
137 #if defined(SYS_epoll_wait)
138 KORE_SYSCALL_ALLOW(epoll_wait),
139 #endif
140 KORE_SYSCALL_ALLOW(epoll_pwait),
141
142 /* Process things. */
143 KORE_SYSCALL_ALLOW(exit),
144 KORE_SYSCALL_ALLOW(kill),
145 KORE_SYSCALL_ALLOW(getuid),
146 KORE_SYSCALL_ALLOW(getpid),
147 #if defined(SYS_arch_prctl)
148 KORE_SYSCALL_ALLOW(arch_prctl),
149 #endif
150 KORE_SYSCALL_ALLOW(exit_group),
151 KORE_SYSCALL_ALLOW(sigaltstack),
152 #if defined(SYS_sigreturn)
153 KORE_SYSCALL_ALLOW(sigreturn),
154 #endif
155 KORE_SYSCALL_ALLOW(rt_sigreturn),
156 KORE_SYSCALL_ALLOW(rt_sigaction),
157 KORE_SYSCALL_ALLOW(rt_sigprocmask),
158
159 /* Other things. */
160 KORE_SYSCALL_ALLOW(brk),
161 #if defined(SYS_mmap)
162 KORE_SYSCALL_ALLOW(mmap),
163 #endif
164 #if defined(SYS_mmap2)
165 KORE_SYSCALL_ALLOW(mmap2),
166 #endif
167 #if defined(SYS_madvise)
168 KORE_SYSCALL_ALLOW(madvise),
169 #endif
170 KORE_SYSCALL_ALLOW(munmap),
171 KORE_SYSCALL_ALLOW(clock_gettime),
172 #if defined(__NR_getrandom)
173 KORE_SYSCALL_ALLOW(getrandom),
174 #endif
175
176 #if defined(KORE_USE_ACME)
177 #if defined(SYS_mkdir)
178 KORE_SYSCALL_ALLOW(mkdir),
179 #endif
180 KORE_SYSCALL_ALLOW(mkdirat),
181 KORE_SYSCALL_ALLOW(umask),
182 #endif
183 };
184 #endif
185
186 struct key {
187 KORE_PRIVATE_KEY *pkey;
188 struct kore_domain *dom;
189 TAILQ_ENTRY(key) list;
190 };
191
192 /* Helper for weird API designs (looking at you OpenSSL). */
193 union deconst {
194 void *p;
195 const void *cp;
196 };
197
198 #if defined(KORE_USE_ACME)
199
200 #define ACME_ORDER_STATE_INIT 1
201 #define ACME_ORDER_STATE_SUBMIT 2
202
203 #define ACME_X509_EXPIRATION 120
204 #define ACME_TLS_ALPN_01_OID "1.3.6.1.5.5.7.1.31"
205
206 #define ACME_RENEWAL_THRESHOLD 5
207 #define ACME_RENEWAL_TIMER (3600 * 1000)
208
209 /* UTCTIME in format of YYMMDDHHMMSSZ */
210 #define ASN1_UTCTIME_LEN 13
211
212 /* GENERALIZEDTIME in format of YYYYMMDDHHMMSSZ */
213 #define ASN1_GENERALIZEDTIME_LEN 15
214
215 /* Set to 1 when we receive KORE_ACME_PROC_READY. */
216 static int acmeproc_ready = 0;
217
218 /* Renewal timer for all domains under acme control. */
219 static struct kore_timer *acme_renewal = NULL;
220
221 #ifndef NID_acmeIdentifier
222 #define NID_acmeIdentifier -1
223 #endif
224
225 /* oid for acme extension. */
226 static int acme_oid = NID_acmeIdentifier;
227
228 struct acme_order {
229 int state;
230 struct kore_timer *timer;
231 char *domain;
232 };
233
234 static char *keymgr_bignum_base64(const BIGNUM *);
235
236 static void keymgr_acme_init(void);
237 static void keymgr_acme_renewal(void *, u_int64_t);
238 static void keymgr_acme_check(struct kore_domain *);
239 static void keymgr_acme_sign(struct kore_msg *, const void *);
240 static void keymgr_acme_ready(struct kore_msg *, const void *);
241 static void keymgr_acme_domainkey(struct kore_domain *, struct key *);
242
243 static void keymgr_acme_order_create(const char *);
244 static void keymgr_acme_order_redo(void *, u_int64_t);
245 static void keymgr_acme_order_start(void *, u_int64_t);
246
247 static void keymgr_x509_ext_alt_name_dns(STACK_OF(X509_EXTENSION *),
248 const char *);
249 static void keymgr_x509_ext_acme_id(STACK_OF(X509_EXTENSION) *,
250 const void *data, size_t len);
251
252 static void keymgr_acme_csr(const struct kore_keyreq *, struct key *);
253 static void keymgr_acme_install_cert(const void *, size_t, struct key *);
254 static void keymgr_acme_order_failed(const void *, size_t, struct key *);
255 static void keymgr_acme_challenge_cert(const void *, size_t, struct key *);
256
257 static int keymgr_x509_not_after(X509 *, time_t *);
258 static int keymgr_asn1_convert_utctime(const ASN1_TIME *, time_t *);
259 static int keymgr_asn1_convert_generalizedtime(const void *,
260 size_t, time_t *);
261
262 #endif /* KORE_USE_ACME */
263
264 static void keymgr_reload(void);
265 static void keymgr_load_randfile(void);
266 static void keymgr_save_randfile(void);
267
268 static struct key *keymgr_load_privatekey(const char *);
269 static void keymgr_load_domain_privatekey(struct kore_domain *);
270
271 static void keymgr_msg_recv(struct kore_msg *, const void *);
272 static void keymgr_entropy_request(struct kore_msg *, const void *);
273 static void keymgr_certificate_request(struct kore_msg *, const void *);
274 static void keymgr_submit_certificates(struct kore_domain *, u_int16_t);
275 static void keymgr_submit_file(u_int8_t, struct kore_domain *,
276 const char *, u_int16_t, int);
277 static void keymgr_x509_msg(const char *, const void *, size_t, int, int);
278
279 static void keymgr_rsa_encrypt(struct kore_msg *, const void *,
280 struct key *);
281
282 #if defined(__OpenBSD__)
283 #if defined(KORE_USE_ACME)
284 static const char *keymgr_pledges = "stdio rpath wpath cpath";
285 #else
286 static const char *keymgr_pledges = "stdio rpath";
287 #endif
288 #endif
289
290 static TAILQ_HEAD(, key) keys;
291 static int initialized = 0;
292
293 char *kore_rand_file = NULL;
294
295 void
296 kore_keymgr_run(void)
297 {
298 int quit;
299 u_int64_t now, netwait, last_seed;
300
301 if (kore_keymgr_active == 0)
302 fatalx("%s: called with kore_keymgr_active == 0", __func__);
303
304 quit = 0;
305
306 kore_server_closeall();
307 kore_module_cleanup();
308
309 net_init();
310 kore_timer_init();
311 kore_connection_init();
312 kore_platform_event_init();
313
314 kore_msg_worker_init();
315 kore_msg_register(KORE_MSG_KEYMGR_REQ, keymgr_msg_recv);
316 kore_msg_register(KORE_MSG_ENTROPY_REQ, keymgr_entropy_request);
317 kore_msg_register(KORE_MSG_CERTIFICATE_REQ, keymgr_certificate_request);
318
319 #if defined(__linux__)
320 /* Drop all enabled seccomp filters, and add only ours. */
321 kore_seccomp_drop();
322 kore_seccomp_filter("keymgr", filter_keymgr,
323 KORE_FILTER_LEN(filter_keymgr));
324 #endif
325 #if defined(KORE_USE_PYTHON)
326 kore_msg_unregister(KORE_PYTHON_SEND_OBJ);
327 #endif
328 kore_worker_privsep();
329
330 if (kore_rand_file != NULL) {
331 keymgr_load_randfile();
332 keymgr_save_randfile();
333 } else if (!kore_quiet) {
334 kore_log(LOG_WARNING, "no rand_file location specified");
335 }
336
337 RAND_poll();
338 last_seed = 0;
339
340 initialized = 1;
341 keymgr_reload();
342
343 #if defined(__OpenBSD__)
344 if (pledge(keymgr_pledges, NULL) == -1)
345 fatalx("failed to pledge keymgr process");
346 #endif
347
348 #if defined(KORE_USE_ACME)
349 if (acme_oid == -1) {
350 acme_oid = OBJ_create(ACME_TLS_ALPN_01_OID, "acme",
351 "acmeIdentifier");
352 }
353 #endif
354
355 kore_worker_started();
356
357 while (quit != 1) {
358 now = kore_time_ms();
359 if ((now - last_seed) > RAND_POLL_INTERVAL) {
360 RAND_poll();
361 last_seed = now;
362 }
363
364 netwait = kore_timer_next_run(now);
365 kore_platform_event_wait(netwait);
366
367 if (sig_recv != 0) {
368 switch (sig_recv) {
369 case SIGQUIT:
370 case SIGINT:
371 case SIGTERM:
372 quit = 1;
373 break;
374 case SIGUSR1:
375 keymgr_reload();
376 break;
377 default:
378 break;
379 }
380 sig_recv = 0;
381 }
382
383 if (quit)
384 break;
385
386 now = kore_time_ms();
387 kore_timer_run(now);
388 kore_connection_prune(KORE_CONNECTION_PRUNE_DISCONNECT);
389 }
390
391 kore_keymgr_cleanup(1);
392 kore_platform_event_cleanup();
393 kore_connection_cleanup();
394 net_cleanup();
395 }
396
397 void
398 kore_keymgr_cleanup(int final)
399 {
400 struct key *key, *next;
401
402 if (initialized == 0)
403 return;
404
405 for (key = TAILQ_FIRST(&keys); key != NULL; key = next) {
406 next = TAILQ_NEXT(key, list);
407 TAILQ_REMOVE(&keys, key, list);
408
409 EVP_PKEY_free(key->pkey);
410 kore_free(key);
411 }
412 }
413
414 static void
415 keymgr_reload(void)
416 {
417 struct kore_server *srv;
418 struct kore_domain *dom;
419
420 if (!kore_quiet)
421 kore_log(LOG_INFO, "(re)loading certificates, keys and CRLs");
422
423 kore_keymgr_cleanup(0);
424 TAILQ_INIT(&keys);
425
426 #if defined(KORE_USE_ACME)
427 keymgr_acme_init();
428 #endif
429
430 kore_domain_callback(keymgr_load_domain_privatekey);
431
432 /* can't use kore_domain_callback() due to dst parameter. */
433 LIST_FOREACH(srv, &kore_servers, list) {
434 if (srv->tls == 0)
435 continue;
436 TAILQ_FOREACH(dom, &srv->domains, list)
437 keymgr_submit_certificates(dom, KORE_MSG_WORKER_ALL);
438 }
439 }
440
441 static void
442 keymgr_submit_certificates(struct kore_domain *dom, u_int16_t dst)
443 {
444 if (access(dom->certfile, R_OK) == -1) {
445 #if defined(KORE_USE_ACME)
446 if (dom->acme && errno == ENOENT)
447 return;
448 #endif
449 fatalx("cannot read '%s' for %s: %s",
450 dom->certfile, dom->domain, errno_s);
451 }
452
453 keymgr_submit_file(KORE_MSG_CERTIFICATE, dom, dom->certfile, dst, 0);
454
455 if (dom->crlfile != NULL)
456 keymgr_submit_file(KORE_MSG_CRL, dom, dom->crlfile, dst, 1);
457 }
458
459 static void
460 keymgr_submit_file(u_int8_t id, struct kore_domain *dom,
461 const char *file, u_int16_t dst, int can_fail)
462 {
463 int fd;
464 struct stat st;
465 u_int8_t *payload;
466
467 if ((fd = open(file, O_RDONLY)) == -1) {
468 if (errno == ENOENT && can_fail)
469 return;
470 fatalx("open(%s): %s", file, errno_s);
471 }
472
473 if (fstat(fd, &st) == -1)
474 fatalx("stat(%s): %s", file, errno_s);
475
476 if (!S_ISREG(st.st_mode))
477 fatalx("%s is not a file", file);
478
479 payload = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
480 if (payload == MAP_FAILED)
481 fatalx("mmap(): %s", errno_s);
482
483 keymgr_x509_msg(dom->domain, payload, st.st_size, dst, id);
484
485 (void)munmap(payload, st.st_size);
486 close(fd);
487 }
488
489 static void
490 keymgr_load_randfile(void)
491 {
492 int fd;
493 struct stat st;
494 ssize_t ret;
495 size_t total;
496 u_int8_t buf[RAND_FILE_SIZE];
497
498 if (kore_rand_file == NULL)
499 return;
500
501 if ((fd = open(kore_rand_file, O_RDONLY)) == -1)
502 fatalx("open(%s): %s", kore_rand_file, errno_s);
503
504 if (fstat(fd, &st) == -1)
505 fatalx("stat(%s): %s", kore_rand_file, errno_s);
506 if (!S_ISREG(st.st_mode))
507 fatalx("%s is not a file", kore_rand_file);
508 if (st.st_size != RAND_FILE_SIZE)
509 fatalx("%s has an invalid size", kore_rand_file);
510
511 total = 0;
512
513 while (total != RAND_FILE_SIZE) {
514 ret = read(fd, buf, sizeof(buf));
515 if (ret == 0)
516 fatalx("EOF on %s", kore_rand_file);
517
518 if (ret == -1) {
519 if (errno == EINTR)
520 continue;
521 fatalx("read(%s): %s", kore_rand_file, errno_s);
522 }
523
524 total += (size_t)ret;
525 RAND_seed(buf, (int)ret);
526 OPENSSL_cleanse(buf, sizeof(buf));
527 }
528
529 (void)close(fd);
530 if (unlink(kore_rand_file) == -1) {
531 kore_log(LOG_WARNING, "failed to unlink %s: %s",
532 kore_rand_file, errno_s);
533 }
534 }
535
536 static void
537 keymgr_save_randfile(void)
538 {
539 int fd;
540 struct stat st;
541 ssize_t ret;
542 u_int8_t buf[RAND_FILE_SIZE];
543
544 if (kore_rand_file == NULL)
545 return;
546
547 if (stat(RAND_TMP_FILE, &st) != -1) {
548 kore_log(LOG_WARNING, "removing stale %s file", RAND_TMP_FILE);
549 (void)unlink(RAND_TMP_FILE);
550 }
551
552 if (RAND_bytes(buf, sizeof(buf)) != 1) {
553 kore_log(LOG_WARNING, "RAND_bytes: %s", ssl_errno_s);
554 goto cleanup;
555 }
556
557 if ((fd = open(RAND_TMP_FILE,
558 O_CREAT | O_TRUNC | O_WRONLY, 0400)) == -1) {
559 kore_log(LOG_WARNING,
560 "failed to open %s: %s - random data not written",
561 RAND_TMP_FILE, errno_s);
562 goto cleanup;
563 }
564
565 ret = write(fd, buf, sizeof(buf));
566 if (ret == -1 || (size_t)ret != sizeof(buf)) {
567 kore_log(LOG_WARNING, "failed to write random data");
568 (void)close(fd);
569 (void)unlink(RAND_TMP_FILE);
570 goto cleanup;
571 }
572
573 if (close(fd) == -1)
574 kore_log(LOG_WARNING, "close(%s): %s", RAND_TMP_FILE, errno_s);
575
576 if (rename(RAND_TMP_FILE, kore_rand_file) == -1) {
577 kore_log(LOG_WARNING, "rename(%s, %s): %s",
578 RAND_TMP_FILE, kore_rand_file, errno_s);
579 (void)unlink(kore_rand_file);
580 (void)unlink(RAND_TMP_FILE);
581 }
582
583 cleanup:
584 OPENSSL_cleanse(buf, sizeof(buf));
585 }
586
587 static void
588 keymgr_load_domain_privatekey(struct kore_domain *dom)
589 {
590 struct key *key;
591
592 if (dom->server->tls == 0)
593 return;
594
595 key = keymgr_load_privatekey(dom->certkey);
596
597 if (key->pkey == NULL) {
598 #if defined(KORE_USE_ACME)
599 if (dom->acme)
600 keymgr_acme_domainkey(dom, key);
601 #endif
602 if (key->pkey == NULL) {
603 fatalx("failed to load private key for '%s' (%s)",
604 dom->domain, errno_s);
605 }
606 }
607
608 key->dom = dom;
609
610 if (!kore_quiet)
611 kore_log(LOG_INFO, "loaded private key for '%s'", dom->domain);
612 }
613
614 static struct key *
615 keymgr_load_privatekey(const char *path)
616 {
617 struct key *key;
618
619 key = kore_calloc(1, sizeof(*key));
620 TAILQ_INSERT_TAIL(&keys, key, list);
621
622 /* Caller should check if pkey was loaded. */
623 if (path)
624 key->pkey = kore_tls_rsakey_load(path);
625
626 return (key);
627 }
628
629 static void
630 keymgr_certificate_request(struct kore_msg *msg, const void *data)
631 {
632 struct kore_server *srv;
633 struct kore_domain *dom;
634
635 LIST_FOREACH(srv, &kore_servers, list) {
636 if (srv->tls == 0)
637 continue;
638 TAILQ_FOREACH(dom, &srv->domains, list)
639 keymgr_submit_certificates(dom, msg->src);
640 }
641 }
642
643 static void
644 keymgr_entropy_request(struct kore_msg *msg, const void *data)
645 {
646 u_int8_t buf[RAND_FILE_SIZE];
647
648 if (RAND_bytes(buf, sizeof(buf)) != 1) {
649 kore_log(LOG_WARNING,
650 "failed to generate entropy for worker %u: %s",
651 msg->src, ssl_errno_s);
652 return;
653 }
654
655 /* No cleanse, this stuff is leaked in the kernel path anyway. */
656 kore_msg_send(msg->src, KORE_MSG_ENTROPY_RESP, buf, sizeof(buf));
657 }
658
659 static void
660 keymgr_msg_recv(struct kore_msg *msg, const void *data)
661 {
662 const struct kore_keyreq *req;
663 struct key *key;
664
665 if (msg->length < sizeof(*req))
666 return;
667
668 req = (const struct kore_keyreq *)data;
669
670 if (msg->length != (sizeof(*req) + req->data_len))
671 return;
672
673 if (req->domain[KORE_DOMAINNAME_LEN] != '\0')
674 return;
675
676 key = NULL;
677 TAILQ_FOREACH(key, &keys, list) {
678 if (key->dom == NULL)
679 continue;
680 if (!strcmp(key->dom->domain, req->domain))
681 break;
682 }
683
684 if (key == NULL)
685 return;
686
687 switch (msg->id) {
688 case KORE_MSG_KEYMGR_REQ:
689 switch (EVP_PKEY_id(key->pkey)) {
690 case EVP_PKEY_RSA:
691 keymgr_rsa_encrypt(msg, data, key);
692 break;
693 default:
694 break;
695 }
696 break;
697 #if defined(KORE_USE_ACME)
698 case KORE_ACME_CSR_REQUEST:
699 keymgr_acme_csr(req, key);
700 break;
701 case KORE_ACME_ORDER_FAILED:
702 keymgr_acme_order_failed(req->data, req->data_len, key);
703 break;
704 case KORE_ACME_CHALLENGE_CERT:
705 keymgr_acme_challenge_cert(req->data, req->data_len, key);
706 break;
707 case KORE_ACME_INSTALL_CERT:
708 keymgr_acme_install_cert(req->data, req->data_len, key);
709 break;
710 #endif
711 }
712 }
713
714 static void
715 keymgr_rsa_encrypt(struct kore_msg *msg, const void *data, struct key *key)
716 {
717 union deconst cp;
718 int ret;
719 RSA *rsa;
720 const struct kore_keyreq *req;
721 size_t keylen;
722 u_int8_t buf[1024];
723
724 req = (const struct kore_keyreq *)data;
725 cp.cp = EVP_PKEY_get0_RSA(key->pkey);
726
727 rsa = cp.p;
728
729 keylen = RSA_size(rsa);
730 if (req->data_len > keylen || keylen > sizeof(buf))
731 return;
732
733 ret = RSA_private_encrypt(req->data_len, req->data,
734 buf, rsa, req->padding);
735 if (ret != RSA_size(rsa))
736 return;
737
738 kore_msg_send(msg->src, KORE_MSG_KEYMGR_RESP, buf, ret);
739 }
740
741 static void
742 keymgr_x509_msg(const char *domain, const void *data, size_t len,
743 int target, int msg)
744 {
745 struct kore_buf buf;
746 struct kore_x509_msg hdr;
747
748 memset(&hdr, 0, sizeof(hdr));
749
750 hdr.data_len = len;
751
752 if (kore_strlcpy(hdr.domain, domain, sizeof(hdr.domain)) >=
753 sizeof(hdr.domain))
754 fatalx("%s: domain truncated", __func__);
755
756 kore_buf_init(&buf, sizeof(hdr) + len);
757 kore_buf_append(&buf, &hdr, sizeof(hdr));
758 kore_buf_append(&buf, data, len);
759
760 kore_msg_send(target, msg, buf.data, buf.offset);
761 kore_buf_cleanup(&buf);
762 }
763
764 #if defined(KORE_USE_ACME)
765 static void
766 keymgr_acme_init(void)
767 {
768 const RSA *rsa;
769 struct key *key;
770 char *e, *n;
771 int needsreg;
772 const BIGNUM *be, *bn;
773
774 if (acme_provider == NULL)
775 return;
776
777 if (mkdir(KORE_ACME_CERTDIR, 0700) == -1) {
778 if (errno != EEXIST)
779 fatalx("mkdir(%s): %s", KORE_ACME_CERTDIR, errno_s);
780 }
781
782 umask(S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
783
784 needsreg = 0;
785 acmeproc_ready = 0;
786 key = keymgr_load_privatekey(KORE_ACME_ACCOUNT_KEY);
787
788 if (acme_renewal != NULL)
789 kore_timer_remove(acme_renewal);
790
791 acme_renewal = kore_timer_add(keymgr_acme_renewal,
792 ACME_RENEWAL_TIMER, NULL, 0);
793
794 if (key->pkey == NULL) {
795 kore_log(LOG_INFO, "generating new ACME account key");
796 key->pkey = kore_tls_rsakey_generate(KORE_ACME_ACCOUNT_KEY);
797 needsreg = 1;
798 } else {
799 kore_log(LOG_INFO, "loaded existing ACME account key");
800 }
801
802 rsa = EVP_PKEY_get0_RSA(key->pkey);
803 RSA_get0_key(rsa, &bn, &be, NULL);
804
805 e = keymgr_bignum_base64(be);
806 n = keymgr_bignum_base64(bn);
807
808 kore_msg_send(KORE_WORKER_ACME, KORE_ACME_RSAKEY_E, e, strlen(e));
809 kore_msg_send(KORE_WORKER_ACME, KORE_ACME_RSAKEY_N, n, strlen(n));
810
811 kore_free(e);
812 kore_free(n);
813
814 if (needsreg) {
815 kore_msg_send(KORE_WORKER_ACME,
816 KORE_ACME_ACCOUNT_CREATE, NULL, 0);
817 } else {
818 kore_msg_send(KORE_WORKER_ACME,
819 KORE_ACME_ACCOUNT_RESOLVE, NULL, 0);
820 }
821
822 kore_msg_register(KORE_ACME_SIGN, keymgr_acme_sign);
823 kore_msg_register(KORE_ACME_CSR_REQUEST, keymgr_msg_recv);
824 kore_msg_register(KORE_ACME_PROC_READY, keymgr_acme_ready);
825 kore_msg_register(KORE_ACME_ORDER_FAILED, keymgr_msg_recv);
826 kore_msg_register(KORE_ACME_INSTALL_CERT, keymgr_msg_recv);
827 kore_msg_register(KORE_ACME_CHALLENGE_CERT, keymgr_msg_recv);
828 }
829
830 static void
831 keymgr_acme_domainkey(struct kore_domain *dom, struct key *key)
832 {
833 char *p;
834
835 kore_log(LOG_INFO, "generated new domain key for %s", dom->domain);
836
837 if ((p = strrchr(dom->certkey, '/')) == NULL)
838 fatalx("invalid certkey path '%s'", dom->certkey);
839
840 *p = '\0';
841
842 if (mkdir(dom->certkey, 0700) == -1) {
843 if (errno != EEXIST)
844 fatalx("mkdir(%s): %s", dom->certkey, errno_s);
845 }
846
847 *p = '/';
848 key->pkey = kore_tls_rsakey_generate(dom->certkey);
849 }
850
851 static void
852 keymgr_acme_order_create(const char *domain)
853 {
854 struct acme_order *order;
855
856 order = kore_calloc(1, sizeof(*order));
857
858 order->state = ACME_ORDER_STATE_INIT;
859 order->domain = kore_strdup(domain);
860 order->timer = kore_timer_add(keymgr_acme_order_start,
861 1000, order, KORE_TIMER_ONESHOT);
862 }
863
864 static void
865 keymgr_acme_order_redo(void *udata, u_int64_t now)
866 {
867 struct kore_domain *dom = udata;
868
869 kore_log(LOG_INFO, "[%s] redoing order", dom->domain);
870 keymgr_acme_order_create(dom->domain);
871 }
872
873 static void
874 keymgr_acme_order_start(void *udata, u_int64_t now)
875 {
876 struct acme_order *order = udata;
877
878 switch (order->state) {
879 case ACME_ORDER_STATE_INIT:
880 if (acmeproc_ready == 0)
881 break;
882 order->state = ACME_ORDER_STATE_SUBMIT;
883 /* fallthrough */
884 case ACME_ORDER_STATE_SUBMIT:
885 kore_msg_send(KORE_WORKER_ACME, KORE_ACME_ORDER_CREATE,
886 order->domain, strlen(order->domain));
887 kore_free(order->domain);
888 kore_free(order);
889 order = NULL;
890 break;
891 default:
892 fatalx("%s: unknown order state %d", __func__, order->state);
893 }
894
895 if (order != NULL) {
896 order->timer = kore_timer_add(keymgr_acme_order_start,
897 5000, order, KORE_TIMER_ONESHOT);
898 }
899 }
900
901 static void
902 keymgr_acme_ready(struct kore_msg *msg, const void *data)
903 {
904 acmeproc_ready = 1;
905 kore_log(LOG_INFO, "acme process ready to receive orders");
906
907 keymgr_acme_renewal(NULL, kore_time_ms());
908 }
909
910 static void
911 keymgr_acme_check(struct kore_domain *dom)
912 {
913 FILE *fp;
914 int days;
915 X509 *x509;
916 time_t expires, now;
917
918 if (dom->acme == 0)
919 return;
920
921 if (access(dom->certfile, R_OK) == -1) {
922 if (errno == ENOENT) {
923 keymgr_acme_order_create(dom->domain);
924 return;
925 }
926 kore_log(LOG_ERR, "access(%s): %s", dom->certfile, errno_s);
927 return;
928 }
929
930 if ((fp = fopen(dom->certfile, "r")) == NULL) {
931 kore_log(LOG_ERR, "fopen(%s): %s", dom->certfile, errno_s);
932 return;
933 }
934
935 if ((x509 = PEM_read_X509(fp, NULL, NULL, NULL)) == NULL) {
936 fclose(fp);
937 kore_log(LOG_ERR, "PEM_read_X509: %s", ssl_errno_s);
938 return;
939 }
940
941 fclose(fp);
942
943 if (!keymgr_x509_not_after(x509, &expires)) {
944 X509_free(x509);
945 return;
946 }
947
948 time(&now);
949 days = (expires - now) / 86400;
950
951 kore_log(LOG_INFO, "%s certificate expires in %d days",
952 dom->domain, days);
953
954 if (days <= ACME_RENEWAL_THRESHOLD) {
955 kore_log(LOG_INFO, "%s renewing certificate", dom->domain);
956 keymgr_acme_order_create(dom->domain);
957 }
958
959 X509_free(x509);
960 }
961
962 static void
963 keymgr_acme_renewal(void *udata, u_int64_t now)
964 {
965 kore_domain_callback(keymgr_acme_check);
966 }
967
968 static void
969 keymgr_acme_sign(struct kore_msg *msg, const void *data)
970 {
971 u_int32_t id;
972 struct kore_buf buf;
973 const u_int8_t *ptr;
974 u_int8_t *sig;
975 EVP_MD_CTX *ctx;
976 struct key *key;
977 char *b64;
978 unsigned int siglen;
979
980 TAILQ_FOREACH(key, &keys, list) {
981 if (key->dom == NULL)
982 break;
983 }
984
985 if (key == NULL)
986 fatalx("%s: missing key", __func__);
987
988 if (msg->length < sizeof(id))
989 fatalx("%s: invalid length (%zu)", __func__, msg->length);
990
991 ptr = data;
992 memcpy(&id, ptr, sizeof(id));
993
994 ptr += sizeof(id);
995 msg->length -= sizeof(id);
996
997 sig = kore_calloc(1, EVP_PKEY_size(key->pkey));
998
999 if ((ctx = EVP_MD_CTX_create()) == NULL)
1000 fatalx("EVP_MD_CTX_create: %s", ssl_errno_s);
1001
1002 if (!EVP_SignInit_ex(ctx, EVP_sha256(), NULL))
1003 fatalx("EVP_SignInit_ex: %s", ssl_errno_s);
1004
1005 if (!EVP_SignUpdate(ctx, ptr, msg->length))
1006 fatalx("EVP_SignUpdate: %s", ssl_errno_s);
1007
1008 if (!EVP_SignFinal(ctx, sig, &siglen, key->pkey))
1009 fatalx("EVP_SignFinal: %s", ssl_errno_s);
1010
1011 if (!kore_base64url_encode(sig, siglen, &b64, KORE_BASE64_RAW))
1012 fatalx("%s: failed to b64url encode signed data", __func__);
1013
1014 kore_buf_init(&buf, siglen + sizeof(id));
1015 kore_buf_append(&buf, &id, sizeof(id));
1016 kore_buf_append(&buf, b64, strlen(b64));
1017
1018 kore_msg_send(KORE_WORKER_ACME,
1019 KORE_ACME_SIGN_RESULT, buf.data, buf.offset);
1020
1021 EVP_MD_CTX_destroy(ctx);
1022
1023 kore_free(sig);
1024 kore_free(b64);
1025 kore_buf_cleanup(&buf);
1026 }
1027
1028 static void
1029 keymgr_acme_install_cert(const void *data, size_t len, struct key *key)
1030 {
1031 int fd;
1032 ssize_t ret;
1033
1034 fd = open(key->dom->certfile, O_CREAT | O_TRUNC | O_WRONLY, 0700);
1035 if (fd == -1)
1036 fatalx("open(%s): %s", key->dom->certfile, errno_s);
1037
1038 kore_log(LOG_INFO, "writing %zu bytes of data", len);
1039
1040 for (;;) {
1041 ret = write(fd, data, len);
1042 if (ret == -1) {
1043 if (errno == EINTR)
1044 continue;
1045 fatalx("write(%s): %s", key->dom->certfile, errno_s);
1046 }
1047
1048 break;
1049 }
1050
1051 if ((size_t)ret != len) {
1052 fatalx("incorrect write on %s (%zd/%zu)",
1053 key->dom->certfile, ret, len);
1054 }
1055
1056 if (close(fd) == -1) {
1057 kore_log(LOG_NOTICE,
1058 "close error on '%s' (%s)", key->dom->certfile, errno_s);
1059 }
1060
1061 keymgr_submit_certificates(key->dom, KORE_MSG_WORKER_ALL);
1062
1063 keymgr_x509_msg(key->dom->domain, NULL, 0,
1064 KORE_MSG_WORKER_ALL, KORE_ACME_CHALLENGE_CLEAR_CERT);
1065 }
1066
1067 static void
1068 keymgr_acme_order_failed(const void *data, size_t len, struct key *key)
1069 {
1070 u_int32_t retry;
1071
1072 if (len != sizeof(retry)) {
1073 kore_log(LOG_ERR, "%s: invalid payload (%zu)", __func__, len);
1074 return;
1075 }
1076
1077 memcpy(&retry, data, len);
1078
1079 kore_timer_add(keymgr_acme_order_redo, retry, key->dom,
1080 KORE_TIMER_ONESHOT);
1081 }
1082
1083 static void
1084 keymgr_acme_challenge_cert(const void *data, size_t len, struct key *key)
1085 {
1086 STACK_OF(X509_EXTENSION) *sk;
1087 time_t now;
1088 X509_EXTENSION *ext;
1089 X509_NAME *name;
1090 X509 *x509;
1091 int slen, i;
1092 u_int8_t *cert, *uptr;
1093
1094 kore_log(LOG_INFO, "[%s] generating tls-alpn-01 challenge cert",
1095 key->dom->domain);
1096
1097 if (len != SHA256_DIGEST_LENGTH)
1098 fatalx("invalid digest length of %zu bytes", len);
1099
1100 if ((x509 = X509_new()) == NULL)
1101 fatalx("X509_new(): %s", ssl_errno_s);
1102
1103 if (!X509_set_version(x509, 2))
1104 fatalx("X509_set_version(): %s", ssl_errno_s);
1105
1106 time(&now);
1107 if (!ASN1_INTEGER_set(X509_get_serialNumber(x509), now))
1108 fatalx("ASN1_INTEGER_set(): %s", ssl_errno_s);
1109
1110 if (!X509_gmtime_adj(X509_get_notBefore(x509), 0))
1111 fatalx("X509_gmtime_adj(): %s", ssl_errno_s);
1112
1113 if (!X509_gmtime_adj(X509_get_notAfter(x509), ACME_X509_EXPIRATION))
1114 fatalx("X509_gmtime_adj(): %s", ssl_errno_s);
1115
1116 if (!X509_set_pubkey(x509, key->pkey))
1117 fatalx("X509_set_pubkey(): %s", ssl_errno_s);
1118
1119 if ((name = X509_get_subject_name(x509)) == NULL)
1120 fatalx("X509_get_subject_name(): %s", ssl_errno_s);
1121
1122 if (!X509_NAME_add_entry_by_txt(name, "CN",
1123 MBSTRING_ASC, (const unsigned char *)key->dom->domain, -1, -1, 0))
1124 fatalx("X509_NAME_add_entry_by_txt(): CN %s", ssl_errno_s);
1125
1126 if (!X509_set_issuer_name(x509, name))
1127 fatalx("X509_set_issuer_name(): %s", ssl_errno_s);
1128
1129 sk = sk_X509_EXTENSION_new_null();
1130 keymgr_x509_ext_acme_id(sk, data, len);
1131 keymgr_x509_ext_alt_name_dns(sk, key->dom->domain);
1132
1133 for (i = 0; i < sk_X509_EXTENSION_num(sk); i++) {
1134 ext = sk_X509_EXTENSION_value(sk, i);
1135 if (!X509_add_ext(x509, ext, 0))
1136 fatalx("X509_add_ext(): %s", ssl_errno_s);
1137 }
1138
1139 if (!X509_sign(x509, key->pkey, EVP_sha256()))
1140 fatalx("X509_sign(): %s", ssl_errno_s);
1141
1142 if ((slen = i2d_X509(x509, NULL)) <= 0)
1143 fatalx("i2d_X509: %s", ssl_errno_s);
1144
1145 cert = kore_calloc(1, slen);
1146 uptr = cert;
1147
1148 if (i2d_X509(x509, &uptr) <= 0)
1149 fatalx("i2d_X509: %s", ssl_errno_s);
1150
1151 keymgr_x509_msg(key->dom->domain, cert, slen,
1152 KORE_MSG_WORKER_ALL, KORE_ACME_CHALLENGE_SET_CERT);
1153
1154 kore_free(cert);
1155 X509_free(x509);
1156 sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
1157 }
1158
1159 static void
1160 keymgr_acme_csr(const struct kore_keyreq *req, struct key *key)
1161 {
1162 int len;
1163 STACK_OF(X509_EXTENSION) *sk;
1164 X509_REQ *csr;
1165 X509_NAME *name;
1166 u_int8_t *data, *uptr;
1167
1168 kore_log(LOG_INFO, "[%s] creating CSR", req->domain);
1169
1170 if ((csr = X509_REQ_new()) == NULL)
1171 fatalx("X509_REQ_new: %s", ssl_errno_s);
1172
1173 if (!X509_REQ_set_version(csr, 3))
1174 fatalx("X509_REQ_set_version(): %s", ssl_errno_s);
1175
1176 if (!X509_REQ_set_pubkey(csr, key->pkey))
1177 fatalx("X509_REQ_set_pubkey(): %s", ssl_errno_s);
1178
1179 if ((name = X509_REQ_get_subject_name(csr)) == NULL)
1180 fatalx("X509_REQ_get_subject_name(): %s", ssl_errno_s);
1181
1182 if (!X509_NAME_add_entry_by_txt(name, "CN",
1183 MBSTRING_ASC, (const unsigned char *)key->dom->domain, -1, -1, 0))
1184 fatalx("X509_NAME_add_entry_by_txt(): %s", ssl_errno_s);
1185
1186 sk = sk_X509_EXTENSION_new_null();
1187 keymgr_x509_ext_alt_name_dns(sk, key->dom->domain);
1188
1189 if (!X509_REQ_add_extensions(csr, sk))
1190 fatalx("X509_REQ_add_extensions(): %s", ssl_errno_s);
1191
1192 if (!X509_REQ_sign(csr, key->pkey, EVP_sha256()))
1193 fatalx("X509_REQ_sign(): %s", ssl_errno_s);
1194
1195 if ((len = i2d_X509_REQ(csr, NULL)) <= 0)
1196 fatalx("i2d_X509_REQ: %s", ssl_errno_s);
1197
1198 data = kore_calloc(1, len);
1199 uptr = data;
1200
1201 if (i2d_X509_REQ(csr, &uptr) <= 0)
1202 fatalx("i2d_X509_REQ: %s", ssl_errno_s);
1203
1204 keymgr_x509_msg(key->dom->domain, data, len,
1205 KORE_WORKER_ACME, KORE_ACME_CSR_RESPONSE);
1206
1207 kore_free(data);
1208 X509_REQ_free(csr);
1209
1210 sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
1211 }
1212
1213 static void
1214 keymgr_x509_ext_alt_name_dns(STACK_OF(X509_EXTENSION) *sk,
1215 const char *dns_name)
1216 {
1217 ASN1_IA5STRING *ia5;
1218 X509_EXTENSION *ext;
1219 GENERAL_NAME *gen;
1220 GENERAL_NAMES *gens;
1221
1222 if ((ia5 = ASN1_IA5STRING_new()) == NULL)
1223 fatalx("ASN1_IA5STRING_new(): %s", ssl_errno_s);
1224
1225 if (!ASN1_STRING_set(ia5, dns_name, -1))
1226 fatalx("ASN1_STRING_set(): %s", ssl_errno_s);
1227
1228 if ((gen = GENERAL_NAME_new()) == NULL)
1229 fatalx("GENERAL_NAME_new(): %s", ssl_errno_s);
1230
1231 GENERAL_NAME_set0_value(gen, GEN_DNS, ia5);
1232
1233 if ((gens = GENERAL_NAMES_new()) == NULL)
1234 fatalx("GENERAL_NAMES_new(): %s", ssl_errno_s);
1235
1236 if (!sk_GENERAL_NAME_push(gens, gen))
1237 fatalx("sk_GENERAL_NAME_push(): %s", ssl_errno_s);
1238
1239 ext = X509V3_EXT_i2d(NID_subject_alt_name, 0, gens);
1240 if (ext == NULL)
1241 fatalx("X509V3_EXT_i2d(): %s", ssl_errno_s);
1242
1243 GENERAL_NAMES_free(gens);
1244
1245 if (!sk_X509_EXTENSION_push(sk, ext))
1246 fatalx("sk_X509_EXTENSION_push(): %s", ssl_errno_s);
1247 }
1248
1249 static void
1250 keymgr_x509_ext_acme_id(STACK_OF(X509_EXTENSION) *sk, const void *data,
1251 size_t len)
1252 {
1253 ASN1_OCTET_STRING *aos;
1254 X509_EXTENSION *ext;
1255 unsigned char *der;
1256 int der_len;
1257
1258 if (len != SHA256_DIGEST_LENGTH)
1259 fatalx("invalid digest length of %zu bytes", len);
1260
1261 if ((aos = ASN1_OCTET_STRING_new()) == NULL)
1262 fatalx("ASN1_OCTET_STRING_new(): %s", ssl_errno_s);
1263
1264 if (!ASN1_STRING_set(aos, data, len))
1265 fatalx("ASN1_STRING_set(): %s", ssl_errno_s);
1266
1267 der = NULL;
1268 der_len = i2d_ASN1_OCTET_STRING(aos, &der);
1269 if (der_len <= 0)
1270 fatalx("i2d_ASN1_OCTET_STRING(): %s", ssl_errno_s);
1271
1272 if (!ASN1_STRING_set(aos, der, der_len))
1273 fatalx("ASN1_STRING_set(): %s", ssl_errno_s);
1274
1275 free(der);
1276
1277 ext = X509_EXTENSION_create_by_NID(NULL, acme_oid, 1, aos);
1278 if (ext == NULL)
1279 fatalx("X509_EXTENSION_create_by_NID(): %s", ssl_errno_s);
1280
1281 ASN1_OCTET_STRING_free(aos);
1282
1283 if (!sk_X509_EXTENSION_push(sk, ext))
1284 fatalx("sk_X509_EXTENSION_push(): %s", ssl_errno_s);
1285 }
1286
1287 static char *
1288 keymgr_bignum_base64(const BIGNUM *bn)
1289 {
1290 int len;
1291 void *buf;
1292 char *encoded;
1293
1294 len = BN_num_bytes(bn);
1295 buf = kore_calloc(1, len);
1296
1297 if (BN_bn2bin(bn, buf) != len)
1298 fatalx("BN_bn2bin: %s", ssl_errno_s);
1299
1300 if (!kore_base64url_encode(buf, len, &encoded, KORE_BASE64_RAW))
1301 fatalx("failed to base64 encode BIGNUM");
1302
1303 return (encoded);
1304 }
1305
1306 static int
1307 keymgr_x509_not_after(X509 *x509, time_t *out)
1308 {
1309 const ASN1_TIME *na;
1310 int ret;
1311
1312 ret = KORE_RESULT_ERROR;
1313
1314 if ((na = X509_get_notAfter(x509)) == NULL) {
1315 kore_log(LOG_ERR, "no notAfter date in x509");
1316 return (KORE_RESULT_ERROR);
1317 }
1318
1319 switch (na->type) {
1320 case V_ASN1_UTCTIME:
1321 ret = keymgr_asn1_convert_utctime(na, out);
1322 break;
1323 case V_ASN1_GENERALIZEDTIME:
1324 ret = keymgr_asn1_convert_generalizedtime(na->data,
1325 na->length, out);
1326 break;
1327 default:
1328 kore_log(LOG_ERR, "invalid notAfter type (%d)", na->type);
1329 break;
1330 }
1331
1332 return (ret);
1333 }
1334
1335 static int
1336 keymgr_asn1_convert_utctime(const ASN1_TIME *na, time_t *out)
1337 {
1338 int len, year;
1339 char buf[ASN1_GENERALIZEDTIME_LEN + 1];
1340
1341 if (na->length != ASN1_UTCTIME_LEN) {
1342 kore_log(LOG_ERR, "invalid UTCTIME: too short (%d)",
1343 na->length);
1344 return (KORE_RESULT_ERROR);
1345 }
1346
1347 if (!isdigit(na->data[0]) || !isdigit(na->data[1])) {
1348 kore_log(LOG_ERR, "invalid UTCTIME: YY are not digits");
1349 return (KORE_RESULT_ERROR);
1350 }
1351
1352 year = (na->data[0] - '0') * 10 + (na->data[1] - '0');
1353
1354 /* RFC 5280 says years >= 50 are interpreted as 19YY */
1355 if (year >= 50)
1356 year = 1900 + year;
1357 else
1358 year = 2000 + year;
1359
1360 /* Convert it to GENERALIZEDTIME format and call that parser. */
1361 len = snprintf(buf, sizeof(buf), "%04d%.*s", year,
1362 na->length - 2, (const char *)na->data+ 2);
1363 if (len == -1 || (size_t)len >= sizeof(buf)) {
1364 kore_log(LOG_ERR, "invalid UTCTIME: failed to convert");
1365 return (KORE_RESULT_ERROR);
1366 }
1367
1368 return (keymgr_asn1_convert_generalizedtime(buf, len, out));
1369 }
1370
1371 static int
1372 keymgr_asn1_convert_generalizedtime(const void *ptr, size_t len, time_t *out)
1373 {
1374 size_t i;
1375 struct tm tm;
1376 const u_int8_t *buf;
1377
1378 if (len != ASN1_GENERALIZEDTIME_LEN) {
1379 kore_log(LOG_ERR, "invalid GENERALIZEDTIME: too short (%zu)",
1380 len);
1381 return (KORE_RESULT_ERROR);
1382 }
1383
1384 buf = ptr;
1385
1386 for (i = 0; i < len - 1; i++) {
1387 if (!isdigit(buf[i])) {
1388 kore_log(LOG_ERR,
1389 "invalid GENERALIZEDTIME: invalid bytes");
1390 return (KORE_RESULT_ERROR);
1391 }
1392 }
1393
1394 /* RFC 5280 states that Zulu time must be used (Z). */
1395 if (buf[i] != 'Z') {
1396 kore_log(LOG_ERR, "invalid GENERALIZEDTIME: not Zulu time");
1397 return (KORE_RESULT_ERROR);
1398 }
1399
1400 memset(&tm, 0, sizeof(tm));
1401
1402 tm.tm_year = (buf[0] - '0') * 1000 + (buf[1] - '0') * 100 +
1403 (buf[2] - '0') * 10 + (buf[3] - '0');
1404
1405 tm.tm_mon = (buf[4] - '0') * 10 + (buf[5] - '0');
1406 tm.tm_mday = (buf[6] - '0') * 10 + (buf[7] - '0');
1407 tm.tm_hour = (buf[8] - '0') * 10 + (buf[9] - '0');
1408 tm.tm_min = (buf[10] - '0') * 10 + (buf[11] - '0');
1409 tm.tm_sec = (buf[12] - '0') * 10 + (buf[13] - '0');
1410
1411 tm.tm_mon = tm.tm_mon - 1;
1412 tm.tm_year = tm.tm_year - 1900;
1413
1414 *out = mktime(&tm);
1415
1416 return (KORE_RESULT_OK);
1417 }
1418 #endif