Enable post-handshake auth under gnutls on TLS1.3

This commit is contained in:
Nikos Mavrogiannopoulos 2018-10-08 10:42:22 +02:00 committed by Tim Rühsen
parent 0727b8f3a9
commit c11cc83d9e

View File

@ -60,6 +60,11 @@ as that of the covered work. */
static int
_do_handshake (gnutls_session_t session, int fd, double timeout);
#if GNUTLS_VERSION_NUMBER >= 0x030604
static int
_do_reauth (gnutls_session_t session, int fd, double timeout);
#endif
static int
key_type_to_gnutls_type (enum keyfile_type type)
{
@ -287,6 +292,14 @@ wgnutls_read_timeout (int fd, char *buf, int bufsize, void *arg, double timeout)
if ((ret = _do_handshake (ctx->session, fd, timeout)) == 0)
ret = GNUTLS_E_AGAIN; /* restart reading */
}
#if GNUTLS_VERSION_NUMBER >= 0x030604
if (!timed_out && ret == GNUTLS_E_REAUTH_REQUEST)
{
DEBUGP (("GnuTLS: *** re-authentication while reading\n"));
if ((ret = _do_reauth (ctx->session, fd, timeout)) == 0)
ret = GNUTLS_E_AGAIN; /* restart reading */
}
#endif
}
}
while (ret == GNUTLS_E_INTERRUPTED || (ret == GNUTLS_E_AGAIN && !timed_out));
@ -519,6 +532,84 @@ _do_handshake (gnutls_session_t session, int fd, double timeout)
return err;
}
#if GNUTLS_VERSION_NUMBER >= 0x030604
static int
_do_reauth (gnutls_session_t session, int fd, double timeout)
{
#ifdef F_GETFL
int flags = 0;
#endif
int err;
if (timeout)
{
#ifdef F_GETFL
flags = fcntl (fd, F_GETFL, 0);
if (flags < 0)
return flags;
if (fcntl (fd, F_SETFL, flags | O_NONBLOCK))
return -1;
#else
/* XXX: Assume it was blocking before. */
const int one = 1;
if (ioctl (fd, FIONBIO, &one) < 0)
return -1;
#endif
}
/* We don't stop the handshake process for non-fatal errors */
do
{
err = gnutls_reauth (session, 0);
if (timeout && err == GNUTLS_E_AGAIN)
{
if (gnutls_record_get_direction (session))
{
/* wait for writeability */
err = select_fd (fd, timeout, WAIT_FOR_WRITE);
}
else
{
/* wait for readability */
err = select_fd (fd, timeout, WAIT_FOR_READ);
}
if (err <= 0)
{
if (err == 0)
{
errno = ETIMEDOUT;
err = -1;
}
break;
}
err = GNUTLS_E_AGAIN;
}
else if (err < 0)
{
logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err));
}
}
while (err && gnutls_error_is_fatal (err) == 0);
if (timeout)
{
#ifdef F_GETFL
if (fcntl (fd, F_SETFL, flags) < 0)
return -1;
#else
const int zero = 0;
if (ioctl (fd, FIONBIO, &zero) < 0)
return -1;
#endif
}
return err;
}
#endif
static const char *
_sni_hostname(const char *hostname)
{
@ -655,7 +746,12 @@ ssl_connect_wget (int fd, const char *hostname, int *continue_session)
gnutls_session_t session;
int err;
#if GNUTLS_VERSION_NUMBER >= 0x030604
// enable support of TLS1.3 post-handshake authentication
gnutls_init (&session, GNUTLS_CLIENT | GNUTLS_POST_HANDSHAKE_AUTH);
#else
gnutls_init (&session, GNUTLS_CLIENT);
#endif
/* We set the server name but only if it's not an IP address. */
if (! is_valid_ip_address (hostname))