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.
This commit is contained in:
Joris Vink 2021-04-21 10:48:00 +02:00
parent 960fe5afd3
commit cf9e97f087
7 changed files with 49 additions and 136 deletions

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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(...) \

13
misc/ffdhe4096.pem Normal file
View File

@ -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-----

View File

@ -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)

View File

@ -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();