From cc7dccb1858e73176814c3a8457ff6f94ff45662 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 13 Jan 2021 11:36:16 +0000 Subject: Implement handshake timeout for libtls backend --- doc/s6-tlsc-io.html | 4 +--- doc/s6-tlsd-io.html | 4 +--- package/deps.mak | 9 +++++---- src/include/s6-networking/stls.h | 5 +++-- src/sbearssl/sbearssl_run.c | 11 +++++++---- src/stls/deps-lib/stls | 2 ++ src/stls/stls-internal.h | 5 +++++ src/stls/stls_client_init_and_handshake.c | 4 ++-- src/stls/stls_handshake.c | 30 ++++++++++++++++++++++++++++++ src/stls/stls_server_init_and_handshake.c | 4 ++-- src/tls/s6-tlsc-io.c | 3 +-- src/tls/s6-tlsd-io.c | 3 +-- 12 files changed, 60 insertions(+), 24 deletions(-) create mode 100644 src/stls/stls_handshake.c diff --git a/doc/s6-tlsc-io.html b/doc/s6-tlsc-io.html index d4c1b7e..b2e9ce1 100644 --- a/doc/s6-tlsc-io.html +++ b/doc/s6-tlsc-io.html @@ -198,9 +198,7 @@ use SNI, which may be a security risk.
  • -K kimeout : if the peer fails to send data for kimeout milliseconds during the handshake, close the connection. The default is 0, which means infinite timeout -(never kill the connection). This option is ignored by the -libtls backend, which does not have a way to interrupt -the handshake after a timeout.
  • +(never kill the connection).
  • -d notif : handshake notification. notif must be a file descriptor open for writing. When the TLS handshake has completed, some data (terminated by two null diff --git a/doc/s6-tlsd-io.html b/doc/s6-tlsd-io.html index 00f7cd4..8f84728 100644 --- a/doc/s6-tlsd-io.html +++ b/doc/s6-tlsd-io.html @@ -193,9 +193,7 @@ connection without using close_notify. This is the default.
  • -K kimeout : if the peer fails to send data for kimeout milliseconds during the handshake, close the connection. The default is 0, which means infinite timeout -(never kill the connection). This option is ignored by the -libtls backend, which does not have a way to interrupt -the handshake after a timeout.
  • +(never kill the connection).
  • -d notif : handshake notification. notif must be a file descriptor open for writing. When the TLS handshake has completed, some data (terminated by two null diff --git a/package/deps.mak b/package/deps.mak index 784e1eb..145adca 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -70,6 +70,7 @@ src/sbearssl/sbearssl_x500_name_len.o src/sbearssl/sbearssl_x500_name_len.lo: sr src/sbearssl/sbearssl_x509_minimal_set_tai.o src/sbearssl/sbearssl_x509_minimal_set_tai.lo: src/sbearssl/sbearssl_x509_minimal_set_tai.c src/include/s6-networking/sbearssl.h src/stls/stls_client_init_and_handshake.o src/stls/stls_client_init_and_handshake.lo: src/stls/stls_client_init_and_handshake.c src/include/s6-networking/stls.h src/stls/stls-internal.h src/stls/stls_drop.o src/stls/stls_drop.lo: src/stls/stls_drop.c src/stls/stls-internal.h +src/stls/stls_handshake.o src/stls/stls_handshake.lo: src/stls/stls_handshake.c src/stls/stls-internal.h src/stls/stls_run.o src/stls/stls_run.lo: src/stls/stls_run.c src/include/s6-networking/stls.h src/stls/stls_send_environment.o src/stls/stls_send_environment.lo: src/stls/stls_send_environment.c src/include/s6-networking/stls.h src/stls/stls_server_init_and_handshake.o src/stls/stls_server_init_and_handshake.lo: src/stls/stls_server_init_and_handshake.c src/include/s6-networking/stls.h src/stls/stls-internal.h @@ -135,12 +136,12 @@ endif libsbearssl.so.xyzzy: EXTRA_LIBS := -lbearssl -lskarnet libsbearssl.so.xyzzy: src/sbearssl/sbearssl_append.lo src/sbearssl/sbearssl_cert_from.lo src/sbearssl/sbearssl_cert_readbigpem.lo src/sbearssl/sbearssl_cert_readfile.lo src/sbearssl/sbearssl_cert_to.lo src/sbearssl/sbearssl_client_init_and_run.lo src/sbearssl/sbearssl_drop.lo src/sbearssl/sbearssl_ec_issuer_keytype.lo src/sbearssl/sbearssl_ec_pkey_from.lo src/sbearssl/sbearssl_ec_pkey_to.lo src/sbearssl/sbearssl_ec_skey_from.lo src/sbearssl/sbearssl_ec_skey_to.lo src/sbearssl/sbearssl_error_str.lo src/sbearssl/sbearssl_isder.lo src/sbearssl/sbearssl_pem_decode_from_buffer.lo src/sbearssl/sbearssl_pem_decode_from_string.lo src/sbearssl/sbearssl_pem_push.lo src/sbearssl/sbearssl_pkey_from.lo src/sbearssl/sbearssl_pkey_to.lo src/sbearssl/sbearssl_rsa_pkey_from.lo src/sbearssl/sbearssl_rsa_pkey_to.lo src/sbearssl/sbearssl_rsa_skey_from.lo src/sbearssl/sbearssl_rsa_skey_to.lo src/sbearssl/sbearssl_run.lo src/sbearssl/sbearssl_send_environment.lo src/sbearssl/sbearssl_server_init_and_run.lo src/sbearssl/sbearssl_skey_from.lo src/sbearssl/sbearssl_skey_readfile.lo src/sbearssl/sbearssl_skey_to.lo src/sbearssl/sbearssl_suite_bits.lo src/sbearssl/sbearssl_suite_list.lo src/sbearssl/sbearssl_suite_name.lo src/sbearssl/sbearssl_ta_cert.lo src/sbearssl/sbearssl_ta_certs.lo src/sbearssl/sbearssl_ta_from.lo src/sbearssl/sbearssl_ta_readdir.lo src/sbearssl/sbearssl_ta_readfile.lo src/sbearssl/sbearssl_ta_to.lo src/sbearssl/sbearssl_x500_name_len.lo src/sbearssl/sbearssl_x500_from_ta.lo src/sbearssl/sbearssl_x509_minimal_set_tai.lo ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),) -libstls.a.xyzzy: src/stls/stls_drop.o src/stls/stls_run.o src/stls/stls_client_init_and_handshake.o src/stls/stls_server_init_and_handshake.o src/stls/stls_send_environment.o +libstls.a.xyzzy: src/stls/stls_drop.o src/stls/stls_handshake.o src/stls/stls_run.o src/stls/stls_client_init_and_handshake.o src/stls/stls_server_init_and_handshake.o src/stls/stls_send_environment.o else -libstls.a.xyzzy: src/stls/stls_drop.lo src/stls/stls_run.lo src/stls/stls_client_init_and_handshake.lo src/stls/stls_server_init_and_handshake.lo src/stls/stls_send_environment.lo +libstls.a.xyzzy: src/stls/stls_drop.lo src/stls/stls_handshake.lo src/stls/stls_run.lo src/stls/stls_client_init_and_handshake.lo src/stls/stls_server_init_and_handshake.lo src/stls/stls_send_environment.lo endif -libstls.so.xyzzy: EXTRA_LIBS := ${CRYPTO_LIB} -lskarnet -libstls.so.xyzzy: src/stls/stls_drop.lo src/stls/stls_run.lo src/stls/stls_client_init_and_handshake.lo src/stls/stls_server_init_and_handshake.lo src/stls/stls_send_environment.lo +libstls.so.xyzzy: EXTRA_LIBS := ${CRYPTO_LIB} -lskarnet ${TIMER_LIB} +libstls.so.xyzzy: src/stls/stls_drop.lo src/stls/stls_handshake.lo src/stls/stls_run.lo src/stls/stls_client_init_and_handshake.lo src/stls/stls_server_init_and_handshake.lo src/stls/stls_send_environment.lo ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),) libs6tls.a.xyzzy: src/tls/s6tls_exec_tlscio.o src/tls/s6tls_exec_tlsdio.o src/tls/s6tls_sync_and_exec_app.o src/tls/s6tls_ucspi_exec_app.o else diff --git a/src/include/s6-networking/stls.h b/src/include/s6-networking/stls.h index 65bb950..071b96b 100644 --- a/src/include/s6-networking/stls.h +++ b/src/include/s6-networking/stls.h @@ -8,6 +8,7 @@ #include #include +#include #define STLS_BUFSIZE (16384 + 325 + 1) @@ -20,7 +21,7 @@ extern void stls_run (struct tls *, int *, uint32_t, unsigned int) gccattr_noret /* s6-tlsc-io and s6-tlsd-io */ -struct tls *stls_client_init_and_handshake (int const *, uint32_t, char const *) ; -struct tls *stls_server_init_and_handshake (int const *, uint32_t) ; +struct tls *stls_client_init_and_handshake (int const *, tain_t const *, uint32_t, char const *) ; +struct tls *stls_server_init_and_handshake (int const *, tain_t const *, uint32_t) ; #endif diff --git a/src/sbearssl/sbearssl_run.c b/src/sbearssl/sbearssl_run.c index e097698..fda9f3e 100644 --- a/src/sbearssl/sbearssl_run.c +++ b/src/sbearssl/sbearssl_run.c @@ -29,7 +29,7 @@ void sbearssl_run (br_ssl_engine_context *ctx, int *fds, tain_t const *tto, uint for (;;) { - tain_t deadline = tain_infinite_relative ; + tain_t deadline = TAIN_INFINITE ; unsigned int j = 0 ; unsigned int state = br_ssl_engine_current_state(ctx) ; int r ; @@ -79,13 +79,16 @@ void sbearssl_run (br_ssl_engine_context *ctx, int *fds, tain_t const *tto, uint if (xindex[0] == 4 && xindex[1] == 4 && xindex[3] == 4) { if (!j || handshake_done) break ; - deadline = *tto ; + tain_add_g(&deadline, tto) ; } - tain_add_g(&deadline, &deadline) ; r = iopause_g(x, j, &deadline) ; if (r < 0) strerr_diefu1sys(111, "iopause") ; - else if (!r) break ; + else if (!r) + { + if (verbosity) strerr_dief1x(98, "handshake timed out") ; + else _exit(98) ; + } while (j--) if (x[j].revents & IOPAUSE_EXCEPT) diff --git a/src/stls/deps-lib/stls b/src/stls/deps-lib/stls index 615ce3b..b7b94ec 100644 --- a/src/stls/deps-lib/stls +++ b/src/stls/deps-lib/stls @@ -1,7 +1,9 @@ stls_drop.o +stls_handshake.o stls_run.o stls_client_init_and_handshake.o stls_server_init_and_handshake.o stls_send_environment.o ${CRYPTO_LIB} -lskarnet +${TIMER_LIB} diff --git a/src/stls/stls-internal.h b/src/stls/stls-internal.h index afe7a80..ef004ea 100644 --- a/src/stls/stls-internal.h +++ b/src/stls/stls-internal.h @@ -3,6 +3,11 @@ #ifndef STLS_INTERNAL_H #define STLS_INTERNAL_H +#include + +#include + extern void stls_drop (void) ; +extern void stls_handshake (struct tls *, tain_t const *) ; #endif diff --git a/src/stls/stls_client_init_and_handshake.c b/src/stls/stls_client_init_and_handshake.c index fdea482..7e0bc13 100644 --- a/src/stls/stls_client_init_and_handshake.c +++ b/src/stls/stls_client_init_and_handshake.c @@ -12,7 +12,7 @@ #define diecfg(cfg, s) strerr_diefu3x(96, (s), ": ", tls_config_error(cfg)) #define diectx(e, ctx, s) strerr_diefu3x(e, (s), ": ", tls_error(ctx)) -struct tls *stls_client_init_and_handshake (int const *fds, uint32_t preoptions, char const *servername) +struct tls *stls_client_init_and_handshake (int const *fds, tain_t const *tto, uint32_t preoptions, char const *servername) { struct tls *ctx ; struct tls_config *cfg ; @@ -76,6 +76,6 @@ struct tls *stls_client_init_and_handshake (int const *fds, uint32_t preoptions, if (tls_connect_fds(ctx, fds[0], fds[1], servername) < 0) diectx(97, ctx, "tls_connect_fds") ; tls_config_free(cfg) ; - if (tls_handshake(ctx) < 0) diectx(97, ctx, "tls_handshake") ; + stls_handshake(ctx, tto) ; return ctx ; } diff --git a/src/stls/stls_handshake.c b/src/stls/stls_handshake.c new file mode 100644 index 0000000..989a167 --- /dev/null +++ b/src/stls/stls_handshake.c @@ -0,0 +1,30 @@ +/* ISC license. */ + +#include +#include + +#include + +#include +#include + +#include "stls-internal.h" + +#define diectx(e, ctx, s) strerr_diefu3x(e, (s), ": ", tls_error(ctx)) + +static void alrm_handler (int sig) +{ + strerr_dief1x(98, "handshake timed out") ; +} + +void stls_handshake (struct tls *ctx, tain_t const *tto) +{ + struct sigaction saold ; + struct sigaction sanew = { .sa_handler = &alrm_handler, .sa_flags = SA_RESTART, .sa_sigaction = 0 } ; + sigfillset(&sanew.sa_mask) ; + if (sigaction(SIGALRM, &sanew, &saold) < 0) strerr_diefu1sys(111, "sigaction") ; + if (!alarm_timeout(tto)) strerr_diefu1sys(111, "set an alarm") ; + if (tls_handshake(ctx) < 0) diectx(97, ctx, "tls_handshake") ; + alarm_disable() ; + sigaction(SIGALRM, &saold, 0) ; +} diff --git a/src/stls/stls_server_init_and_handshake.c b/src/stls/stls_server_init_and_handshake.c index e6869be..4a5b2ff 100644 --- a/src/stls/stls_server_init_and_handshake.c +++ b/src/stls/stls_server_init_and_handshake.c @@ -12,7 +12,7 @@ #define diecfg(cfg, s) strerr_diefu3x(96, (s), ": ", tls_config_error(cfg)) #define diectx(e, ctx, s) strerr_diefu3x(e, (s), ": ", tls_error(ctx)) -struct tls *stls_server_init_and_handshake (int const *fds, uint32_t preoptions) +struct tls *stls_server_init_and_handshake (int const *fds, tain_t const *tto, uint32_t preoptions) { struct tls *ctx = 0 ; struct tls *sctx ; @@ -77,6 +77,6 @@ struct tls *stls_server_init_and_handshake (int const *fds, uint32_t preoptions) if (tls_accept_fds(sctx, &ctx, fds[0], fds[1]) < 0) diectx(97, sctx, "tls_accept_fds") ; tls_free(sctx) ; - if (tls_handshake(ctx) < 0) diectx(97, ctx, "tls_handshake") ; + stls_handshake(ctx, tto) ; return ctx ; } diff --git a/src/tls/s6-tlsc-io.c b/src/tls/s6-tlsc-io.c index 8629a8d..7c92d96 100644 --- a/src/tls/s6-tlsc-io.c +++ b/src/tls/s6-tlsc-io.c @@ -24,14 +24,13 @@ static inline void doit (int *, tain_t const *tto, uint32_t, uint32_t, unsigned static inline void doit (int *fds, tain_t const *tto, uint32_t preoptions, uint32_t options, unsigned int verbosity, char const *servername, unsigned int notif) { - struct tls *ctx = stls_client_init_and_handshake(fds + 2, preoptions, servername) ; + struct tls *ctx = stls_client_init_and_handshake(fds + 2, tto, preoptions, servername) ; if (notif) { if (!stls_send_environment(ctx, notif)) strerr_diefu1sys(111, "write post-handshake data") ; fd_close(notif) ; } - (void)tto ; stls_run(ctx, fds, options, verbosity) ; } diff --git a/src/tls/s6-tlsd-io.c b/src/tls/s6-tlsd-io.c index b6621dd..01f0d74 100644 --- a/src/tls/s6-tlsd-io.c +++ b/src/tls/s6-tlsd-io.c @@ -24,14 +24,13 @@ static inline void doit (int *, tain_t const *tto, uint32_t, uint32_t, unsigned static inline void doit (int *fds, tain_t const *tto, uint32_t preoptions, uint32_t options, unsigned int verbosity, unsigned int notif) { - struct tls *ctx = stls_server_init_and_handshake(fds + 2, preoptions) ; + struct tls *ctx = stls_server_init_and_handshake(fds + 2, tto, preoptions) ; if (notif) { if (!stls_send_environment(ctx, notif)) strerr_diefu1sys(111, "write post-handshake data") ; fd_close(notif) ; } - (void)tto ; stls_run(ctx, fds, options, verbosity) ; } -- cgit v1.2.3