|
|
62af7d |
From c11cc83d9ee9230f090c2400a57bbd562905d782 Mon Sep 17 00:00:00 2001
|
|
|
62af7d |
From: Nikos Mavrogiannopoulos <nmav@redhat.com>
|
|
|
62af7d |
Date: Mon, 8 Oct 2018 10:42:22 +0200
|
|
|
62af7d |
Subject: [PATCH] Enable post-handshake auth under gnutls on TLS1.3
|
|
|
62af7d |
|
|
|
62af7d |
---
|
|
|
62af7d |
src/gnutls.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
62af7d |
1 file changed, 96 insertions(+)
|
|
|
62af7d |
|
|
|
62af7d |
diff --git a/src/gnutls.c b/src/gnutls.c
|
|
|
62af7d |
index 206d0b09..a2c9d1c1 100644
|
|
|
62af7d |
--- a/src/gnutls.c
|
|
|
62af7d |
+++ b/src/gnutls.c
|
|
|
62af7d |
@@ -60,6 +60,11 @@ as that of the covered work. */
|
|
|
62af7d |
static int
|
|
|
62af7d |
_do_handshake (gnutls_session_t session, int fd, double timeout);
|
|
|
62af7d |
|
|
|
62af7d |
+#if GNUTLS_VERSION_NUMBER >= 0x030604
|
|
|
62af7d |
+static int
|
|
|
62af7d |
+_do_reauth (gnutls_session_t session, int fd, double timeout);
|
|
|
62af7d |
+#endif
|
|
|
62af7d |
+
|
|
|
62af7d |
static int
|
|
|
62af7d |
key_type_to_gnutls_type (enum keyfile_type type)
|
|
|
62af7d |
{
|
|
|
62af7d |
@@ -287,6 +292,14 @@ wgnutls_read_timeout (int fd, char *buf, int bufsize, void *arg, double timeout)
|
|
|
62af7d |
if ((ret = _do_handshake (ctx->session, fd, timeout)) == 0)
|
|
|
62af7d |
ret = GNUTLS_E_AGAIN; /* restart reading */
|
|
|
62af7d |
}
|
|
|
62af7d |
+#if GNUTLS_VERSION_NUMBER >= 0x030604
|
|
|
62af7d |
+ if (!timed_out && ret == GNUTLS_E_REAUTH_REQUEST)
|
|
|
62af7d |
+ {
|
|
|
62af7d |
+ DEBUGP (("GnuTLS: *** re-authentication while reading\n"));
|
|
|
62af7d |
+ if ((ret = _do_reauth (ctx->session, fd, timeout)) == 0)
|
|
|
62af7d |
+ ret = GNUTLS_E_AGAIN; /* restart reading */
|
|
|
62af7d |
+ }
|
|
|
62af7d |
+#endif
|
|
|
62af7d |
}
|
|
|
62af7d |
}
|
|
|
62af7d |
while (ret == GNUTLS_E_INTERRUPTED || (ret == GNUTLS_E_AGAIN && !timed_out));
|
|
|
62af7d |
@@ -519,6 +532,84 @@ _do_handshake (gnutls_session_t session, int fd, double timeout)
|
|
|
62af7d |
return err;
|
|
|
62af7d |
}
|
|
|
62af7d |
|
|
|
62af7d |
+#if GNUTLS_VERSION_NUMBER >= 0x030604
|
|
|
62af7d |
+static int
|
|
|
62af7d |
+_do_reauth (gnutls_session_t session, int fd, double timeout)
|
|
|
62af7d |
+{
|
|
|
62af7d |
+#ifdef F_GETFL
|
|
|
62af7d |
+ int flags = 0;
|
|
|
62af7d |
+#endif
|
|
|
62af7d |
+ int err;
|
|
|
62af7d |
+
|
|
|
62af7d |
+ if (timeout)
|
|
|
62af7d |
+ {
|
|
|
62af7d |
+#ifdef F_GETFL
|
|
|
62af7d |
+ flags = fcntl (fd, F_GETFL, 0);
|
|
|
62af7d |
+ if (flags < 0)
|
|
|
62af7d |
+ return flags;
|
|
|
62af7d |
+ if (fcntl (fd, F_SETFL, flags | O_NONBLOCK))
|
|
|
62af7d |
+ return -1;
|
|
|
62af7d |
+#else
|
|
|
62af7d |
+ /* XXX: Assume it was blocking before. */
|
|
|
62af7d |
+ const int one = 1;
|
|
|
62af7d |
+ if (ioctl (fd, FIONBIO, &one) < 0)
|
|
|
62af7d |
+ return -1;
|
|
|
62af7d |
+#endif
|
|
|
62af7d |
+ }
|
|
|
62af7d |
+
|
|
|
62af7d |
+ /* We don't stop the handshake process for non-fatal errors */
|
|
|
62af7d |
+ do
|
|
|
62af7d |
+ {
|
|
|
62af7d |
+ err = gnutls_reauth (session, 0);
|
|
|
62af7d |
+
|
|
|
62af7d |
+ if (timeout && err == GNUTLS_E_AGAIN)
|
|
|
62af7d |
+ {
|
|
|
62af7d |
+ if (gnutls_record_get_direction (session))
|
|
|
62af7d |
+ {
|
|
|
62af7d |
+ /* wait for writeability */
|
|
|
62af7d |
+ err = select_fd (fd, timeout, WAIT_FOR_WRITE);
|
|
|
62af7d |
+ }
|
|
|
62af7d |
+ else
|
|
|
62af7d |
+ {
|
|
|
62af7d |
+ /* wait for readability */
|
|
|
62af7d |
+ err = select_fd (fd, timeout, WAIT_FOR_READ);
|
|
|
62af7d |
+ }
|
|
|
62af7d |
+
|
|
|
62af7d |
+ if (err <= 0)
|
|
|
62af7d |
+ {
|
|
|
62af7d |
+ if (err == 0)
|
|
|
62af7d |
+ {
|
|
|
62af7d |
+ errno = ETIMEDOUT;
|
|
|
62af7d |
+ err = -1;
|
|
|
62af7d |
+ }
|
|
|
62af7d |
+ break;
|
|
|
62af7d |
+ }
|
|
|
62af7d |
+
|
|
|
62af7d |
+ err = GNUTLS_E_AGAIN;
|
|
|
62af7d |
+ }
|
|
|
62af7d |
+ else if (err < 0)
|
|
|
62af7d |
+ {
|
|
|
62af7d |
+ logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err));
|
|
|
62af7d |
+ }
|
|
|
62af7d |
+ }
|
|
|
62af7d |
+ while (err && gnutls_error_is_fatal (err) == 0);
|
|
|
62af7d |
+
|
|
|
62af7d |
+ if (timeout)
|
|
|
62af7d |
+ {
|
|
|
62af7d |
+#ifdef F_GETFL
|
|
|
62af7d |
+ if (fcntl (fd, F_SETFL, flags) < 0)
|
|
|
62af7d |
+ return -1;
|
|
|
62af7d |
+#else
|
|
|
62af7d |
+ const int zero = 0;
|
|
|
62af7d |
+ if (ioctl (fd, FIONBIO, &zero) < 0)
|
|
|
62af7d |
+ return -1;
|
|
|
62af7d |
+#endif
|
|
|
62af7d |
+ }
|
|
|
62af7d |
+
|
|
|
62af7d |
+ return err;
|
|
|
62af7d |
+}
|
|
|
62af7d |
+#endif
|
|
|
62af7d |
+
|
|
|
62af7d |
static const char *
|
|
|
62af7d |
_sni_hostname(const char *hostname)
|
|
|
62af7d |
{
|
|
|
62af7d |
@@ -655,7 +746,12 @@ ssl_connect_wget (int fd, const char *hostname, int *continue_session)
|
|
|
62af7d |
gnutls_session_t session;
|
|
|
62af7d |
int err;
|
|
|
62af7d |
|
|
|
62af7d |
+#if GNUTLS_VERSION_NUMBER >= 0x030604
|
|
|
62af7d |
+ // enable support of TLS1.3 post-handshake authentication
|
|
|
62af7d |
+ gnutls_init (&session, GNUTLS_CLIENT | GNUTLS_POST_HANDSHAKE_AUTH);
|
|
|
62af7d |
+#else
|
|
|
62af7d |
gnutls_init (&session, GNUTLS_CLIENT);
|
|
|
62af7d |
+#endif
|
|
|
62af7d |
|
|
|
62af7d |
/* We set the server name but only if it's not an IP address. */
|
|
|
62af7d |
if (! is_valid_ip_address (hostname))
|
|
|
62af7d |
--
|
|
|
62af7d |
2.17.2
|
|
|
62af7d |
|