diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-03-05 10:08:23 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-03-05 10:08:23 +0900 |
commit | c0c4ebc8462f91e7cf41e7404f71dca434b8494e (patch) | |
tree | 764f42c7258a7f83c64a1e75669b5694072cee20 /src/gnutls.c | |
parent | dfd19f19c019e044f97e46081a6960614c0cf3f9 (diff) | |
download | wget-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.c | 126 |
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")); |