openssl addresses failed with "nonblocking operation did not complete" when the peer performed a renegotiation

This commit is contained in:
Gerhard Rieger 2012-07-22 08:29:33 +02:00
parent 86ebee79fa
commit 4b25958cb0
3 changed files with 90 additions and 3 deletions

View file

@ -4,6 +4,10 @@ corrections:
device /dev/ptmx instead of the pty (thanks to Matthew Cloke for
pointing me to this bug)
socats openssl addresses failed with "nonblocking operation did not
complete" when the peer performed a renegotiation. Thanks to Benjamin
Delpy for reporting this bug.
corrected the "fixed possible SIGSEGV" fix because SIGSEGV still might
occur under those conditions. Thanks to Toni Mattila for first
reporting this problem.

82
test.sh
View file

@ -10247,6 +10247,88 @@ PORT=$((PORT+1))
N=$((N+1))
# socat up to 1.7.1.1 (and 2.0.0-b3) terminated with error when an openssl peer
# performed a renegotiation. Test if this is fixed.
NAME=OPENSSLRENEG1
case "$TESTS" in
*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%$NAME%*)
TEST="$NAME: OpenSSL connections survives renogotiation"
# connect with s_client to socat ssl-l; force a renog, then transfer data. When
# data is passed the test succeeded
if ! eval $NUMCOND; then :; else
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
tdiff="$td/test$N.diff"
da="test$N $(date) $RANDOM"
CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
CMD1="openssl s_client -port $PORT -verify 0"
printf "test $F_n $TEST... " $N
$CMD0 >/dev/null 2>"${te}0" &
pid0=$!
waittcp4port $PORT 1
(echo "R"; sleep 1; echo "$da"; sleep 1) |$CMD1 2>"${te}1" |fgrep "$da" >"${tf}1"
rc1=$?
kill $pid0 2>/dev/null; wait
if echo "$da" |diff - ${tf}1 >"$tdiff"; then
$PRINTF "$OK\n"
numOK=$((numOK+1))
else
$PRINTF "$FAILED\n"
echo "$CMD0 &"
echo "$CMD1"
cat "${te}0"
# cat "${te}1"
cat "$tdiff"
numFAIL=$((numFAIL+1))
fi
fi # NUMCOND
;;
esac
N=$((N+1))
# socat up to 1.7.1.1 (and 2.0.0-b3) terminated with error when an openssl peer
# performed a renegotiation. The first temporary fix to this problem might
# leave socat in a blocking ssl-read state. Test if this has been fixed.
NAME=OPENSSLRENEG2
case "$TESTS" in
*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%$NAME%*)
TEST="$NAME: OpenSSL connections do not block after renogotiation"
# connect with s_client to socat ssl-l; force a renog, then transfer data from
# socat to the peer. When data is passed this means that the former ssl read no
# longer blocks and the test succeeds
if ! eval $NUMCOND; then :; else
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
tdiff="$td/test$N.diff"
da="test$N $(date) $RANDOM"
CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,reuseaddr,cert=testsrv.crt,key=testsrv.key,verify=0 SYSTEM:\"sleep 1; echo \\\\\\\"\\\"$da\\\"\\\\\\\"; sleep 1\"!!STDIO"
CMD1="openssl s_client -port $PORT -verify 0"
printf "test $F_n $TEST... " $N
eval "$CMD0 >/dev/null 2>\"${te}0\" &"
pid0=$!
waittcp4port $PORT 1
(echo "R"; sleep 2) |$CMD1 2>"${te}1" |fgrep "$da" >"${tf}1"
rc1=$?
kill $pid0 2>/dev/null; wait
if echo "$da" |diff - ${tf}1 >"$tdiff"; then
$PRINTF "$OK\n"
numOK=$((numOK+1))
else
$PRINTF "$FAILED\n"
echo "$CMD0 &"
echo "$CMD1"
cat "${te}0"
# cat "${te}1"
cat "$tdiff"
numFAIL=$((numFAIL+1))
fi
fi # NUMCOND
;;
esac
N=$((N+1))
while read KEYW PF LO
do
if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi

View file

@ -1,5 +1,5 @@
/* source: xio-openssl.c */
/* Copyright Gerhard Rieger 2002-2008 */
/* Copyright Gerhard Rieger 2002-2012 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the implementation of the openssl addresses */
@ -1208,8 +1208,9 @@ ssize_t xioread_openssl(struct single *pipe, void *buff, size_t bufsiz) {
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_CONNECT:
case SSL_ERROR_WANT_X509_LOOKUP:
Error("nonblocking operation did not complete");
break; /*!*/
Info("nonblocking operation did not complete");
errno = EAGAIN;
return -1;
case SSL_ERROR_SYSCALL:
if (ERR_peek_error() == 0) {
if (ret == 0) {