From 92e1ffcc10845a78775e02c8fe4486a616cd137d Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Sat, 15 Apr 2023 10:03:31 +0200 Subject: [PATCH 01/10] remove -f from the cli, it is default. --- src/cli.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cli.c b/src/cli.c index 59a466e..cdb05a1 100644 --- a/src/cli.c +++ b/src/cli.c @@ -234,7 +234,7 @@ static void cli_file_create(const char *, const char *, size_t); static struct cmd cmds[] = { { "help", "this help text", cli_help }, - { "run", "run an application (-fnr implied)", cli_run }, + { "run", "run an application (-nr implied)", cli_run }, { "gen", "generate asset file for compilation", cli_genasset }, { "reload", "reload the application (SIGHUP)", cli_reload }, { "info", "show info on kore on this system", cli_info }, @@ -1824,10 +1824,10 @@ cli_run_kore(void) if (bopt->single_binary) { cpath = NULL; - flags = "-fnr"; + flags = "-nr"; (void)cli_vasprintf(&cmd, "./%s", appl); } else { - flags = "-fnrc"; + flags = "-nrc"; (void)cli_vasprintf(&cmd, "%s/bin/kore", prefix); (void)cli_vasprintf(&cpath, "conf/%s.conf", appl); } From 4fe2baee57bf7eefefacec20ca5f4c7a1fccd909 Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Thu, 7 Sep 2023 11:10:50 +0200 Subject: [PATCH 02/10] sync syscall lists from linux --- misc/linux/aarch64_syscall.h.in | 13 ++++++++++++- misc/linux/arm_syscall.h.in | 33 ++++++++++++++++++++++----------- misc/linux/x86_64_syscall.h.in | 13 ++++++++++++- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/misc/linux/aarch64_syscall.h.in b/misc/linux/aarch64_syscall.h.in index 47d1d51..5f420e6 100644 --- a/misc/linux/aarch64_syscall.h.in +++ b/misc/linux/aarch64_syscall.h.in @@ -287,5 +287,16 @@ #define __NR_fsconfig 431 #define __NR_fsmount 432 #define __NR_fspick 433 -#define __NR_clone3 435 +#define __NR_pidfd_open 434 +#define __NR_clone3 435 +#define __NR_close_range 436 +#define __NR_openat2 437 +#define __NR_pidfd_getfd 438 +#define __NR_faccessat2 439 +#define __NR_process_madvise 440 +#define __NR_epoll_pwait2 441 +#define __NR_mount_setattr 442 +#define __NR_landlock_create_ruleset 444 +#define __NR_landlock_add_rule 445 +#define __NR_landlock_restrict_self 446 diff --git a/misc/linux/arm_syscall.h.in b/misc/linux/arm_syscall.h.in index 86334ed..048fdea 100644 --- a/misc/linux/arm_syscall.h.in +++ b/misc/linux/arm_syscall.h.in @@ -55,8 +55,8 @@ #define __NR_sethostname 74 #define __NR_setrlimit 75 #define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 +#define __NR_gettimeofday_time32 78 +#define __NR_settimeofday_time32 79 #define __NR_getgroups 80 #define __NR_setgroups 81 #define __NR_symlink 83 @@ -211,14 +211,14 @@ #define __NR_remap_file_pages 253 #define __NR_set_tid_address 256 #define __NR_timer_create 257 -#define __NR_timer_settime 258 -#define __NR_timer_gettime 259 +#define __NR_timer_settime32 258 +#define __NR_timer_gettime32 259 #define __NR_timer_getoverrun 260 #define __NR_timer_delete 261 -#define __NR_clock_settime 262 -#define __NR_clock_gettime 263 -#define __NR_clock_getres 264 -#define __NR_clock_nanosleep 265 +#define __NR_clock_settime32 262 +#define __NR_clock_gettime32 263 +#define __NR_clock_getres_time32 264 +#define __NR_clock_nanosleep_time32 265 #define __NR_statfs64 266 #define __NR_fstatfs64 267 #define __NR_tgkill 268 @@ -308,8 +308,8 @@ #define __NR_timerfd_create 350 #define __NR_eventfd 351 #define __NR_fallocate 352 -#define __NR_timerfd_settime 353 -#define __NR_timerfd_gettime 354 +#define __NR_timerfd_settime32 353 +#define __NR_timerfd_gettime32 354 #define __NR_signalfd4 355 #define __NR_eventfd2 356 #define __NR_epoll_create1 357 @@ -387,7 +387,18 @@ #define __NR_fsconfig 431 #define __NR_fsmount 432 #define __NR_fspick 433 -#define __NR_clone3 435 +#define __NR_pidfd_open 434 +#define __NR_clone3 435 +#define __NR_close_range 436 +#define __NR_openat2 437 +#define __NR_pidfd_getfd 438 +#define __NR_faccessat2 439 +#define __NR_process_madvise 440 +#define __NR_epoll_pwait2 441 +#define __NR_mount_setattr 442 +#define __NR_landlock_create_ruleset 444 +#define __NR_landlock_add_rule 445 +#define __NR_landlock_restrict_self 446 #define __ARM_NR_breakpoint 0x0f0001 #define __ARM_NR_cacheflush 0x0f0002 diff --git a/misc/linux/x86_64_syscall.h.in b/misc/linux/x86_64_syscall.h.in index d2cab06..c3882de 100644 --- a/misc/linux/x86_64_syscall.h.in +++ b/misc/linux/x86_64_syscall.h.in @@ -343,5 +343,16 @@ #define __NR_fsconfig 431 #define __NR_fsmount 432 #define __NR_fspick 433 -#define __NR_clone3 435 +#define __NR_pidfd_open 434 +#define __NR_clone3 435 +#define __NR_close_range 436 +#define __NR_openat2 437 +#define __NR_pidfd_getfd 438 +#define __NR_faccessat2 439 +#define __NR_process_madvise 440 +#define __NR_epoll_pwait2 441 +#define __NR_mount_setattr 442 +#define __NR_landlock_create_ruleset 444 +#define __NR_landlock_add_rule 445 +#define __NR_landlock_restrict_self 446 From dad6cc7bfe1e922fc44308c96d9cb66d6b7aa78f Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Fri, 3 Nov 2023 12:25:39 +0100 Subject: [PATCH 03/10] remove const from kore_runtime_count(). via some github PR, please don't make me interact with github too much. --- include/kore/kore.h | 2 +- src/runtime.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/kore/kore.h b/include/kore/kore.h index c09d8eb..d13a65b 100644 --- a/include/kore/kore.h +++ b/include/kore/kore.h @@ -1028,7 +1028,7 @@ int kore_route_lookup(struct http_request *, #endif /* runtime.c */ -const size_t kore_runtime_count(void); +size_t kore_runtime_count(void); struct kore_runtime_call *kore_runtime_getcall(const char *); struct kore_module *kore_module_load(const char *, const char *, int); diff --git a/src/runtime.c b/src/runtime.c index 8b942cb..4ed8dea 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -76,7 +76,7 @@ static struct kore_runtime *runtimes[] = { NULL }; -const size_t +size_t kore_runtime_count(void) { return ((sizeof(runtimes) / sizeof(runtimes[0])) - 1); From ff5a3982cec8ab5eeabf487788663a2097fd2ea1 Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Tue, 28 Nov 2023 09:22:05 +0100 Subject: [PATCH 04/10] Add unlink and rename system calls to whitelist. The keymgr uses these when handling entropy files. --- src/keymgr_openssl.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/keymgr_openssl.c b/src/keymgr_openssl.c index d9c4084..c9bfc6a 100644 --- a/src/keymgr_openssl.c +++ b/src/keymgr_openssl.c @@ -85,6 +85,14 @@ static struct sock_filter filter_keymgr[] = { /* Deny these, but with EACCESS instead of dying. */ KORE_SYSCALL_DENY(ioctl, EACCES), + /* Entropy handling. */ +#if defined(SYS_unlink) + KORE_SYSCALL_ALLOW(unlink), +#endif +#if defined(SYS_rename) + KORE_SYSCALL_ALLOW(rename), +#endif + /* Required to deal with private keys and certs. */ #if defined(SYS_open) KORE_SYSCALL_ALLOW(open), From 4df120704db7a29884ed8dfe7e10b384ec0e3117 Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Tue, 28 Nov 2023 09:23:08 +0100 Subject: [PATCH 05/10] Add stat64() to keymgr seccomp whitelist. --- src/keymgr_openssl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/keymgr_openssl.c b/src/keymgr_openssl.c index c9bfc6a..94c331b 100644 --- a/src/keymgr_openssl.c +++ b/src/keymgr_openssl.c @@ -105,6 +105,9 @@ static struct sock_filter filter_keymgr[] = { KORE_SYSCALL_ALLOW(stat), #endif KORE_SYSCALL_ALLOW(fstat), +#if defined(SYS_stat64) + KORE_SYSCALL_ALLOW(stat64), +#endif #if defined(SYS_fstat64) KORE_SYSCALL_ALLOW(fstat64), #endif From f47f8d3f5e31b789a3a22ea439d10e1dbba8cf3c Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Fri, 1 Dec 2023 00:33:18 +0100 Subject: [PATCH 06/10] Missing options for HTTP method restrictions. While Kore supports the OPTIONS method, it was not possible to specify this in the route methods configuration. Pointed out via discord. --- src/config.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/config.c b/src/config.c index 3bc2109..2c154ef 100644 --- a/src/config.c +++ b/src/config.c @@ -1255,6 +1255,8 @@ configure_route_methods(char *options) current_route->methods |= HTTP_METHOD_HEAD; } else if (!strcasecmp(argv[i], "patch")) { current_route->methods |= HTTP_METHOD_PATCH; + } else if (!strcasecmp(argv[i], "options")) { + current_route->methods |= HTTP_METHOD_OPTIONS; } else { kore_log(LOG_ERR, "unknown method: %s in method for %s", argv[i], current_route->path); From 3d88ea442e1d4afbe2099ba1bb6b14727b821802 Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Fri, 8 Dec 2023 07:46:25 +0100 Subject: [PATCH 07/10] double acme timeout. helps when having large installations of certs renewing at the same time. --- src/acme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/acme.c b/src/acme.c index 08c2cb5..16693c6 100644 --- a/src/acme.c +++ b/src/acme.c @@ -157,7 +157,7 @@ struct acme_auth { #define ACME_ORDER_STATE_FETCH_CERT 7 #define ACME_ORDER_STATE_COMPLETE 8 #define ACME_ORDER_TICK 1000 -#define ACME_ORDER_TIMEOUT 120000 +#define ACME_ORDER_TIMEOUT 240000 #define ACME_ORDER_CSR_REQUESTED 0x1000 From 16e283e932c5833fea8ee9f8f3d726400a6cb173 Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Sun, 14 Jan 2024 13:01:23 +0100 Subject: [PATCH 08/10] Tabs are ok when decoding post data. --- src/http.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http.c b/src/http.c index 626bf06..1b3b34e 100644 --- a/src/http.c +++ b/src/http.c @@ -1051,7 +1051,7 @@ http_argument_urldecode(char *arg, int url) return (KORE_RESULT_ERROR); } else { if ((v <= 0x1f || v == 0x7f) && - (v != '\n' && v != '\r')) + (v != '\n' && v != '\r' && v != '\t')) return (KORE_RESULT_ERROR); } From 2179c5e5d3406b7f988de94b1f52edeb06cd06a6 Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Thu, 25 Jan 2024 18:23:43 +0100 Subject: [PATCH 09/10] Get rid of X509V3_EXT_add_alias(). The code shuffling to avoid using this is a bit more complex but in the end perhaps a more sane approach. diff from tb@ with minor cleanups from me --- src/keymgr_openssl.c | 113 +++++++++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 35 deletions(-) diff --git a/src/keymgr_openssl.c b/src/keymgr_openssl.c index 94c331b..0f04496 100644 --- a/src/keymgr_openssl.c +++ b/src/keymgr_openssl.c @@ -218,8 +218,12 @@ static int acmeproc_ready = 0; /* Renewal timer for all domains under acme control. */ static struct kore_timer *acme_renewal = NULL; +#ifndef NID_acmeIdentifier +#define NID_acmeIdentifier -1 +#endif + /* oid for acme extension. */ -static int acme_oid = -1; +static int acme_oid = NID_acmeIdentifier; struct acme_order { int state; @@ -240,9 +244,10 @@ static void keymgr_acme_order_create(const char *); static void keymgr_acme_order_redo(void *, u_int64_t); static void keymgr_acme_order_start(void *, u_int64_t); -static void keymgr_x509_ext(STACK_OF(X509_EXTENSION) *, - int, const char *, ...) - __attribute__((format (printf, 3, 4))); +static void keymgr_x509_ext_alt_name_dns(STACK_OF(X509_EXTENSION *), + const char *); +static void keymgr_x509_ext_acme_id(STACK_OF(X509_EXTENSION) *, + const void *data, size_t len); static void keymgr_acme_csr(const struct kore_keyreq *, struct key *); static void keymgr_acme_install_cert(const void *, size_t, struct key *); @@ -341,8 +346,10 @@ kore_keymgr_run(void) #endif #if defined(KORE_USE_ACME) - acme_oid = OBJ_create(ACME_TLS_ALPN_01_OID, "acme", "acmeIdentifier"); - X509V3_EXT_add_alias(acme_oid, NID_subject_key_identifier); + if (acme_oid == -1) { + acme_oid = OBJ_create(ACME_TLS_ALPN_01_OID, "acme", + "acmeIdentifier"); + } #endif kore_worker_started(); @@ -1077,15 +1084,12 @@ static void keymgr_acme_challenge_cert(const void *data, size_t len, struct key *key) { STACK_OF(X509_EXTENSION) *sk; - size_t idx; time_t now; X509_EXTENSION *ext; X509_NAME *name; X509 *x509; - const u_int8_t *digest; int slen, i; u_int8_t *cert, *uptr; - char hex[(SHA256_DIGEST_LENGTH * 2) + 1]; kore_log(LOG_INFO, "[%s] generating tls-alpn-01 challenge cert", key->dom->domain); @@ -1093,15 +1097,6 @@ keymgr_acme_challenge_cert(const void *data, size_t len, struct key *key) if (len != SHA256_DIGEST_LENGTH) fatalx("invalid digest length of %zu bytes", len); - digest = data; - - for (idx = 0; idx < SHA256_DIGEST_LENGTH; idx++) { - slen = snprintf(hex + (idx * 2), sizeof(hex) - (idx * 2), - "%02x", digest[idx]); - if (slen == -1 || (size_t)slen >= sizeof(hex)) - fatalx("failed to convert digest to hex"); - } - if ((x509 = X509_new()) == NULL) fatalx("X509_new(): %s", ssl_errno_s); @@ -1132,8 +1127,8 @@ keymgr_acme_challenge_cert(const void *data, size_t len, struct key *key) fatalx("X509_set_issuer_name(): %s", ssl_errno_s); sk = sk_X509_EXTENSION_new_null(); - keymgr_x509_ext(sk, acme_oid, "critical,%s", hex); - keymgr_x509_ext(sk, NID_subject_alt_name, "DNS:%s", key->dom->domain); + keymgr_x509_ext_acme_id(sk, data, len); + keymgr_x509_ext_alt_name_dns(sk, key->dom->domain); for (i = 0; i < sk_X509_EXTENSION_num(sk); i++) { ext = sk_X509_EXTENSION_value(sk, i); @@ -1189,7 +1184,7 @@ keymgr_acme_csr(const struct kore_keyreq *req, struct key *key) fatalx("X509_NAME_add_entry_by_txt(): %s", ssl_errno_s); sk = sk_X509_EXTENSION_new_null(); - keymgr_x509_ext(sk, NID_subject_alt_name, "DNS:%s", key->dom->domain); + keymgr_x509_ext_alt_name_dns(sk, key->dom->domain); if (!X509_REQ_add_extensions(csr, sk)) fatalx("X509_REQ_add_extensions(): %s", ssl_errno_s); @@ -1216,26 +1211,74 @@ keymgr_acme_csr(const struct kore_keyreq *req, struct key *key) } static void -keymgr_x509_ext(STACK_OF(X509_EXTENSION) *sk, int extnid, const char *fmt, ...) +keymgr_x509_ext_alt_name_dns(STACK_OF(X509_EXTENSION) *sk, + const char *dns_name) { - int len; - va_list args; + ASN1_IA5STRING *ia5; + GENERAL_NAME *gen; + GENERAL_NAMES *gens; X509_EXTENSION *ext; - char buf[1024]; - va_start(args, fmt); - len = vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); + ia5 = ASN1_IA5STRING_new(); + if (ia5 == NULL) + fatalx("ASN1_IA5STRING_new(): %s", ssl_errno_s); + if (!ASN1_STRING_set(ia5, dns_name, -1)) + fatalx("ASN1_STRING_set(): %s", ssl_errno_s); - if (len == -1 || (size_t)len >= sizeof(buf)) - fatalx("failed to create buffer for extension %d", extnid); + gen = GENERAL_NAME_new(); + if (gen == NULL) + fatalx("GENERAL_NAME_new(): %s", ssl_errno_s); + GENERAL_NAME_set0_value(gen, GEN_DNS, ia5); - if ((ext = X509V3_EXT_conf_nid(NULL, NULL, extnid, buf)) == NULL) { - fatalx("X509V3_EXT_conf_nid(%d, %s): %s", - extnid, buf, ssl_errno_s); - } + gens = GENERAL_NAMES_new(); + if (gens == NULL) + fatalx("GENERAL_NAMES_new(): %s", ssl_errno_s); + if (!sk_GENERAL_NAME_push(gens, gen)) + fatalx("sk_GENERAL_NAME_push(): %s", ssl_errno_s); - sk_X509_EXTENSION_push(sk, ext); + ext = X509V3_EXT_i2d(NID_subject_alt_name, 0, gens); + if (ext == NULL) + fatalx("X509V3_EXT_i2d(): %s", ssl_errno_s); + + GENERAL_NAMES_free(gens); + + if (!sk_X509_EXTENSION_push(sk, ext)) + fatalx("sk_X509_EXTENSION_push(): %s", ssl_errno_s); +} + +static void +keymgr_x509_ext_acme_id(STACK_OF(X509_EXTENSION) *sk, const void *data, + size_t len) +{ + ASN1_OCTET_STRING *aos; + X509_EXTENSION *ext; + unsigned char *der = NULL; + int der_len; + + if (len != SHA256_DIGEST_LENGTH) + fatalx("invalid digest length of %zu bytes", len); + + aos = ASN1_OCTET_STRING_new(); + if (aos == NULL) + fatalx("ASN1_OCTET_STRING_new(): %s", ssl_errno_s); + if (!ASN1_STRING_set(aos, data, len)) + fatalx("ASN1_STRING_set(): %s", ssl_errno_s); + + der_len = i2d_ASN1_OCTET_STRING(aos, &der); + if (der_len <= 0) + fatalx("i2d_ASN1_OCTET_STRING(): %s", ssl_errno_s); + if (!ASN1_STRING_set(aos, der, der_len)) + fatalx("ASN1_STRING_set(): %s", ssl_errno_s); + free(der); + + ext = X509_EXTENSION_create_by_NID(NULL, acme_oid, 1, aos); + if (ext == NULL) + fatalx("X509_EXTENSION_create_by_NID(): %s", ssl_errno_s); + + ASN1_OCTET_STRING_free(aos); + + if (!sk_X509_EXTENSION_push(sk, ext)) + fatalx("sk_X509_EXTENSION_push(): %s", ssl_errno_s); } static char * From 1451e0fb438cfdeb1768b7acc3a502aabb53e13a Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Thu, 25 Jan 2024 18:32:17 +0100 Subject: [PATCH 10/10] style nits --- src/keymgr_openssl.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/keymgr_openssl.c b/src/keymgr_openssl.c index 0f04496..db23471 100644 --- a/src/keymgr_openssl.c +++ b/src/keymgr_openssl.c @@ -1215,24 +1215,24 @@ keymgr_x509_ext_alt_name_dns(STACK_OF(X509_EXTENSION) *sk, const char *dns_name) { ASN1_IA5STRING *ia5; + X509_EXTENSION *ext; GENERAL_NAME *gen; GENERAL_NAMES *gens; - X509_EXTENSION *ext; - ia5 = ASN1_IA5STRING_new(); - if (ia5 == NULL) + if ((ia5 = ASN1_IA5STRING_new()) == NULL) fatalx("ASN1_IA5STRING_new(): %s", ssl_errno_s); + if (!ASN1_STRING_set(ia5, dns_name, -1)) fatalx("ASN1_STRING_set(): %s", ssl_errno_s); - gen = GENERAL_NAME_new(); - if (gen == NULL) + if ((gen = GENERAL_NAME_new()) == NULL) fatalx("GENERAL_NAME_new(): %s", ssl_errno_s); + GENERAL_NAME_set0_value(gen, GEN_DNS, ia5); - gens = GENERAL_NAMES_new(); - if (gens == NULL) + if ((gens = GENERAL_NAMES_new()) == NULL) fatalx("GENERAL_NAMES_new(): %s", ssl_errno_s); + if (!sk_GENERAL_NAME_push(gens, gen)) fatalx("sk_GENERAL_NAME_push(): %s", ssl_errno_s); @@ -1252,23 +1252,26 @@ keymgr_x509_ext_acme_id(STACK_OF(X509_EXTENSION) *sk, const void *data, { ASN1_OCTET_STRING *aos; X509_EXTENSION *ext; - unsigned char *der = NULL; + unsigned char *der; int der_len; if (len != SHA256_DIGEST_LENGTH) fatalx("invalid digest length of %zu bytes", len); - aos = ASN1_OCTET_STRING_new(); - if (aos == NULL) + if ((aos = ASN1_OCTET_STRING_new()) == NULL) fatalx("ASN1_OCTET_STRING_new(): %s", ssl_errno_s); + if (!ASN1_STRING_set(aos, data, len)) fatalx("ASN1_STRING_set(): %s", ssl_errno_s); + der = NULL; der_len = i2d_ASN1_OCTET_STRING(aos, &der); if (der_len <= 0) fatalx("i2d_ASN1_OCTET_STRING(): %s", ssl_errno_s); + if (!ASN1_STRING_set(aos, der, der_len)) fatalx("ASN1_STRING_set(): %s", ssl_errno_s); + free(der); ext = X509_EXTENSION_create_by_NID(NULL, acme_oid, 1, aos);