When sharing the x509 store in wolfSSL, always use an explicitly
constructed one, as the SSLCTX might have "only" an internal one which
is not obeying reference count lifetimes.
Fixes#14278
Reported-by: Alex Snast
Closes#14279
Adds a `bool eos` flag to send methods to indicate that the data is the
last chunk the invovled transfer wants to send to the server.
This will help protocol filters like HTTP/2 and 3 to forward the
stream's EOF flag and also allow to EAGAIN such calls when buffers are
not yet fully flushed.
Closes#14220
Fix the file of wolfssl.c because of this warning/error:
```
curl\lib\vtls\wolfssl.c(1017,42): error C2220: the following warning is treated as an error [curl\bld\lib\libcurl_object.vcxproj]
curl\lib\vtls\wolfssl.c(1017,42): warning C4267: 'function': conversion from 'size_t' to 'unsigned long', possible loss of data [curl\bld\lib\libcurl_object.vcxproj]
```
`size_t` in MSVC is different. Change it to `unsigned long` because
`wolfSSL_ERR_error_string_n` last argument is defined as
`unsigned long`.
Closes#14193
Fix `-Wpointer-bool-conversion` warnings with the method suggested by
both Apple clang and mainline llvm. This was already tried and dropped
in #1705 (in year 2017), but the issue reported there no longer
replicates.
Verified with Apple clang 14, llvm 15, llvm 18 and gcc 11, 14 that the
generated objects are bit by bit identical before and after this patch.
Also:
- stop silencing `-Wtautological-pointer-compare`. This warning don't
seem to be appearing anymore (with or without this patch), at least
with the tested compilers and SDKs (clang 13.1.6-16.0.0beta, llvm 15,
18, gcc 11, 14) and minimum macOS target of 10.8. Older targets fail
to build curl with SecureTransport.
- silence `-Wunreachable-code` for clang only. Previously I applied it
also to GCC, by mistake.
Ref: 8d7172d20a
Apple clang `-Wpointer-bool-conversion`:
```
curl/lib/vtls/sectransp.c:1103:6: error: address of function 'SSLCreateContext' will always evaluate to 'true' [-Werror,-Wpointer-bool-conversion]
if(SSLCreateContext) { /* use the newer API if available */
~~ ^~~~~~~~~~~~~~~~
curl/lib/vtls/sectransp.c:1103:6: note: prefix with the address-of operator to silence this warning
if(SSLCreateContext) { /* use the newer API if available */
^
&
```
Ref: https://github.com/curl/curl/actions/runs/9819538439/job/27113201384#step:8:382
llvm `-Wpointer-bool-conversion`:
```
curl/lib/vtls/sectransp.c:2663:8: error: address of function 'SSLCreateContext' will always evaluate to 'true' [-Werror,-Wpointer-bool-conversion]
if(SSLCreateContext)
~~ ^~~~~~~~~~~~~~~~
curl/lib/vtls/sectransp.c:2663:8: note: prefix with the address-of operator to silence this warning
if(SSLCreateContext)
^
&
```
Ref: https://github.com/curl/curl/actions/runs/9819538439/job/27113200291#step:8:417
gcc still needs `-Waddress` suppressed to avoid these:
```
curl/lib/vtls/n/sectransp.c: In function 'getsubject':
curl/lib/vtls/n/sectransp.c:379:6: warning: the address of 'SecCertificateCopyLongDescription' will always evaluate as 'true' [-Waddress]
379 | if(&SecCertificateCopyLongDescription)
| ^
[...]
```
Follow-up to 59cadacfcc#14128
Follow-up to af271ce9b9#1722
Follow-up to 2b7ce3f56d#1706
Cherry-picked from #14097Closes#14162
- cmake: enable Apple-specific `-Werror=partial-availability` to match
autotools.
- autotools: enable `-pedantic-errors` with llvm/clang to match gcc and
CMake.
- autotools: enable `-Werror-implicit-function-declaration` for
llvm/clang to match gcc.
- cmake: enable `-Werror-implicit-function-declaration` to match
autotools.
- move `-Wpointer-bool-conversion` from autotools to the local file
(`sectransp.c`) it was meant to apply. This way it applies to all
build methods.
- autotoos: show `CURL_CFLAG_EXTRAS` in the `./configure` summary.
(it may contain `-Werror` and/or `-pedentic-errors`.)
Cherry-picked from #14097Closes#14128
Currently we're using WOLFSSL_MAX_ERROR_SZ to define the error buffer
size, this value is user defined which means it can be overwritten with
-DWOLFSSL_MAX_ERROR_SZ=512 when building wolfssl and this overwrite is
not exported to the users of wolfssl.
Instead of relying on WOLFSSL_MAX_ERROR_SZ we'll just use a 256 bytes
error buffer and use wolfSSL_ERR_error_string_n to fill it thus dropping
the dependency on WOLFSSL_MAX_ERROR_SZ altogether.
Closes#14114
- deduplicate the code in many tls backends that check
for an existing id and delete it before adding the new one
- rename ssl_primary_config's `sessionid` bool to `cache_session`
Closes#14121
`HAVE_BUILTIN_AVAILABLE` is a curl macro set via autotools and cmake.
Like other `HAVE_`s it signals availability if defined.
SecureTransport code was specifically looking for the value 1, which
triggered compiler warnings when the feature was not present.
Replace the existing workaround of locally suppressing the compiler
warning with using `defined()`.
autotools:
```
767 | #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
| ^~~~~~~~~~~~~~~~~~~~~~
../../lib/vtls/sectransp.c: In function 'sectransp_connect_step1':
../../lib/vtls/sectransp.c:1140:52: error: "HAVE_BUILTIN_AVAILABLE" is not defined, evaluates to 0 [-Werror=undef]
1140 | #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
| ^~~~~~~~~~~~~~~~~~~~~~
../../lib/vtls/sectransp.c:1240:52: error: "HAVE_BUILTIN_AVAILABLE" is not defined, evaluates to 0 [-Werror=undef]
1240 | #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
| ^~~~~~~~~~~~~~~~~~~~~~
../../lib/vtls/sectransp.c: In function 'sectransp_connect_step2':
```
Ref: https://github.com/curl/curl/actions/runs/9815428701/job/27104448045#step:6:499
cmake gcc:
```
1140 | #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
| ^~~~~~~~~~~~~~~~~~~~~~
/Users/runner/work/curl/curl/lib/vtls/sectransp.c:1240:52: error: "HAVE_BUILTIN_AVAILABLE" is not defined, evaluates to 0 [-Werror=undef]
1240 | #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
| ^~~~~~~~~~~~~~~~~~~~~~
/Users/runner/work/curl/curl/lib/vtls/sectransp.c: In function 'sectransp_connect_step2':
/Users/runner/work/curl/curl/lib/vtls/sectransp.c:2231:51: error: "HAVE_BUILTIN_AVAILABLE" is not defined, evaluates to 0 [-Werror=undef]
2231 | #if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
| ^~~~~~~~~~~~~~~~~~~~~~
```
Ref: https://github.com/curl/curl/actions/runs/9815428701/job/27104445425#step:8:355
Cherry-picked from #14097Closes#14122
Based on the standards and guidelines we use for our documentation.
- expand contractions (they're => they are etc)
- host name = > hostname
- file name => filename
- user name = username
- man page => manpage
- run-time => runtime
- set-up => setup
- back-end => backend
- a HTTP => an HTTP
- Two spaces after a period => one space after period
Closes#14073
When libcurl discards a connection there are two phases this may go
through: "shutdown" and "closing". If a connection is aborted, the
shutdown phase is skipped and it is closed right away.
The connection filters attached to the connection implement the phases
in their `do_shutdown()` and `do_close()` callbacks. Filters carry now a
`shutdown` flags next to `connected` to keep track of the shutdown
operation.
Filters are shut down from top to bottom. If a filter is not connected,
its shutdown is skipped. Notable filters that *do* something during
shutdown are HTTP/2 and TLS. HTTP/2 sends the GOAWAY frame. TLS sends
its close notify and expects to receive a close notify from the server.
As sends and receives may EAGAIN on the network, a shutdown is often not
successful right away and needs to poll the connection's socket(s). To
facilitate this, such connections are placed on a new shutdown list
inside the connection cache.
Since managing this list requires the cooperation of a multi handle,
only the connection cache belonging to a multi handle is used. If a
connection was in another cache when being discarded, it is removed
there and added to the multi's cache. If no multi handle is available at
that time, the connection is shutdown and closed in a one-time,
best-effort attempt.
When a multi handle is destroyed, all connection still on the shutdown
list are discarded with a final shutdown attempt and close. In curl
debug builds, the environment variable `CURL_GRACEFUL_SHUTDOWN` can be
set to make this graceful with a timeout in milliseconds given by the
variable.
The shutdown list is limited to the max number of connections configured
for a multi cache. Set via CURLMOPT_MAX_TOTAL_CONNECTIONS. When the
limit is reached, the oldest connection on the shutdown list is
discarded.
- In multi_wait() and multi_waitfds(), collect all connection caches
involved (each transfer might carry its own) into a temporary list.
Let each connection cache on the list contribute sockets and
POLLIN/OUT events it's connections are waiting for.
- in multi_perform() collect the connection caches the same way and let
them peform their maintenance. This will make another non-blocking
attempt to shutdown all connections on its shutdown list.
- for event based multis (multi->socket_cb set), add the sockets and
their poll events via the callback. When `multi_socket()` is invoked
for a socket not known by an active transfer, forward this to the
multi's cache for processing. On closing a connection, remove its
socket(s) via the callback.
TLS connection filters MUST NOT send close nofity messages in their
`do_close()` implementation. The reason is that a TLS close notify
signals a success. When a connection is aborted and skips its shutdown
phase, the server needs to see a missing close notify to detect
something has gone wrong.
A graceful shutdown of FTP's data connection is performed implicitly
before regarding the upload/download as complete and continuing on the
control connection. For FTP without TLS, there is just the socket close
happening. But with TLS, the sent/received close notify signals that the
transfer is complete and healthy. Servers like `vsftpd` verify that and
reject uploads without a TLS close notify.
- added test_19_* for shutdown related tests
- test_19_01 and test_19_02 test for TCP RST packets
which happen without a graceful shutdown and should
no longer appear otherwise.
- add test_19_03 for handling shutdowns by the server
- add test_19_04 for handling shutdowns by curl
- add test_19_05 for event based shutdowny by server
- add test_30_06/07 and test_31_06/07 for shutdown checks
on FTP up- and downloads.
Closes#13976
When user sets CURLOPT_SSLCERT but leaves CURLOPT_SSLKEY unset assume
the path passed in CURLOPT_SSLCERT holds the ssl key which is what we do
in openssl implementation.
Fixes#14007Closes#14008
The function we use is called 'gnutls_x509_crt_check_hostname()' but if
we pass in the hostname with a trailing dot, the check fails. If we pass
in the SNI name, which cannot have a trailing dot, it succeeds for
https://pyropus.ca./
I consider this as a flaw in GnuTLS and have submitted this issue
upstream:
https://gitlab.com/gnutls/gnutls/-/issues/1548
In order to work with old and existing GnuTLS versions, we still need
this change no matter how they view the issue or might change it in the
future.
Fixes#13428
Reported-by: Ryan Carsten Schmidt
Closes#13949
- clarify Curl_xfer_setup() with RECV/SEND flags and different calls for
which socket they operate on. Add a shutdown flag for secondary
sockets
- change Curl_xfer_setup() calls to new functions
- implement non-blocking connection shutdown at the end of receiving or
sending a transfer
Closes#13913
This adds connection shutdown infrastructure and first use for FTP. FTP
data connections, when not encountering an error, are now shut down in a
blocking way with a 2sec timeout.
- add cfilter `Curl_cft_shutdown` callback
- keep a shutdown start timestamp and timeout at connectdata
- provide shutdown timeout default and member in
`data->set.shutdowntimeout`.
- provide methods for starting, interrogating and clearing
shutdown timers
- provide `Curl_conn_shutdown_blocking()` to shutdown the
`sockindex` filter chain in a blocking way. Use that in FTP.
- add `Curl_conn_cf_poll()` to wait for socket events during
shutdown of a connection filter chain.
This gets the monitoring sockets and events via the filters
"adjust_pollset()" methods. This gives correct behaviour when
shutting down a TLS connection through a HTTP/2 proxy.
- Implement shutdown for all socket filters
- for HTTP/2 and h2 proxying to send GOAWAY
- for TLS backends to the best of their capabilities
- for tcp socket filter to make a final, nonblocking
receive to avoid unwanted RST states
- add shutdown forwarding to happy eyeballers and
https connect ballers when applicable.
Closes#13904
- decouple need to recv/send from negotiation state, we need
this later in shutdown handling as well
- move ssl enums from urldata.h to vtls_int.h
- implement use of `connssl->io_need` in vtls.c. and all backends
Closes#13879
Add new job to test building for UWP (aka `CURL_WINDOWS_APP`).
Fix fallouts when building for UWP:
- rand: do not use `BCryptGenRandom()`.
- cmake: disable using win32 LDAP.
- cmake: disable telnet.
- version_win32: fix code before declaration.
- schannel: disable `HAS_MANUAL_VERIFY_API`.
- schannel: disable `SSLSUPP_PINNEDPUBKEY`
and make `schannel_checksum()` a stub.
Ref: e178fbd40a#1429
- schannel: make `cert_get_name_string()` a failing stub.
- system_win32: make `Curl_win32_impersonating()` a failing stub.
- system_win32: try to fix `Curl_win32_init()` (untested).
- threads: fix to use `CreateThread()`.
- src: disable searching `PATH` for the CA bundle.
- src: disable bold text support and capability detection.
- src: disable `getfiletime()`/`setfiletime()`.
- tests: make `win32_load_system_library()` a failing stub.
- tests/server/util: make it compile.
- tests/server/sockfilt: make it compile.
- tests/lib3026: fix to use `CreateThread()`.
See individual commits for build error details.
Some of these fixes may have better solutions, and some may not work
as expected. The goal of this patch is to make curl build for UWP.
Closes#13870
- add special sauce to disable unwanted peer verification by mbedtls
when negotiating TLS v1.3
- add special sauce for MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET
return code on *writing* TLS data. We assume the data had not been
written and EAGAIN.
- return correct Curl error code when peer verification failed.
- disable test_08_05 with 50 HTTP/1.1 connections, as mbedtls reports a
memory allocation failed during handshake.
- bump CI mbedtls version to 3.6.0
Fixes#13653Closes#13838
- similar to openssl, use a shared 'credentials' instance
among TLS connections with a plain configuration.
- different to openssl, a connection with a client certificate
is not eligible to sharing.
- document CURLOPT_CA_CACHE_TIMEOUT in man page
Closes#13795
Previously a large table of ciphers was used to determine the default
ciphers and to lookup manually selected ciphers names.
With the lookup of the manually selected cipher names moved to
Curl_cipher_suite_walk_str() the large table is no longer needed for
that purpose.
The list of manually selected cipher can now be intersected with the
ciphers supported by Secure Transport (SSLGetSupportedCiphers()),
instead of using the fixed table for that.
The other use of the table was to filter the list of all supported
ciphers offered by Secure Transport to create a list of ciphers to
use by default, excluding ciphers in the table marked as weak.
Instead of using a complement based approach (exclude weak), switch
to using an intersection with a smaller list of ciphers deemed
appropriate.
Closes#13823
The versions check wrongly complained and return error if the *minimum*
version was set to something less than 1.3. QUIC is always TLS 1.3, but
that means minimum 1.2 is still fine to ask for.
This also renames the local variable to make the mistake harder to make
in the future.
Regression shipped in 8.8.0
Follow-up to 3210101088
Reported-by: fds242 on github
Fixes#13799Closes#13802
local ftp upload tests sometimes failed with an invalid TLS record being
reported by gnutls. vsftp did log that the shutdown was not regarded as
clean, failing the control connection thereafter.
These changes make test_31_05 work reliable locally.
- on closing the SSL filter, shutdown READ *and* WRITE
- on closing, try a receive after shutdown is sent
- convert to DEBUGF to CURL_TRC_CF
Closes#13790
- add `Curl_hash_add2()` that passes a destructor function for
the element added. Call element destructor instead of hash
destructor if present.
- multi: add `proto_hash` for protocol related information,
remove `struct multi_ssl_backend_data`.
- openssl: use multi->proto_hash to keep x509 shared store
- schannel: use multi->proto_hash to keep x509 shared store
- vtls: remove Curl_free_multi_ssl_backend_data() and its
equivalents in the TLS backends
Closes#13345
- Don't call the keylog function if it has already logged the key.
For old OpenSSL versions and its forks that do not have support for
OpenSSL's keylog callback, libcurl has its own legacy key logging
function that logs the TLS 1.2 (and earlier) key (client random + master
key) on a single line.
Prior to this change, since e7de80e8 (precedes 8.8.0), the legacy key
logging function could write the same key line more than once (usually
twice) due to some incorrect logic.
Closes https://github.com/curl/curl/pull/13683
- send the TLS close notify message when cloding down
the mbedtls connection filter
- this is a "least" effort version and, as other TLS filters,
is lacking a graceful send/receive/timeout for a really
clean shutdown.
Closes#13745
- Revert to the legacy TLS 1.2 key logging code for LibreSSL.
- Document SSLKEYLOGFILE for LibreSSL is TLS 1.2 max.
Prior to this change if the user specified a filename in the
SSLKEYLOGFILE environment variable and was using LibreSSL 3.5.0+ then
an empty file would be created and no keys would be logged.
This is effectively a revert of e43474b4 which changed openssl.c to use
SSL_CTX_set_keylog_callback for LibreSSL 3.5.0+. Unfortunately LibreSSL
added that function only as a stub that doesn't actually do anything.
Reported-by: Gonçalo Carvalho
Fixes https://github.com/curl/curl/issues/13672
Closes https://github.com/curl/curl/pull/13682
- rustls report it has finished the TLS handshake *before*
all relevant data has been sent off, e.g. it FINISHED message
- On connections the send data immediately, this was never noticed
as the FINISHED in rustls buffers was send with the app data
- On passive FTP connections, curl does not send any data after
the handshake, leaving FINISHED unsent and the server never
responded as it was waiting on this.
Closes#13686