kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit cf9e97f087b98130a761270b049a6c605a637d61
parent 960fe5afd35a15083df2e0097a782e76d3f6ccc1
Author: Joris Vink <joris@coders.se>
Date:   Wed, 21 Apr 2021 10:48:00 +0200

Improve TLS settings and dependencies.

- Kore now only supports OpenSSL 1.1.1 and LibreSSL 3.x.
- Revise the default TLS ciphersuites.
- Kore now carries ffdhe4096.pem and installs it under PREFIX/share/kore.
- Kore its tls_dhparam config setting defaults to the path mentioned above
  so you no longer have to set it.

Diffstat:
Makefile | 1+
README.md | 5++---
conf/kore.conf.example | 7++++---
include/kore/kore.h | 3++-
misc/ffdhe4096.pem | 13+++++++++++++
src/cli.c | 27++++++++++++++++-----------
src/domain.c | 129+++++++------------------------------------------------------------------------
7 files changed, 49 insertions(+), 136 deletions(-)

diff --git a/Makefile b/Makefile @@ -198,6 +198,7 @@ install: install -m 555 $(KORE) $(DESTDIR)$(INSTALL_DIR)/$(KORE) install -m 644 kore.features $(DESTDIR)$(SHARE_DIR)/features install -m 644 include/kore/*.h $(DESTDIR)$(INCLUDE_DIR) + install -m 644 misc/ffdhe4096.pem $(DESTDIR)$(SHARE_DIR)/ffdhe4096.pem $(MAKE) -C kodev install $(MAKE) install-sources diff --git a/README.md b/README.md @@ -35,7 +35,7 @@ License Documentation -------------- -[Read the documentation](https://docs.kore.io/4.0.0/) +[Read the documentation](https://docs.kore.io/4.1.0/) Performance ----------- @@ -55,8 +55,7 @@ Building Kore Clone this repository or get the latest release at [https://kore.io/releases/4.1.0](https://kore.io/releases/4.1.0). Requirements -* openssl (1.0.2, 1.1.0 or 1.1.1) - (note: libressl 3.0.0+ works as a replacement) +* openssl 1.1.1 or libressl 3.x Requirement for asynchronous curl (optional) * libcurl (7.64.0 or higher) diff --git a/conf/kore.conf.example b/conf/kore.conf.example @@ -198,10 +198,11 @@ validator v_session function v_session_validate #tls_version 1.3 # Specify the TLS ciphers that will be used. -#tls_cipher ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!kRSA:!kDSA +#tls_cipher AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256:AEAD-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256 -# Required DH parameters for TLS. -#tls_dhparam dh2048.pem +# Required DH parameters for TLS if DHE ciphersuites are in-use. +# Defaults to SHARE_DIR/ffdhe4096.pem, can be overwritten. +#tls_dhparam /usr/local/share/kore/ffdhe4096.pem # OpenBSD specific settings. # Add more pledges if your application requires more privileges. diff --git a/include/kore/kore.h b/include/kore/kore.h @@ -103,7 +103,8 @@ extern int daemon(int, int); #define KORE_DOMAINNAME_LEN 255 #define KORE_PIDFILE_DEFAULT "kore.pid" -#define KORE_DEFAULT_CIPHER_LIST "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!kRSA:!kDSA" +#define KORE_DHPARAM_PATH PREFIX "/share/kore/ffdhe4096.pem" +#define KORE_DEFAULT_CIPHER_LIST "AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256:AEAD-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256" #if defined(KORE_DEBUG) #define kore_debug(...) \ diff --git a/misc/ffdhe4096.pem b/misc/ffdhe4096.pem @@ -0,0 +1,13 @@ +-----BEGIN DH PARAMETERS----- +MIICCAKCAgEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz ++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a +87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 +YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi +7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD +ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3 +7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32 +nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZp4e +8W5vUsMWTfT7eTDp5OWIV7asfV9C1p9tGHdjzx1VA0AEh/VbpX4xzHpxNciG77Qx +iu1qHgEtnmgyqQdgCpGBMMRtx3j5ca0AOAkpmaMzy4t6Gh25PXFAADwqTs6p+Y0K +zAqCkc3OyX3Pjsm1Wn+IpGtNtahR9EGC4caKAH5eZV9q//////////8CAQI= +-----END DH PARAMETERS----- diff --git a/src/cli.c b/src/cli.c @@ -287,7 +287,7 @@ static const char *config_data = "\n" "load\t\t./%s.so\n" "\n" - "tls_dhparam\tdh2048.pem\n" + "tls_dhparam\tdh4096.pem\n" "\n" "domain * {\n" "\tattach\t\ttls\n" @@ -342,7 +342,7 @@ static const char *python_app_data = "\n" "class KoreApp:\n" " def configure(self, args):\n" - " kore.config.tls_dhparam = \"dh2048.pem\"\n" + " kore.config.tls_dhparam = \"dh4096.pem\"\n" " kore.config.deployment = \"development\"\n" " kore.server(\"default\", ip=\"127.0.0.1\", port=\"8888\")\n" "\n" @@ -359,15 +359,20 @@ static const char *python_app_data = "\n" "koreapp = KoreApp()"; -static const char *dh2048_data = +static const char *dh4096_data = "-----BEGIN DH PARAMETERS-----\n" - "MIIBCAKCAQEAn4f4Qn5SudFjEYPWTbUaOTLUH85YWmmPFW1+b5bRa9ygr+1wfamv\n" - "VKVT7jO8c4msSNikUf6eEfoH0H4VTCaj+Habwu+Sj+I416r3mliMD4SjNsUJrBrY\n" - "Y0QV3ZUgZz4A8ARk/WwQcRl8+ZXJz34IaLwAcpyNhoV46iHVxW0ty8ND0U4DIku/\n" - "PNayKimu4BXWXk4RfwNVP59t8DQKqjshZ4fDnbotskmSZ+e+FHrd+Kvrq/WButvV\n" - "Bzy9fYgnUlJ82g/bziCI83R2xAdtH014fR63MpElkqdNeChb94pPbEdFlNUvYIBN\n" - "xx2vTUQMqRbB4UdG2zuzzr5j98HDdblQ+wIBAg==\n" - "-----END DH PARAMETERS-----"; + "MIICCAKCAgEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz\n" + "+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a\n" + "87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7\n" + "YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi\n" + "7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD\n" + "ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3\n" + "7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32\n" + "nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZp4e\n" + "8W5vUsMWTfT7eTDp5OWIV7asfV9C1p9tGHdjzx1VA0AEh/VbpX4xzHpxNciG77Qx\n" + "iu1qHgEtnmgyqQdgCpGBMMRtx3j5ca0AOAkpmaMzy4t6Gh25PXFAADwqTs6p+Y0K\n" + "zAqCkc3OyX3Pjsm1Wn+IpGtNtahR9EGC4caKAH5eZV9q//////////8CAQI=\n" + "-----END DH PARAMETERS-----\n"; static const char *gitignore = "*.o\n.flavor\n.objs\n%s.so\nassets.h\ncert\n"; @@ -1371,7 +1376,7 @@ cli_generate_certs(void) char issuer[64]; /* Write out DH parameters. */ - cli_file_create("dh2048.pem", dh2048_data, strlen(dh2048_data)); + cli_file_create("dh4096.pem", dh4096_data, strlen(dh4096_data)); /* Create new certificate. */ if ((x509 = X509_new()) == NULL) diff --git a/src/domain.c b/src/domain.c @@ -14,12 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* - * XXX - Lots of OPENSSL ifdefs here for 1.0.2 and 1.1.0 release lines. - * The idea is to only support 1.1.1 down the line and remove the rest. - * (although we have to remain compat with 1.0.2 due to LibreSSL). - */ - #include <sys/param.h> #include <sys/types.h> @@ -68,54 +62,8 @@ static int keymgr_rsa_privenc(int, const unsigned char *, static ECDSA_SIG *keymgr_ecdsa_sign(const unsigned char *, int, const BIGNUM *, const BIGNUM *, EC_KEY *); -#if defined(KORE_OPENSSL_NEWER_API) static RSA_METHOD *keymgr_rsa_meth = NULL; static EC_KEY_METHOD *keymgr_ec_meth = NULL; -#else -/* - * Run own ecdsa_method data structure as OpenSSL has this in ecs_locl.h - * and does not export this on systems. - */ -struct ecdsa_method { - const char *name; - ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *, - int, const BIGNUM *, const BIGNUM *, EC_KEY *); - int (*ecdsa_sign_setup)(EC_KEY *, BN_CTX *, BIGNUM **, - BIGNUM **); - int (*ecdsa_do_verify)(const unsigned char *, int, - const ECDSA_SIG *, EC_KEY *); - int flags; - char *app_data; -}; -#endif - -#if !defined(KORE_OPENSSL_NEWER_API) -static ECDSA_METHOD keymgr_ecdsa = { - "kore ECDSA keymgr method", - keymgr_ecdsa_sign, - NULL, - NULL, - 0, - NULL -}; - -static RSA_METHOD keymgr_rsa = { - "kore RSA keymgr method", - NULL, - NULL, - keymgr_rsa_privenc, - NULL, - NULL, - NULL, - keymgr_rsa_init, - keymgr_rsa_finish, - RSA_METHOD_FLAG_NO_CHECK, - NULL, - NULL, - NULL, - NULL -}; -#endif static u_int16_t domain_id = 0; static struct kore_domain *cached[KORE_DOMAIN_CACHE]; @@ -128,7 +76,6 @@ kore_domain_init(void) for (i = 0; i < KORE_DOMAIN_CACHE; i++) cached[i] = NULL; -#if defined(KORE_OPENSSL_NEWER_API) if (keymgr_rsa_meth == NULL) { if ((keymgr_rsa_meth = RSA_meth_new("kore RSA keymgr method", RSA_METHOD_FLAG_NO_CHECK)) == NULL) @@ -145,7 +92,6 @@ kore_domain_init(void) } EC_KEY_METHOD_set_sign(keymgr_ec_meth, NULL, NULL, keymgr_ecdsa_sign); -#endif #if !defined(TLS1_3_VERSION) if (!kore_quiet) { @@ -159,7 +105,6 @@ kore_domain_init(void) void kore_domain_cleanup(void) { -#if defined(KORE_OPENSSL_NEWER_API) if (keymgr_rsa_meth != NULL) { RSA_meth_free(keymgr_rsa_meth); keymgr_rsa_meth = NULL; @@ -169,7 +114,6 @@ kore_domain_cleanup(void) EC_KEY_METHOD_free(keymgr_ec_meth); keymgr_ec_meth = NULL; } -#endif } struct kore_domain * @@ -278,40 +222,24 @@ kore_domain_tlsinit(struct kore_domain *dom, int type, { const u_int8_t *ptr; RSA *rsa; + BIO *bio; X509 *x509; EVP_PKEY *pkey; STACK_OF(X509_NAME) *certs; EC_KEY *eckey; const SSL_METHOD *method; -#if !defined(KORE_OPENSSL_NEWER_API) - EC_KEY *ecdh; -#endif kore_debug("kore_domain_tlsinit(%s)", dom->domain); if (dom->ssl_ctx != NULL) SSL_CTX_free(dom->ssl_ctx); -#if defined(KORE_OPENSSL_NEWER_API) if ((method = TLS_method()) == NULL) fatalx("TLS_method(): %s", ssl_errno_s); -#else - switch (tls_version) { - case KORE_TLS_VERSION_1_3: - case KORE_TLS_VERSION_1_2: - case KORE_TLS_VERSION_BOTH: - method = TLSv1_2_server_method(); - break; - default: - fatalx("unknown tls_version: %d", tls_version); - return; - } -#endif if ((dom->ssl_ctx = SSL_CTX_new(method)) == NULL) fatalx("SSL_ctx_new(): %s", ssl_errno_s); -#if defined(KORE_OPENSSL_NEWER_API) if (!SSL_CTX_set_min_proto_version(dom->ssl_ctx, TLS1_2_VERSION)) fatalx("SSL_CTX_set_min_proto_version: %s", ssl_errno_s); @@ -346,7 +274,6 @@ kore_domain_tlsinit(struct kore_domain *dom, int type, fatalx("unknown tls_version: %d", tls_version); return; } -#endif switch (type) { case KORE_PEM_CERT_CHAIN: @@ -380,22 +307,13 @@ kore_domain_tlsinit(struct kore_domain *dom, int type, if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL) fatalx("no RSA public key present"); RSA_set_app_data(rsa, dom); -#if defined(KORE_OPENSSL_NEWER_API) RSA_set_method(rsa, keymgr_rsa_meth); -#else - RSA_set_method(rsa, &keymgr_rsa); -#endif break; case EVP_PKEY_EC: if ((eckey = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) fatalx("no EC public key present"); -#if defined(KORE_OPENSSL_NEWER_API) EC_KEY_set_ex_data(eckey, 0, dom); EC_KEY_set_method(eckey, keymgr_ec_meth); -#else - ECDSA_set_ex_data(eckey, 0, dom); - ECDSA_set_method(eckey, &keymgr_ecdsa); -#endif break; default: fatalx("unknown public key in certificate"); @@ -409,22 +327,22 @@ kore_domain_tlsinit(struct kore_domain *dom, int type, dom->domain, ssl_errno_s); } - if (tls_dhparam == NULL) - fatalx("No DH parameters given"); + if (tls_dhparam == NULL) { + if ((bio = BIO_new_file(KORE_DHPARAM_PATH, "r")) == NULL) + fatal("failed to open %s", KORE_DHPARAM_PATH); + + tls_dhparam = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + BIO_free(bio); + + if (tls_dhparam == NULL) + fatal("PEM_read_bio_DHparams(): %s", ssl_errno_s); + } SSL_CTX_set_tmp_dh(dom->ssl_ctx, tls_dhparam); SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_SINGLE_DH_USE); -#if defined(KORE_OPENSSL_NEWER_API) if (!SSL_CTX_set_ecdh_auto(dom->ssl_ctx, 1)) fatalx("SSL_CTX_set_ecdh_auto: %s", ssl_errno_s); -#else - if ((ecdh = EC_KEY_new_by_curve_name(NID_secp384r1)) == NULL) - fatalx("EC_KEY_new_by_curve_name: %s", ssl_errno_s); - - SSL_CTX_set_tmp_ecdh(dom->ssl_ctx, ecdh); - EC_KEY_free(ecdh); -#endif SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_SINGLE_ECDH_USE); SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_COMPRESSION); @@ -605,27 +523,17 @@ keymgr_init(void) if ((meth = RSA_get_default_method()) == NULL) fatal("failed to obtain RSA method"); -#if defined(KORE_OPENSSL_NEWER_API) RSA_meth_set_pub_enc(keymgr_rsa_meth, RSA_meth_get_pub_enc(meth)); RSA_meth_set_pub_dec(keymgr_rsa_meth, RSA_meth_get_pub_dec(meth)); RSA_meth_set_bn_mod_exp(keymgr_rsa_meth, RSA_meth_get_bn_mod_exp(meth)); -#else - keymgr_rsa.rsa_pub_enc = meth->rsa_pub_enc; - keymgr_rsa.rsa_pub_dec = meth->rsa_pub_dec; - keymgr_rsa.bn_mod_exp = meth->bn_mod_exp; -#endif } static int keymgr_rsa_init(RSA *rsa) { if (rsa != NULL) { -#if defined(KORE_OPENSSL_NEWER_API) RSA_set_flags(rsa, RSA_flags(rsa) | RSA_FLAG_EXT_PKEY | RSA_METHOD_FLAG_NO_CHECK); -#else - rsa->flags |= RSA_FLAG_EXT_PKEY | RSA_METHOD_FLAG_NO_CHECK; -#endif return (1); } @@ -702,13 +610,8 @@ keymgr_ecdsa_sign(const unsigned char *dgst, int dgst_len, if (len > sizeof(keymgr_buf)) fatal("keymgr_buf too small"); -#if defined(KORE_OPENSSL_NEWER_API) if ((dom = EC_KEY_get_ex_data(eckey, 0)) == NULL) fatal("EC_KEY has no domain"); -#else - if ((dom = ECDSA_get_ex_data(eckey, 0)) == NULL) - fatal("EC_KEY has no domain"); -#endif memset(keymgr_buf, 0, sizeof(keymgr_buf)); req = (struct kore_keyreq *)keymgr_buf; @@ -890,23 +793,13 @@ domain_load_certificate_chain(SSL_CTX *ctx, const void *data, size_t len) if (SSL_CTX_use_certificate(ctx, x) == 0) return (NULL); -#if defined(KORE_OPENSSL_NEWER_API) SSL_CTX_clear_chain_certs(ctx); -#else - sk_X509_pop_free(ctx->extra_certs, X509_free); - ctx->extra_certs = NULL; -#endif ERR_clear_error(); while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL)) != NULL) { /* ca its reference count won't be increased. */ -#if defined(KORE_OPENSSL_NEWER_API) if (SSL_CTX_add0_chain_cert(ctx, ca) == 0) return (NULL); -#else - if (SSL_CTX_add_extra_chain_cert(ctx, ca) == 0) - return (NULL); -#endif } err = ERR_peek_last_error();