Move common TLS initialization code to tls_init.c.
This commit is contained in:
2
MANIFEST
2
MANIFEST
@@ -358,6 +358,8 @@ logsrvd/regress/fuzz/fuzz_logsrvd_conf.c
|
|||||||
logsrvd/regress/fuzz/fuzz_logsrvd_conf.dict
|
logsrvd/regress/fuzz/fuzz_logsrvd_conf.dict
|
||||||
logsrvd/sendlog.c
|
logsrvd/sendlog.c
|
||||||
logsrvd/sendlog.h
|
logsrvd/sendlog.h
|
||||||
|
logsrvd/tls_common.h
|
||||||
|
logsrvd/tls_init.c
|
||||||
m4/ax_append_flag.m4
|
m4/ax_append_flag.m4
|
||||||
m4/ax_check_compile_flag.m4
|
m4/ax_check_compile_flag.m4
|
||||||
m4/ax_check_link_flag.m4
|
m4/ax_check_link_flag.m4
|
||||||
|
@@ -119,9 +119,10 @@ SHELL = @SHELL@
|
|||||||
|
|
||||||
PROGS = sudo_logsrvd sudo_sendlog
|
PROGS = sudo_logsrvd sudo_sendlog
|
||||||
|
|
||||||
LOGSRVD_OBJS = logsrv_util.o iolog_writer.o logsrvd.o logsrvd_conf.o
|
LOGSRVD_OBJS = logsrv_util.o iolog_writer.o logsrvd.o logsrvd_conf.o \
|
||||||
|
tls_init.o
|
||||||
|
|
||||||
SENDLOG_OBJS = logsrv_util.o sendlog.o
|
SENDLOG_OBJS = logsrv_util.o sendlog.o tls_init.o
|
||||||
|
|
||||||
IOBJS = $(LOGSRVD_OBJS:.o=.i) $(SENDLOG_OBJS:.o=.i)
|
IOBJS = $(LOGSRVD_OBJS:.o=.i) $(SENDLOG_OBJS:.o=.i)
|
||||||
|
|
||||||
@@ -283,7 +284,7 @@ fuzz_logsrvd_conf.o: $(srcdir)/regress/fuzz/fuzz_logsrvd_conf.c \
|
|||||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_iolog.h \
|
$(incdir)/sudo_eventlog.h $(incdir)/sudo_iolog.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||||
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h \
|
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h \
|
||||||
$(top_builddir)/config.h
|
$(srcdir)/tls_common.h $(top_builddir)/config.h
|
||||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/fuzz/fuzz_logsrvd_conf.c
|
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/fuzz/fuzz_logsrvd_conf.c
|
||||||
fuzz_logsrvd_conf.i: $(srcdir)/regress/fuzz/fuzz_logsrvd_conf.c \
|
fuzz_logsrvd_conf.i: $(srcdir)/regress/fuzz/fuzz_logsrvd_conf.c \
|
||||||
$(incdir)/compat/stdbool.h $(incdir)/log_server.pb-c.h \
|
$(incdir)/compat/stdbool.h $(incdir)/log_server.pb-c.h \
|
||||||
@@ -292,7 +293,7 @@ fuzz_logsrvd_conf.i: $(srcdir)/regress/fuzz/fuzz_logsrvd_conf.c \
|
|||||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_iolog.h \
|
$(incdir)/sudo_eventlog.h $(incdir)/sudo_iolog.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||||
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h \
|
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h \
|
||||||
$(top_builddir)/config.h
|
$(srcdir)/tls_common.h $(top_builddir)/config.h
|
||||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
fuzz_logsrvd_conf.plog: fuzz_logsrvd_conf.i
|
fuzz_logsrvd_conf.plog: fuzz_logsrvd_conf.i
|
||||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/fuzz/fuzz_logsrvd_conf.c --i-file $< --output-file $@
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/fuzz/fuzz_logsrvd_conf.c --i-file $< --output-file $@
|
||||||
@@ -302,7 +303,8 @@ iolog_writer.o: $(srcdir)/iolog_writer.c $(incdir)/compat/stdbool.h \
|
|||||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_gettext.h \
|
$(incdir)/sudo_eventlog.h $(incdir)/sudo_gettext.h \
|
||||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_queue.h \
|
$(incdir)/sudo_iolog.h $(incdir)/sudo_queue.h \
|
||||||
$(incdir)/sudo_util.h $(srcdir)/logsrv_util.h \
|
$(incdir)/sudo_util.h $(srcdir)/logsrv_util.h \
|
||||||
$(srcdir)/logsrvd.h $(top_builddir)/config.h
|
$(srcdir)/logsrvd.h $(srcdir)/tls_common.h \
|
||||||
|
$(top_builddir)/config.h
|
||||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/iolog_writer.c
|
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/iolog_writer.c
|
||||||
iolog_writer.i: $(srcdir)/iolog_writer.c $(incdir)/compat/stdbool.h \
|
iolog_writer.i: $(srcdir)/iolog_writer.c $(incdir)/compat/stdbool.h \
|
||||||
$(incdir)/log_server.pb-c.h $(incdir)/protobuf-c/protobuf-c.h \
|
$(incdir)/log_server.pb-c.h $(incdir)/protobuf-c/protobuf-c.h \
|
||||||
@@ -310,7 +312,8 @@ iolog_writer.i: $(srcdir)/iolog_writer.c $(incdir)/compat/stdbool.h \
|
|||||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_gettext.h \
|
$(incdir)/sudo_eventlog.h $(incdir)/sudo_gettext.h \
|
||||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_queue.h \
|
$(incdir)/sudo_iolog.h $(incdir)/sudo_queue.h \
|
||||||
$(incdir)/sudo_util.h $(srcdir)/logsrv_util.h \
|
$(incdir)/sudo_util.h $(srcdir)/logsrv_util.h \
|
||||||
$(srcdir)/logsrvd.h $(top_builddir)/config.h
|
$(srcdir)/logsrvd.h $(srcdir)/tls_common.h \
|
||||||
|
$(top_builddir)/config.h
|
||||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
iolog_writer.plog: iolog_writer.i
|
iolog_writer.plog: iolog_writer.i
|
||||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog_writer.c --i-file $< --output-file $@
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog_writer.c --i-file $< --output-file $@
|
||||||
@@ -339,7 +342,7 @@ logsrvd.o: $(srcdir)/logsrvd.c $(incdir)/compat/getopt.h \
|
|||||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
||||||
$(incdir)/sudo_json.h $(incdir)/sudo_plugin.h \
|
$(incdir)/sudo_json.h $(incdir)/sudo_plugin.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_rand.h $(incdir)/sudo_util.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_rand.h $(incdir)/sudo_util.h \
|
||||||
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h \
|
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h $(srcdir)/tls_common.h \
|
||||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/logsrvd.c
|
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/logsrvd.c
|
||||||
logsrvd.i: $(srcdir)/logsrvd.c $(incdir)/compat/getopt.h \
|
logsrvd.i: $(srcdir)/logsrvd.c $(incdir)/compat/getopt.h \
|
||||||
@@ -351,7 +354,7 @@ logsrvd.i: $(srcdir)/logsrvd.c $(incdir)/compat/getopt.h \
|
|||||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
||||||
$(incdir)/sudo_json.h $(incdir)/sudo_plugin.h \
|
$(incdir)/sudo_json.h $(incdir)/sudo_plugin.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_rand.h $(incdir)/sudo_util.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_rand.h $(incdir)/sudo_util.h \
|
||||||
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h \
|
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h $(srcdir)/tls_common.h \
|
||||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
logsrvd.plog: logsrvd.i
|
logsrvd.plog: logsrvd.i
|
||||||
@@ -364,7 +367,8 @@ logsrvd_conf.o: $(srcdir)/logsrvd_conf.c $(incdir)/compat/getaddrinfo.h \
|
|||||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
|
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||||
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h \
|
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h \
|
||||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
$(srcdir)/tls_common.h $(top_builddir)/config.h \
|
||||||
|
$(top_builddir)/pathnames.h
|
||||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/logsrvd_conf.c
|
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/logsrvd_conf.c
|
||||||
logsrvd_conf.i: $(srcdir)/logsrvd_conf.c $(incdir)/compat/getaddrinfo.h \
|
logsrvd_conf.i: $(srcdir)/logsrvd_conf.c $(incdir)/compat/getaddrinfo.h \
|
||||||
$(incdir)/compat/stdbool.h $(incdir)/log_server.pb-c.h \
|
$(incdir)/compat/stdbool.h $(incdir)/log_server.pb-c.h \
|
||||||
@@ -374,7 +378,8 @@ logsrvd_conf.i: $(srcdir)/logsrvd_conf.c $(incdir)/compat/getaddrinfo.h \
|
|||||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
|
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||||
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h \
|
$(srcdir)/logsrv_util.h $(srcdir)/logsrvd.h \
|
||||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
$(srcdir)/tls_common.h $(top_builddir)/config.h \
|
||||||
|
$(top_builddir)/pathnames.h
|
||||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
logsrvd_conf.plog: logsrvd_conf.i
|
logsrvd_conf.plog: logsrvd_conf.i
|
||||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/logsrvd_conf.c --i-file $< --output-file $@
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/logsrvd_conf.c --i-file $< --output-file $@
|
||||||
@@ -387,7 +392,7 @@ sendlog.o: $(srcdir)/sendlog.c $(incdir)/compat/getaddrinfo.h \
|
|||||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
||||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||||
$(incdir)/sudo_util.h $(srcdir)/logsrv_util.h $(srcdir)/sendlog.h \
|
$(incdir)/sudo_util.h $(srcdir)/logsrv_util.h $(srcdir)/sendlog.h \
|
||||||
$(top_builddir)/config.h
|
$(srcdir)/tls_common.h $(top_builddir)/config.h
|
||||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sendlog.c
|
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sendlog.c
|
||||||
sendlog.i: $(srcdir)/sendlog.c $(incdir)/compat/getaddrinfo.h \
|
sendlog.i: $(srcdir)/sendlog.c $(incdir)/compat/getaddrinfo.h \
|
||||||
$(incdir)/compat/getopt.h $(incdir)/compat/stdbool.h \
|
$(incdir)/compat/getopt.h $(incdir)/compat/stdbool.h \
|
||||||
@@ -398,7 +403,23 @@ sendlog.i: $(srcdir)/sendlog.c $(incdir)/compat/getaddrinfo.h \
|
|||||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
||||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||||
$(incdir)/sudo_util.h $(srcdir)/logsrv_util.h $(srcdir)/sendlog.h \
|
$(incdir)/sudo_util.h $(srcdir)/logsrv_util.h $(srcdir)/sendlog.h \
|
||||||
$(top_builddir)/config.h
|
$(srcdir)/tls_common.h $(top_builddir)/config.h
|
||||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
sendlog.plog: sendlog.i
|
sendlog.plog: sendlog.i
|
||||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sendlog.c --i-file $< --output-file $@
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sendlog.c --i-file $< --output-file $@
|
||||||
|
tls_init.o: $(srcdir)/tls_init.c $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/hostcheck.h $(incdir)/sudo_compat.h \
|
||||||
|
$(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
|
||||||
|
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||||
|
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||||
|
$(srcdir)/tls_common.h $(top_builddir)/config.h
|
||||||
|
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/tls_init.c
|
||||||
|
tls_init.i: $(srcdir)/tls_init.c $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/hostcheck.h $(incdir)/sudo_compat.h \
|
||||||
|
$(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
|
||||||
|
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||||
|
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||||
|
$(srcdir)/tls_common.h $(top_builddir)/config.h
|
||||||
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
|
tls_init.plog: tls_init.i
|
||||||
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/tls_init.c --i-file $< --output-file $@
|
||||||
|
@@ -74,11 +74,6 @@
|
|||||||
#include "hostcheck.h"
|
#include "hostcheck.h"
|
||||||
#include "logsrvd.h"
|
#include "logsrvd.h"
|
||||||
|
|
||||||
#if defined(HAVE_OPENSSL)
|
|
||||||
# define LOGSRVD_DEFAULT_CIPHER_LST12 "HIGH:!aNULL"
|
|
||||||
# define LOGSRVD_DEFAULT_CIPHER_LST13 "TLS_AES_256_GCM_SHA384"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_NOFOLLOW
|
#ifndef O_NOFOLLOW
|
||||||
# define O_NOFOLLOW 0
|
# define O_NOFOLLOW 0
|
||||||
#endif
|
#endif
|
||||||
@@ -1173,131 +1168,6 @@ verify_peer_identity(int preverify_ok, X509_STORE_CTX *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_server_cert(SSL_CTX *ctx, const struct logsrvd_tls_config *tls_config)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_SSL_CTX_GET0_CERTIFICATE
|
|
||||||
bool ret = false;
|
|
||||||
X509_STORE_CTX *store_ctx = NULL;
|
|
||||||
X509_STORE *ca_store;
|
|
||||||
STACK_OF(X509) *chain_certs;
|
|
||||||
X509 *x509;
|
|
||||||
debug_decl(verify_server_cert, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
if ((x509 = SSL_CTX_get0_certificate(ctx)) == NULL) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"unable to get X509 object from SSL_CTX: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((store_ctx = X509_STORE_CTX_new()) == NULL) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"unable to allocate X509_STORE_CTX object: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SSL_CTX_get0_chain_certs(ctx, &chain_certs)) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"unable to get chain certs: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ca_store = SSL_CTX_get_cert_store(ctx)) != NULL)
|
|
||||||
X509_STORE_set_flags(ca_store, X509_V_FLAG_X509_STRICT);
|
|
||||||
|
|
||||||
if (!X509_STORE_CTX_init(store_ctx, ca_store, x509, chain_certs)) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"unable to initialize X509_STORE_CTX object: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (X509_verify_cert(store_ctx) <= 0) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"unable to verify cert %s: %s", tls_config->cert_path,
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = true;
|
|
||||||
exit:
|
|
||||||
X509_STORE_CTX_free(store_ctx);
|
|
||||||
|
|
||||||
debug_return_bool(ret);
|
|
||||||
#else
|
|
||||||
/* TODO: verify server cert with old OpenSSL */
|
|
||||||
return true;
|
|
||||||
#endif /* HAVE_SSL_CTX_GET0_CERTIFICATE */
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
init_tls_ciphersuites(SSL_CTX *ctx, const struct logsrvd_tls_config *tls_config)
|
|
||||||
{
|
|
||||||
const char *errstr;
|
|
||||||
int success = 0;
|
|
||||||
debug_decl(init_tls_ciphersuites, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
if (tls_config->ciphers_v12) {
|
|
||||||
/* try to set TLS v1.2 ciphersuite list from config if given */
|
|
||||||
success = SSL_CTX_set_cipher_list(ctx, tls_config->ciphers_v12);
|
|
||||||
if (success) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
|
||||||
"TLS 1.2 ciphersuite list set to %s", tls_config->ciphers_v12);
|
|
||||||
} else {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("unable to set TLS 1.2 ciphersuite to %s: %s"),
|
|
||||||
tls_config->ciphers_v12, errstr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!success) {
|
|
||||||
/* fallback to default ciphersuites for TLS v1.2 */
|
|
||||||
if (SSL_CTX_set_cipher_list(ctx, LOGSRVD_DEFAULT_CIPHER_LST12) <= 0) {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("unable to set TLS 1.2 ciphersuite to %s: %s"),
|
|
||||||
LOGSRVD_DEFAULT_CIPHER_LST12, errstr);
|
|
||||||
debug_return_bool(false);
|
|
||||||
} else {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
|
||||||
"TLS v1.2 ciphersuite list set to %s (default)",
|
|
||||||
LOGSRVD_DEFAULT_CIPHER_LST12);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# if defined(HAVE_SSL_CTX_SET_CIPHERSUITES)
|
|
||||||
success = 0;
|
|
||||||
if (tls_config->ciphers_v13) {
|
|
||||||
/* try to set TLSv1.3 ciphersuite list from config */
|
|
||||||
success = SSL_CTX_set_ciphersuites(ctx, tls_config->ciphers_v13);
|
|
||||||
if (success) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
|
||||||
"TLS v1.3 ciphersuite list set to %s", tls_config->ciphers_v13);
|
|
||||||
} else {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("unable to set TLS 1.3 ciphersuite to %s: %s"),
|
|
||||||
tls_config->ciphers_v13, errstr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!success) {
|
|
||||||
/* fallback to default ciphersuites for TLS v1.3 */
|
|
||||||
if (SSL_CTX_set_ciphersuites(ctx, LOGSRVD_DEFAULT_CIPHER_LST13) <= 0) {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("unable to set TLS 1.3 ciphersuite to %s: %s"),
|
|
||||||
LOGSRVD_DEFAULT_CIPHER_LST13, errstr);
|
|
||||||
debug_return_bool(false);
|
|
||||||
} else {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
|
||||||
"TLS v1.3 ciphersuite list set to %s (default)",
|
|
||||||
LOGSRVD_DEFAULT_CIPHER_LST13);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
debug_return_bool(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calls series of openssl initialization functions in order to
|
* Calls series of openssl initialization functions in order to
|
||||||
* be able to establish configured network connections over TLS
|
* be able to establish configured network connections over TLS
|
||||||
@@ -1305,145 +1175,23 @@ init_tls_ciphersuites(SSL_CTX *ctx, const struct logsrvd_tls_config *tls_config)
|
|||||||
static bool
|
static bool
|
||||||
init_tls_server_context(void)
|
init_tls_server_context(void)
|
||||||
{
|
{
|
||||||
const SSL_METHOD *method;
|
|
||||||
FILE *dhparam_file = NULL;
|
|
||||||
SSL_CTX *ctx = NULL;
|
|
||||||
struct logsrvd_tls_runtime *tls_runtime = logsrvd_get_tls_runtime();
|
struct logsrvd_tls_runtime *tls_runtime = logsrvd_get_tls_runtime();
|
||||||
const struct logsrvd_tls_config *tls_config = logsrvd_get_tls_config();
|
const struct logsrvd_tls_config *tls_config = logsrvd_get_tls_config();
|
||||||
bool ca_bundle_required = tls_config->verify | tls_config->check_peer;
|
|
||||||
const char *errstr;
|
|
||||||
debug_decl(init_tls_server_context, SUDO_DEBUG_UTIL);
|
debug_decl(init_tls_server_context, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
SSL_library_init();
|
tls_runtime->ssl_ctx = init_tls_context(tls_config->cacert_path,
|
||||||
OpenSSL_add_all_algorithms();
|
tls_config->cert_path, tls_config->pkey_path, tls_config->dhparams_path,
|
||||||
SSL_load_error_strings();
|
tls_config->ciphers_v12, tls_config->ciphers_v13, tls_config->verify);
|
||||||
|
|
||||||
if ((method = TLS_server_method()) == NULL) {
|
if (tls_runtime->ssl_ctx != NULL) {
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("unable to get TLS server method: %s"), errstr);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if ((ctx = SSL_CTX_new(method)) == NULL) {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("unable to create TLS context: %s"), errstr);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SSL_CTX_use_certificate_chain_file(ctx, tls_config->cert_path) <= 0) {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("%s: %s"), tls_config->cert_path, errstr);
|
|
||||||
sudo_warnx(U_("unable to load certificate %s"), tls_config->cert_path);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if server or client authentication is required, CA bundle file has to be prepared */
|
|
||||||
if (ca_bundle_required) {
|
|
||||||
if (tls_config->cacert_path != NULL) {
|
|
||||||
STACK_OF(X509_NAME) *cacerts =
|
|
||||||
SSL_load_client_CA_file(tls_config->cacert_path);
|
|
||||||
|
|
||||||
if (cacerts == NULL) {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("%s: %s"), tls_config->cacert_path, errstr);
|
|
||||||
sudo_warnx(U_("unable to load certificate authority bundle %s"),
|
|
||||||
tls_config->cacert_path);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
SSL_CTX_set_client_CA_list(ctx, cacerts);
|
|
||||||
|
|
||||||
/* set the location of the CA bundle file for verification */
|
|
||||||
if (SSL_CTX_load_verify_locations(ctx, tls_config->cacert_path, NULL) <= 0) {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx("SSL_CTX_load_verify_locations: %s", errstr);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!SSL_CTX_set_default_verify_paths(ctx)) {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx("SSL_CTX_set_default_verify_paths: %s", errstr);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* only verify server cert if it is set in the configuration */
|
|
||||||
if (tls_config->verify) {
|
|
||||||
if (!verify_server_cert(ctx, tls_config))
|
|
||||||
goto bad;
|
|
||||||
} else {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
|
||||||
"skipping server cert check");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if peer authentication is enabled, verify client cert during TLS handshake
|
|
||||||
* The last parameter is a callback, where identity validation (hostname/ip)
|
|
||||||
* will be performed, because it is not automatically done by openssl.
|
|
||||||
*/
|
|
||||||
if (tls_config->check_peer) {
|
if (tls_config->check_peer) {
|
||||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_peer_identity);
|
/* Verify server cert during the handshake. */
|
||||||
|
SSL_CTX_set_verify(tls_runtime->ssl_ctx,
|
||||||
|
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
|
||||||
|
verify_peer_identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if private key file was not set, assume that the cert file contains the private key */
|
|
||||||
char* pkey = (tls_config->pkey_path == NULL ? tls_config->cert_path : tls_config->pkey_path);
|
|
||||||
|
|
||||||
if (!SSL_CTX_use_PrivateKey_file(ctx, pkey, SSL_FILETYPE_PEM) ||
|
|
||||||
!SSL_CTX_check_private_key(ctx)) {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("%s: %s"), pkey, errstr);
|
|
||||||
sudo_warnx(U_("unable to load private key %s"), pkey);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize TLSv1.2 and TLSv1.3 ciphersuites */
|
|
||||||
if (!init_tls_ciphersuites(ctx, tls_config)) {
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* try to load and set diffie-hellman parameters */
|
|
||||||
if (tls_config->dhparams_path != NULL)
|
|
||||||
dhparam_file = fopen(tls_config->dhparams_path, "r");
|
|
||||||
if (dhparam_file != NULL) {
|
|
||||||
DH *dhparams = PEM_read_DHparams(dhparam_file, NULL, NULL, NULL);
|
|
||||||
if (dhparams != NULL) {
|
|
||||||
if (!SSL_CTX_set_tmp_dh(ctx, dhparams)) {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("unable to set diffie-hellman parameters: %s"),
|
|
||||||
errstr);
|
|
||||||
DH_free(dhparams);
|
|
||||||
} else {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
|
||||||
"diffie-hellman parameters are loaded");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("unable to set diffie-hellman parameters: %s"),
|
|
||||||
errstr);
|
|
||||||
}
|
|
||||||
fclose(dhparam_file);
|
|
||||||
} else {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
|
||||||
"dhparam file not found, will use default parameters");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* audit server supports TLS version 1.2 or higher */
|
|
||||||
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
|
||||||
if (!SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION)) {
|
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
|
||||||
sudo_warnx(U_("unable to set minimum protocol version to TLS 1.2: %s"),
|
|
||||||
errstr);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
SSL_CTX_set_options(ctx,
|
|
||||||
SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tls_runtime->ssl_ctx = ctx;
|
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
bad:
|
|
||||||
SSL_CTX_free(ctx);
|
|
||||||
|
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "logsrv_util.h"
|
#include "logsrv_util.h"
|
||||||
|
#include "tls_common.h"
|
||||||
|
|
||||||
/* Default timeout value for server socket */
|
/* Default timeout value for server socket */
|
||||||
#define DEFAULT_SOCKET_TIMEOUT_SEC 30
|
#define DEFAULT_SOCKET_TIMEOUT_SEC 30
|
||||||
|
@@ -1385,81 +1385,6 @@ verify_peer_identity(int preverify_ok, X509_STORE_CTX *ctx)
|
|||||||
debug_return_int(0);
|
debug_return_int(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SSL_CTX *
|
|
||||||
init_tls_client_context(const char *ca_bundle_file, const char *cert_file, const char *key_file)
|
|
||||||
{
|
|
||||||
const SSL_METHOD *method;
|
|
||||||
SSL_CTX *ctx = NULL;
|
|
||||||
debug_decl(init_tls_client_context, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
SSL_library_init();
|
|
||||||
OpenSSL_add_all_algorithms();
|
|
||||||
SSL_load_error_strings();
|
|
||||||
|
|
||||||
if ((method = TLS_client_method()) == NULL) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"creation of SSL_METHOD failed: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if ((ctx = SSL_CTX_new(method)) == NULL) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"creation of new SSL_CTX object failed: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
|
||||||
if (!SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION)) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"unable to restrict min. protocol version: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
SSL_CTX_set_options(ctx,
|
|
||||||
SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (cert_file) {
|
|
||||||
if (!SSL_CTX_use_certificate_chain_file(ctx, cert_file)) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"unable to load cert to the ssl context: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (!SSL_CTX_use_PrivateKey_file(ctx, key_file, X509_FILETYPE_PEM)) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"unable to load key to the ssl context: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ca_bundle_file != NULL) {
|
|
||||||
/* sets the location of the CA bundle file for verification purposes */
|
|
||||||
if (SSL_CTX_load_verify_locations(ctx, ca_bundle_file, NULL) <= 0) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"calling SSL_CTX_load_verify_locations() failed: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verify_server) {
|
|
||||||
/* verify server cert during the handshake */
|
|
||||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_peer_identity);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
bad:
|
|
||||||
SSL_CTX_free(ctx);
|
|
||||||
ctx = NULL;
|
|
||||||
|
|
||||||
done:
|
|
||||||
debug_return_ptr(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tls_connect_cb(int sock, int what, void *v)
|
tls_connect_cb(int sock, int what, void *v)
|
||||||
{
|
{
|
||||||
@@ -1550,11 +1475,18 @@ tls_setup(struct client_closure *closure)
|
|||||||
const char *errstr;
|
const char *errstr;
|
||||||
debug_decl(tls_setup, SUDO_DEBUG_UTIL);
|
debug_decl(tls_setup, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
if ((ssl_ctx = init_tls_client_context(ca_bundle, cert, key)) == NULL) {
|
ssl_ctx = init_tls_context(ca_bundle, cert, key, NULL, NULL, NULL, false);
|
||||||
|
if (ssl_ctx == NULL) {
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
sudo_warnx(U_("Unable to initialize ssl context: %s"), errstr);
|
sudo_warnx(U_("Unable to initialize ssl context: %s"), errstr);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (verify_server) {
|
||||||
|
/* verify server cert during the handshake */
|
||||||
|
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, verify_peer_identity);
|
||||||
|
}
|
||||||
|
|
||||||
if ((closure->ssl = SSL_new(ssl_ctx)) == NULL) {
|
if ((closure->ssl = SSL_new(ssl_ctx)) == NULL) {
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
sudo_warnx(U_("Unable to allocate ssl object: %s"), errstr);
|
sudo_warnx(U_("Unable to allocate ssl object: %s"), errstr);
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "logsrv_util.h"
|
#include "logsrv_util.h"
|
||||||
|
#include "tls_common.h"
|
||||||
|
|
||||||
enum client_state {
|
enum client_state {
|
||||||
ERROR,
|
ERROR,
|
||||||
|
32
logsrvd/tls_common.h
Normal file
32
logsrvd/tls_common.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: ISC
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SUDO_TLS_COMMON_H
|
||||||
|
#define SUDO_TLS_COMMON_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_OPENSSL)
|
||||||
|
# include <openssl/ssl.h>
|
||||||
|
|
||||||
|
/* tls_init.c */
|
||||||
|
SSL_CTX *init_tls_context(const char *ca_bundle_file, const char *cert_file, const char *key_file, const char *dhparam_file, const char *ciphers_v12, const char *ciphers_v13, bool verify_cert);
|
||||||
|
|
||||||
|
#endif /* HAVE_OPENSSL */
|
||||||
|
|
||||||
|
#endif /* SUDO_TLS_COMMON_H */
|
307
logsrvd/tls_init.c
Normal file
307
logsrvd/tls_init.c
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: ISC
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2021 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_STDBOOL_H
|
||||||
|
# include <stdbool.h>
|
||||||
|
#else
|
||||||
|
# include "compat/stdbool.h"
|
||||||
|
#endif /* HAVE_STDBOOL_H */
|
||||||
|
#if defined(HAVE_STDINT_H)
|
||||||
|
# include <stdint.h>
|
||||||
|
#elif defined(HAVE_INTTYPES_H)
|
||||||
|
# include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_OPENSSL)
|
||||||
|
# include <openssl/ssl.h>
|
||||||
|
# include <openssl/err.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sudo_compat.h"
|
||||||
|
#include "sudo_debug.h"
|
||||||
|
#include "sudo_event.h"
|
||||||
|
#include "sudo_fatal.h"
|
||||||
|
#include "sudo_gettext.h"
|
||||||
|
|
||||||
|
#include "hostcheck.h"
|
||||||
|
#include "tls_common.h"
|
||||||
|
|
||||||
|
#define DEFAULT_CIPHER_LST12 "HIGH:!aNULL"
|
||||||
|
#define DEFAULT_CIPHER_LST13 "TLS_AES_256_GCM_SHA384"
|
||||||
|
|
||||||
|
#if defined(HAVE_OPENSSL)
|
||||||
|
|
||||||
|
static bool
|
||||||
|
verify_cert_chain(SSL_CTX *ctx, const char *cert_file)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_SSL_CTX_GET0_CERTIFICATE
|
||||||
|
bool ret = false;
|
||||||
|
X509_STORE_CTX *store_ctx = NULL;
|
||||||
|
X509_STORE *ca_store;
|
||||||
|
STACK_OF(X509) *chain_certs;
|
||||||
|
X509 *x509;
|
||||||
|
debug_decl(verify_cert_chain, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
|
if ((x509 = SSL_CTX_get0_certificate(ctx)) == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unable to get X509 object from SSL_CTX: %s",
|
||||||
|
ERR_error_string(ERR_peek_error(), NULL));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((store_ctx = X509_STORE_CTX_new()) == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unable to allocate X509_STORE_CTX object: %s",
|
||||||
|
ERR_error_string(ERR_peek_error(), NULL));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SSL_CTX_get0_chain_certs(ctx, &chain_certs)) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unable to get chain certs: %s",
|
||||||
|
ERR_error_string(ERR_peek_error(), NULL));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ca_store = SSL_CTX_get_cert_store(ctx)) != NULL)
|
||||||
|
X509_STORE_set_flags(ca_store, X509_V_FLAG_X509_STRICT);
|
||||||
|
|
||||||
|
if (!X509_STORE_CTX_init(store_ctx, ca_store, x509, chain_certs)) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unable to initialize X509_STORE_CTX object: %s",
|
||||||
|
ERR_error_string(ERR_peek_error(), NULL));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (X509_verify_cert(store_ctx) <= 0) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unable to verify cert %s: %s", cert_file,
|
||||||
|
ERR_error_string(ERR_peek_error(), NULL));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
done:
|
||||||
|
X509_STORE_CTX_free(store_ctx);
|
||||||
|
|
||||||
|
debug_return_bool(ret);
|
||||||
|
#else
|
||||||
|
/* TODO: verify server cert with old OpenSSL */
|
||||||
|
return true;
|
||||||
|
#endif /* HAVE_SSL_CTX_GET0_CERTIFICATE */
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
init_tls_ciphersuites(SSL_CTX *ctx, const char *ciphers_v12,
|
||||||
|
const char *ciphers_v13)
|
||||||
|
{
|
||||||
|
const char *errstr;
|
||||||
|
int success = 0;
|
||||||
|
debug_decl(init_tls_ciphersuites, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
|
if (ciphers_v12 != NULL) {
|
||||||
|
/* try to set TLS v1.2 ciphersuite list from config if given */
|
||||||
|
success = SSL_CTX_set_cipher_list(ctx, ciphers_v12);
|
||||||
|
if (success) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
|
"TLS 1.2 ciphersuite list set to %s", ciphers_v12);
|
||||||
|
} else {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx(U_("unable to set TLS 1.2 ciphersuite to %s: %s"),
|
||||||
|
ciphers_v12, errstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
/* fallback to default ciphersuites for TLS v1.2 */
|
||||||
|
if (SSL_CTX_set_cipher_list(ctx, DEFAULT_CIPHER_LST12) <= 0) {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx(U_("unable to set TLS 1.2 ciphersuite to %s: %s"),
|
||||||
|
DEFAULT_CIPHER_LST12, errstr);
|
||||||
|
debug_return_bool(false);
|
||||||
|
} else {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
|
"TLS v1.2 ciphersuite list set to %s (default)",
|
||||||
|
DEFAULT_CIPHER_LST12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# if defined(HAVE_SSL_CTX_SET_CIPHERSUITES)
|
||||||
|
success = 0;
|
||||||
|
if (ciphers_v13 != NULL) {
|
||||||
|
/* try to set TLSv1.3 ciphersuite list from config */
|
||||||
|
success = SSL_CTX_set_ciphersuites(ctx, ciphers_v13);
|
||||||
|
if (success) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
|
"TLS v1.3 ciphersuite list set to %s", ciphers_v13);
|
||||||
|
} else {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx(U_("unable to set TLS 1.3 ciphersuite to %s: %s"),
|
||||||
|
ciphers_v13, errstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
/* fallback to default ciphersuites for TLS v1.3 */
|
||||||
|
if (SSL_CTX_set_ciphersuites(ctx, LOGSRVD_DEFAULT_CIPHER_LST13) <= 0) {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx(U_("unable to set TLS 1.3 ciphersuite to %s: %s"),
|
||||||
|
LOGSRVD_DEFAULT_CIPHER_LST13, errstr);
|
||||||
|
debug_return_bool(false);
|
||||||
|
} else {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
|
"TLS v1.3 ciphersuite list set to %s (default)",
|
||||||
|
LOGSRVD_DEFAULT_CIPHER_LST13);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SSL_CTX *
|
||||||
|
init_tls_context(const char *ca_bundle_file, const char *cert_file,
|
||||||
|
const char *key_file, const char *dhparam_file, const char *ciphers_v12,
|
||||||
|
const char *ciphers_v13, bool verify_cert)
|
||||||
|
{
|
||||||
|
SSL_CTX *ctx = NULL;
|
||||||
|
const char *errstr;
|
||||||
|
debug_decl(init_tls_context, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
|
SSL_library_init();
|
||||||
|
OpenSSL_add_all_algorithms();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
|
||||||
|
/* Create the ssl context and enforce TLS 1.2 or higher. */
|
||||||
|
if ((ctx = SSL_CTX_new(TLS_client_method())) == NULL) {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx(U_("unable to create TLS context: %s"), errstr);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
||||||
|
if (!SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION)) {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx(U_("unable to set minimum protocol version to TLS 1.2: %s"),
|
||||||
|
errstr);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
SSL_CTX_set_options(ctx,
|
||||||
|
SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ca_bundle_file != NULL) {
|
||||||
|
STACK_OF(X509_NAME) *cacerts =
|
||||||
|
SSL_load_client_CA_file(ca_bundle_file);
|
||||||
|
|
||||||
|
if (cacerts == NULL) {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx(U_("%s: %s"), ca_bundle_file, errstr);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
SSL_CTX_set_client_CA_list(ctx, cacerts);
|
||||||
|
|
||||||
|
if (SSL_CTX_load_verify_locations(ctx, ca_bundle_file, NULL) <= 0) {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx("SSL_CTX_load_verify_locations: %s", errstr);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!SSL_CTX_set_default_verify_paths(ctx)) {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx("SSL_CTX_set_default_verify_paths: %s", errstr);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cert_file != NULL) {
|
||||||
|
if (!SSL_CTX_use_certificate_chain_file(ctx, cert_file)) {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx(U_("%s: %s"), cert_file, errstr);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
if (key_file == NULL) {
|
||||||
|
/* No explicit key file set, try to use the cert file. */
|
||||||
|
key_file = cert_file;
|
||||||
|
}
|
||||||
|
if (!SSL_CTX_use_PrivateKey_file(ctx, key_file, X509_FILETYPE_PEM) ||
|
||||||
|
!SSL_CTX_check_private_key(ctx)) {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx(U_("%s: %s"), key_file, errstr);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optionally verify the certificate we are using. */
|
||||||
|
if (verify_cert) {
|
||||||
|
if (!verify_cert_chain(ctx, cert_file))
|
||||||
|
goto bad;
|
||||||
|
} else {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
|
"skipping local cert check");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize TLS 1.2 1.3 ciphersuites. */
|
||||||
|
if (!init_tls_ciphersuites(ctx, ciphers_v12, ciphers_v13)) {
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load diffie-hellman parameters from a file if specified.
|
||||||
|
* Failure to open the file is not a fatal error.
|
||||||
|
*/
|
||||||
|
if (dhparam_file != NULL) {
|
||||||
|
FILE *fp = fopen(dhparam_file, "r");
|
||||||
|
if (fp != NULL) {
|
||||||
|
DH *dhparams = PEM_read_DHparams(fp, NULL, NULL, NULL);
|
||||||
|
if (dhparams != NULL) {
|
||||||
|
if (!SSL_CTX_set_tmp_dh(ctx, dhparams)) {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx(U_("unable to set diffie-hellman parameters: %s"),
|
||||||
|
errstr);
|
||||||
|
DH_free(dhparams);
|
||||||
|
} else {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
|
"loaded diffie-hellman parameters from %s", dhparam_file);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
|
sudo_warnx(U_("unable to read diffie-hellman parameters: %s"),
|
||||||
|
errstr);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
} else {
|
||||||
|
sudo_warn(U_("unable to open %s"), dhparam_file);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
|
"dhparam file not specified, using default parameters");
|
||||||
|
}
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
|
||||||
|
done:
|
||||||
|
debug_return_ptr(ctx);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_OPENSSL */
|
Reference in New Issue
Block a user