From 54c06a9cd7bcf8f245cf5f9da760f91939259f69 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Sun, 16 Feb 2025 09:02:46 +0900 Subject: [PATCH 1/3] serv: fix detection of early data reception Upon success, gnutls_record_recv_early_data returns the amount of data received, so the application should treat positive numbers as an indication of early data reception. Signed-off-by: Daiki Ueno --- src/serv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/serv.c b/src/serv.c index 17db12c5ca..86008c9523 100644 --- a/src/serv.c +++ b/src/serv.c @@ -1690,7 +1690,7 @@ static void tcp_server(const char *name, int port, int timeout) GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { j->earlydata_eof = 1; } - if (r == 0) { + if (r >= 0) { earlydata_read = 1; } } -- 2.49.0 From 8c488288ea05a759977dccd4ee4d61610da4dc38 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Mon, 17 Mar 2025 09:00:44 +0900 Subject: [PATCH 2/3] cli: send early data only after session data is set Now that max_early_data_size is recorded as part of the stored resumption data, this needs to be read before attempting to send early data. Signed-off-by: Daiki Ueno --- src/socket.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/socket.c b/src/socket.c index 48784b67fa..f32910c239 100644 --- a/src/socket.c +++ b/src/socket.c @@ -580,6 +580,11 @@ void socket_open_int(socket_st *hd, const char *hostname, const char *service, } if (hd->session) { + if (hd->rdata.data) { + gnutls_session_set_data(hd->session, + hd->rdata.data, + hd->rdata.size); + } if (hd->edata.data) { ret = gnutls_record_send_early_data( hd->session, hd->edata.data, @@ -591,11 +596,6 @@ void socket_open_int(socket_st *hd, const char *hostname, const char *service, exit(1); } } - if (hd->rdata.data) { - gnutls_session_set_data(hd->session, - hd->rdata.data, - hd->rdata.size); - } if (client_trace || server_trace) { hd->server_trace = server_trace; -- 2.49.0 From 56fa5e1901fe40a97553cf3141a4d205c4286702 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Sun, 16 Feb 2025 09:04:50 +0900 Subject: [PATCH 3/3] tests: add basic tests for 0-RTT with gnutls-serv and gnutls-cli Signed-off-by: Daiki Ueno --- tests/Makefile.am | 2 +- tests/gnutls-cli-earlydata.sh | 84 +++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100755 tests/gnutls-cli-earlydata.sh diff --git a/tests/Makefile.am b/tests/Makefile.am index ec8fd982c5..72926e9da4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -546,7 +546,7 @@ dist_check_SCRIPTS += fastopen.sh pkgconfig.sh starttls.sh starttls-ftp.sh start sni-resume.sh ocsp-tests/ocsptool.sh cert-reencoding.sh pkcs7-cat.sh long-crl.sh \ serv-udp.sh logfile-option.sh gnutls-cli-resume.sh profile-tests.sh \ server-weak-keys.sh ocsp-tests/ocsp-signer-verify.sh cfg-test.sh \ - sanity-lib.sh + sanity-lib.sh gnutls-cli-earlydata.sh if !DISABLE_SYSTEM_CONFIG dist_check_SCRIPTS += system-override-sig.sh system-override-hash.sh \ diff --git a/tests/gnutls-cli-earlydata.sh b/tests/gnutls-cli-earlydata.sh new file mode 100755 index 0000000000..72763f029f --- /dev/null +++ b/tests/gnutls-cli-earlydata.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +# Copyright (C) 2025 Red Hat, Inc. +# +# Author: Daiki Ueno +# +# This file is part of GnuTLS. +# +# GnuTLS is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# GnuTLS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see +# + +: ${srcdir=.} +: ${SERV=../src/gnutls-serv${EXEEXT}} +: ${CLI=../src/gnutls-cli${EXEEXT}} +unset RETCODE + +if ! test -x "$SERV"; then + exit 77 +fi + +if ! test -x "$CLI"; then + exit 77 +fi + +if test "$WINDIR" != ""; then + exit 77 +fi + +if test -n "$VALGRIND"; then + VALGRIND="${LIBTOOL:-libtool} --mode=execute $VALGRIND --error-exitcode=1" +fi + +SERV="$SERV -q" + +. "$srcdir/scripts/common.sh" + +: ${ac_cv_sizeof_time_t=8} +if test "$ac_cv_sizeof_time_t" -ge 8; then + ATTIME_VALID="2038-10-12" # almost the pregenerated cert expiration +else + ATTIME_VALID="2030-12-17" # end of epoch − 2590 days of validity +fi + +testdir=`create_testdir earlydata` +KEY="$srcdir/../doc/credentials/x509/key-ecc.pem" +CERT="$srcdir/../doc/credentials/x509/cert-ecc.pem" +CACERT="$srcdir/../doc/credentials/x509/ca.pem" + +eval "$GETPORT" +launch_server --echo --x509keyfile "$KEY" --x509certfile "$CERT" --disable-client-cert --earlydata --maxearlydata 1000 +PID=$! +wait_server "$PID" + +echo "This is a test message" > "$testdir/earlydata.txt" + +$VALGRIND "$CLI" --attime="$ATTIME_VALID" -p "$PORT" localhost --logfile="$testdir/cli.log" --priority="NORMAL:-VERS-ALL:+VERS-TLS1.3" --x509cafile "$CACERT" --resume --waitresumption --earlydata="$testdir/earlydata.txt" "$testdir/cli.out" +if test $? -ne 0; then + cat "$testdir/cli.log" + fail "$PID" "failed to communicate with the server" +fi + +if ! grep "This is a resumed session" "$testdir/cli.log" > /dev/null; then + fail "$PID" "session is not resumed" +fi + +if ! cmp "$testdir/earlydata.txt" "$testdir/cli.out" > /dev/null; then + fail "$PID" "early data has not been sent back" +fi + +kill "$PID" +wait + +exit 0 -- 2.49.0