curl/lib/vtls
Jay Satiro 4f42150d04 sendf: change Curl_read_plain to wrap Curl_recv_plain (take 2)
Prior to this change Curl_read_plain would attempt to read the
socket directly. On Windows that's a problem because recv data may be
cached by libcurl and that data is only drained using Curl_recv_plain.

Rather than rewrite Curl_read_plain to handle cached recv data, I
changed it to wrap Curl_recv_plain, in much the same way that
Curl_write_plain already wraps Curl_send_plain.

Curl_read_plain -> Curl_recv_plain
Curl_write_plain -> Curl_send_plain

This fixes a bug in the schannel backend where decryption of arbitrary
TLS records fails because cached recv data is never drained. We send
data (TLS records formed by Schannel) using Curl_write_plain, which
calls Curl_send_plain, and that may do a recv-before-send
("pre-receive") to cache received data. The code calls Curl_read_plain
to read data (TLS records from the server), which prior to this change
did not call Curl_recv_plain and therefore cached recv data wasn't
retrieved, resulting in malformed TLS records and decryption failure
(SEC_E_DECRYPT_FAILURE).

The bug has only been observed during Schannel TLS 1.3 handshakes. Refer
to the issue and PR for more information.

--

This is take 2 of the original fix. It preserves the original behavior
of Curl_read_plain to write 0 to the bytes read parameter on error,
since apparently some callers expect that (SOCKS tests were hanging).
The original fix which landed in 12e1def5 and was later reverted in
18383fbf failed to work properly because it did not do that.

Also, it changes Curl_write_plain the same way to complement
Curl_read_plain, and it changes Curl_send_plain to return -1 instead of
0 on CURLE_AGAIN to complement Curl_recv_plain.

Behavior on error with these changes:

Curl_recv_plain returns -1 and *code receives error code.
Curl_send_plain returns -1 and *code receives error code.
Curl_read_plain returns error code and *n (bytes read) receives 0.
Curl_write_plain returns error code and *written receives 0.

--

Ref: https://github.com/curl/curl/issues/9431#issuecomment-1312420361

Assisted-by: Joel Depooter
Reported-by: Egor Pugin

Fixes https://github.com/curl/curl/issues/9431
Closes https://github.com/curl/curl/pull/9949
2022-11-20 03:54:36 -05:00
..
bearssl.c lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
bearssl.h
gskit.c lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
gskit.h
gtls.c lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
gtls.h
hostcheck.c
hostcheck.h
keylog.c
keylog.h
mbedtls_threadlock.c
mbedtls_threadlock.h
mbedtls.c lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
mbedtls.h
nss.c lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
nssg.h
openssl.c lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
openssl.h
rustls.c lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
rustls.h
schannel_verify.c lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
schannel.c sendf: change Curl_read_plain to wrap Curl_recv_plain (take 2) 2022-11-20 03:54:36 -05:00
schannel.h
sectransp.c lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
sectransp.h
vtls_int.h lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
vtls.c vtls: fix build without proxy support 2022-11-12 00:14:24 +01:00
vtls.h lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
wolfssl.c lib: connection filters (cfilter) addition to curl: 2022-11-11 15:17:51 +01:00
wolfssl.h
x509asn1.c
x509asn1.h