mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
quic_record_append: return correct code
0-return from quic_record_append is an error. `quic_record_complete(qr) || len == 0` is not an error condition. We should return as normal on success. The issue is that passing in buffers with length 1 then 3 causes `qr_length` (in `quic_record_make`) to return 0. Then when `quic_record_append` gets called the `len` gets consumed by the first `if` and `len == 0` is true. This causes the error return which is not correct behaviour. Reported in https://github.com/wolfSSL/wolfssl/issues/8156. Reproducing is a bit tricky. I couldn't get the docker to work. First setup ngtcp2 as described in https://github.com/ngtcp2/ngtcp2/pkgs/container/ngtcp2-interop. The Relevant steps are (I tested with master/main branches of all libs): ``` $ git clone --depth 1 -b v5.7.4-stable https://github.com/wolfSSL/wolfssl $ cd wolfssl $ autoreconf -i $ # For wolfSSL < v5.6.6, append --enable-quic. $ ./configure --prefix=$PWD/build \ --enable-all --enable-aesni --enable-harden --enable-keylog-export \ --disable-ech $ make -j$(nproc) $ make install $ cd .. $ git clone --recursive https://github.com/ngtcp2/nghttp3 $ cd nghttp3 $ autoreconf -i $ ./configure --prefix=$PWD/build --enable-lib-only $ make -j$(nproc) check $ make install $ cd .. $ git clone --recursive https://github.com/ngtcp2/ngtcp2 $ cd ngtcp2 $ autoreconf -i $ # For Mac users who have installed libev with MacPorts, append $ # LIBEV_CFLAGS="-I/opt/local/include" LIBEV_LIBS="-L/opt/local/lib -lev" $ ./configure PKG_CONFIG_PATH=$PWD/../wolfssl/build/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig \ --with-wolfssl $ make -j$(nproc) check ``` Download and unzip https://github.com/user-attachments/files/17621329/failing.pcap.zip From the ngtcp2 dir: ``` ./examples/wsslserver 127.0.0.1 44433 /path/to/wolfssl/certs/server-key.pem /path/to/wolfssl/certs/server-cert.pem ``` Then run the following python script (`failing.pcap` has to be available in the running dir) (probably needs to be run as `sudo`): ``` from scapy.utils import rdpcap, PcapNgReader from scapy.all import * reader = PcapNgReader("failing.pcap") for i in reader: p = i[IP] p.dport = 44433 p.dst = "127.0.0.1" p[UDP].chksum=0 p.display() send(p) ``` Then observe the log line: ``` I00000000 0xa48accb7b49ec1556ac7111c64d3a4572a81 frm tx 625216795 Initial CONNECTION_CLOSE(0x1c) error_code=CRYPTO_ERROR(0x100) frame_type=0 reason_len=0 reason=[] ``` You can also use `gdb` and place a break inside the following section in `wolfssl/src/quic.c`. ``` if (quic_record_complete(qr) || len == 0) { return 0; } ```
This commit is contained in:
18
src/quic.c
18
src/quic.c
@ -154,18 +154,16 @@ static int quic_record_append(WOLFSSL *ssl, QuicRecord *qr, const uint8_t *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quic_record_complete(qr) || len == 0) {
|
if (!quic_record_complete(qr) && len != 0) {
|
||||||
return 0;
|
missing = qr->len - qr->end;
|
||||||
|
if (len > missing) {
|
||||||
|
len = missing;
|
||||||
|
}
|
||||||
|
XMEMCPY(qr->data + qr->end, data, len);
|
||||||
|
qr->end += (word32)len;
|
||||||
|
consumed += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
missing = qr->len - qr->end;
|
|
||||||
if (len > missing) {
|
|
||||||
len = missing;
|
|
||||||
}
|
|
||||||
XMEMCPY(qr->data + qr->end, data, len);
|
|
||||||
qr->end += (word32)len;
|
|
||||||
consumed += len;
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
*pconsumed = (ret == WOLFSSL_SUCCESS) ? consumed : 0;
|
*pconsumed = (ret == WOLFSSL_SUCCESS) ? consumed : 0;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -287,7 +287,10 @@ static int test_provide_quic_data(void) {
|
|||||||
*/
|
*/
|
||||||
AssertNotNull(ssl = wolfSSL_new(ctx));
|
AssertNotNull(ssl = wolfSSL_new(ctx));
|
||||||
len = fake_record(1, 100, lbuffer);
|
len = fake_record(1, 100, lbuffer);
|
||||||
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer, len, 0));
|
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer, 1, 0));
|
||||||
|
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer+1, 3, 0));
|
||||||
|
AssertTrue(provide_data(ssl, wolfssl_encryption_initial, lbuffer+4, len, 0)
|
||||||
|
);
|
||||||
len = fake_record(2, 1523, lbuffer);
|
len = fake_record(2, 1523, lbuffer);
|
||||||
AssertTrue(provide_data(ssl, wolfssl_encryption_handshake, lbuffer, len, 0));
|
AssertTrue(provide_data(ssl, wolfssl_encryption_handshake, lbuffer, len, 0));
|
||||||
len = fake_record(2, 1, lbuffer);
|
len = fake_record(2, 1, lbuffer);
|
||||||
|
Reference in New Issue
Block a user