summaryrefslogtreecommitdiff
path: root/src/gnutls.c
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-03-05 10:08:23 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-03-05 10:08:23 +0900
commitc0c4ebc8462f91e7cf41e7404f71dca434b8494e (patch)
tree764f42c7258a7f83c64a1e75669b5694072cee20 /src/gnutls.c
parentdfd19f19c019e044f97e46081a6960614c0cf3f9 (diff)
downloadwget-c0c4ebc8462f91e7cf41e7404f71dca434b8494e.tar.gz
wget-c0c4ebc8462f91e7cf41e7404f71dca434b8494e.tar.bz2
wget-c0c4ebc8462f91e7cf41e7404f71dca434b8494e.zip
Imported Upstream version 1.20upstream/1.20
Diffstat (limited to 'src/gnutls.c')
-rw-r--r--src/gnutls.c126
1 files changed, 125 insertions, 1 deletions
diff --git a/src/gnutls.c b/src/gnutls.c
index 0368b4a..a2c9d1c 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -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)
{
@@ -565,6 +656,15 @@ set_prio_default (gnutls_session_t session)
err = gnutls_priority_set_direct (session, "NORMAL:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1", NULL);
break;
+ case secure_protocol_tlsv1_3:
+#if GNUTLS_VERSION_NUMBER >= 0x030603
+ err = gnutls_priority_set_direct (session, "NORMAL:-VERS-SSL3.0:+VERS-TLS1.3:-VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.2", NULL);
+ break;
+#else
+ logprintf (LOG_NOTQUIET, _("Your GnuTLS version is too old to support TLS 1.3\n"));
+ return -1;
+#endif
+
case secure_protocol_pfs:
err = gnutls_priority_set_direct (session, "PFS:-VERS-SSL3.0", NULL);
if (err != GNUTLS_E_SUCCESS)
@@ -596,19 +696,38 @@ set_prio_default (gnutls_session_t session)
allowed_protocols[0] = GNUTLS_TLS1_0;
allowed_protocols[1] = GNUTLS_TLS1_1;
allowed_protocols[2] = GNUTLS_TLS1_2;
+#if GNUTLS_VERSION_NUMBER >= 0x030603
+ allowed_protocols[3] = GNUTLS_TLS1_3;
+#endif
err = gnutls_protocol_set_priority (session, allowed_protocols);
break;
case secure_protocol_tlsv1_1:
allowed_protocols[0] = GNUTLS_TLS1_1;
allowed_protocols[1] = GNUTLS_TLS1_2;
+#if GNUTLS_VERSION_NUMBER >= 0x030603
+ allowed_protocols[2] = GNUTLS_TLS1_3;
+#endif
err = gnutls_protocol_set_priority (session, allowed_protocols);
break;
case secure_protocol_tlsv1_2:
allowed_protocols[0] = GNUTLS_TLS1_2;
+#if GNUTLS_VERSION_NUMBER >= 0x030603
+ allowed_protocols[1] = GNUTLS_TLS1_3;
+#endif
+ err = gnutls_protocol_set_priority (session, allowed_protocols);
+ break;
+
+ case secure_protocol_tlsv1_3:
+#if GNUTLS_VERSION_NUMBER >= 0x030603
+ allowed_protocols[0] = GNUTLS_TLS1_3;
err = gnutls_protocol_set_priority (session, allowed_protocols);
break;
+#else
+ logprintf (LOG_NOTQUIET, _("Your GnuTLS version is too old to support TLS 1.3\n"));
+ return -1;
+#endif
default:
logprintf (LOG_NOTQUIET, _("GnuTLS: unimplemented 'secure-protocol' option value %d\n"), opt.secure_protocol);
@@ -627,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))
@@ -805,7 +929,7 @@ ssl_check_certificate (int fd, const char *host)
}
_CHECK_CERT (GNUTLS_CERT_INVALID, _("%s: The certificate of %s is not trusted.\n"));
- _CHECK_CERT (GNUTLS_CERT_SIGNER_NOT_FOUND, _("%s: The certificate of %s hasn't got a known issuer.\n"));
+ _CHECK_CERT (GNUTLS_CERT_SIGNER_NOT_FOUND, _("%s: The certificate of %s doesn't have a known issuer.\n"));
_CHECK_CERT (GNUTLS_CERT_REVOKED, _("%s: The certificate of %s has been revoked.\n"));
_CHECK_CERT (GNUTLS_CERT_SIGNER_NOT_CA, _("%s: The certificate signer of %s was not a CA.\n"));
_CHECK_CERT (GNUTLS_CERT_INSECURE_ALGORITHM, _("%s: The certificate of %s was signed using an insecure algorithm.\n"));