diff options
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | lib/Makefile.am | 2 | ||||
-rw-r--r-- | lib/gnutls.pc.in | 2 | ||||
-rw-r--r-- | lib/priority.c | 35 | ||||
-rw-r--r-- | src/udp-serv.c | 17 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rwxr-xr-x | tests/serv-udp.sh | 71 | ||||
-rw-r--r-- | tests/suite/Makefile.am | 3 | ||||
-rwxr-xr-x | tests/suite/multi-ticket-reception.sh | 99 |
10 files changed, 212 insertions, 27 deletions
diff --git a/.travis.yml b/.travis.yml index 017a3788fe..466146c396 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,6 @@ notifications: before_install: - - git submodule update --init - if [[ "$TRAVIS_OS_NAME" = "osx" ]]; then brew update; for pkg in autoconf automake autogen libtool nettle p11-kit libtasn1 gettext;do diff --git a/configure.ac b/configure.ac index c21660c3f3..8cc4c26d60 100644 --- a/configure.ac +++ b/configure.ac @@ -207,6 +207,12 @@ dnl Need netinet/tcp.h for TCP_FASTOPEN AC_CHECK_HEADERS([netinet/tcp.h]) AC_CHECK_HEADERS([stdatomic.h]) +dnl This ensures that we link with the right library for atomic operations on Linux SPARC +AC_SEARCH_LIBS([__atomic_load_4], [atomic], [], [AC_MSG_NOTICE([Could not detect libatomic])]) +AS_IF([test "$ac_cv_search___atomic_load_4" = "none required" || test "$ac_cv_search___atomic_load_4" = "no"], + [AC_SUBST([LIBATOMIC_LIBS], [])], + [AC_SUBST([LIBATOMIC_LIBS], [$ac_cv_search___atomic_load_4])]) + dnl We use its presence to detect C11 threads AC_CHECK_HEADERS([threads.h]) diff --git a/lib/Makefile.am b/lib/Makefile.am index 5c0eac680c..9f140469da 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -149,7 +149,7 @@ thirdparty_libadd += $(LIBIDN2_LIBS) endif if HAVE_LIBUNISTRING -thirdparty_libadd += $(LTLIBUNISTRING) +thirdparty_libadd += $(LIBUNISTRING) else libgnutls_la_LIBADD += unistring/libunistring.la endif diff --git a/lib/gnutls.pc.in b/lib/gnutls.pc.in index 9f26852ccd..68be2d1101 100644 --- a/lib/gnutls.pc.in +++ b/lib/gnutls.pc.in @@ -19,6 +19,6 @@ Description: Transport Security Layer implementation for the GNU system URL: http://www.gnutls.org/ Version: @VERSION@ Libs: -L${libdir} -lgnutls -Libs.private: @LIBINTL@ @LIBSOCKET@ @LIBNSL@ @LIBPTHREAD@ @LIB_SELECT@ @TSS_LIBS@ @GMP_LIBS@ @LIBUNISTRING@ @LIBIDN2_LIBS@ +Libs.private: @LIBINTL@ @LIBSOCKET@ @LIBNSL@ @LIBPTHREAD@ @LIB_SELECT@ @TSS_LIBS@ @GMP_LIBS@ @LIBUNISTRING@ @LIBIDN2_LIBS@ @LIBATOMIC_LIBS@ @GNUTLS_REQUIRES_PRIVATE@ Cflags: -I${includedir} diff --git a/lib/priority.c b/lib/priority.c index a8223a5308..2699901d26 100644 --- a/lib/priority.c +++ b/lib/priority.c @@ -1204,15 +1204,6 @@ static void add_dh(gnutls_priority_t priority_cache) } } -#define REMOVE_TLS13_IN_LOOP(vers, i) \ - if (vers->tls13_sem) { \ - for (j=i+1;j<priority_cache->protocol.num_priorities;j++) \ - priority_cache->protocol.priorities[j-1] = priority_cache->protocol.priorities[j]; \ - priority_cache->protocol.num_priorities--; \ - i--; \ - continue; \ - } - static int set_ciphersuite_list(gnutls_priority_t priority_cache) { unsigned i, j, z; @@ -1255,17 +1246,22 @@ static int set_ciphersuite_list(gnutls_priority_t priority_cache) } } + /* if we have NULL ciphersuites, SRP, or RSA-PSK enabled remove TLS1.3+ + * protocol versions; they cannot be negotiated under TLS1.3. */ + if (have_null || have_srp || have_rsa_psk) { + for (i = j = 0; i < priority_cache->protocol.num_priorities; i++) { + vers = version_to_entry(priority_cache->protocol.priorities[i]); + if (!vers || !vers->tls13_sem) + priority_cache->protocol.priorities[j++] = priority_cache->protocol.priorities[i]; + } + priority_cache->protocol.num_priorities = j; + } + for (i = 0; i < priority_cache->protocol.num_priorities; i++) { vers = version_to_entry(priority_cache->protocol.priorities[i]); if (!vers) continue; - /* if we have NULL ciphersuites, SRP, or RSA-PSK enabled remove TLS1.3+ - * protocol versions; they cannot be negotiated under TLS1.3. */ - if (have_null || have_srp || have_rsa_psk) { - REMOVE_TLS13_IN_LOOP(vers, i); - } - if (vers->transport == GNUTLS_STREAM) { /* TLS */ tls_sig_sem |= vers->tls_sig_sem; if (vers->tls13_sem) @@ -1413,13 +1409,12 @@ static int set_ciphersuite_list(gnutls_priority_t priority_cache) * do not support TLS1.3 will negotiate TLS1.2 if seen a TLS1.3 handshake */ if (unlikely((!have_psk && tlsmax && tlsmax->id >= GNUTLS_TLS1_3 && priority_cache->groups.size == 0)) || (!have_tls12 && have_pre_tls12 && have_tls13)) { - for (i = 0; i < priority_cache->protocol.num_priorities; i++) { + for (i = j = 0; i < priority_cache->protocol.num_priorities; i++) { vers = version_to_entry(priority_cache->protocol.priorities[i]); - if (!vers || vers->transport != GNUTLS_STREAM) - continue; - - REMOVE_TLS13_IN_LOOP(vers, i); + if (!vers || vers->transport != GNUTLS_STREAM || !vers->tls13_sem) + priority_cache->protocol.priorities[j++] = priority_cache->protocol.priorities[i]; } + priority_cache->protocol.num_priorities = j; } return 0; diff --git a/src/udp-serv.c b/src/udp-serv.c index fdaa0fb886..2d82482876 100644 --- a/src/udp-serv.c +++ b/src/udp-serv.c @@ -56,6 +56,15 @@ static ssize_t pull_func(gnutls_transport_ptr_t p, void *data, #define MAX_BUFFER 255 /* Longest string to echo */ +/* record layer indication for a handshake packet */ +#define HANDSHAKE_CONTENT_TYPE 22 +/* TLS record content is the first by of the packet */ +#define RECORD_CONTENT_POS 0 +/* handshake type is first byte in Handshake packet; + * we have to skip type;version;epoch;sequence_number; + * and length in DTLSPlaintext */ +#define HANDSHAKE_TYPE_POS 13 + void udp_server(const char *name, int port, int mtu) { int sock, ret; @@ -91,7 +100,11 @@ void udp_server(const char *name, int port, int mtu) recvfrom(sock, buffer, sizeof(buffer)-1, MSG_PEEK, (struct sockaddr *) &cli_addr, &cli_addr_size); - if (ret > 0) { + + /* only accept a valid client hello */ + if (ret > HANDSHAKE_TYPE_POS && + buffer[RECORD_CONTENT_POS] == HANDSHAKE_CONTENT_TYPE && + buffer[HANDSHAKE_TYPE_POS] == GNUTLS_HANDSHAKE_CLIENT_HELLO) { if (!HAVE_OPT(NOCOOKIE)) { memset(&prestate, 0, sizeof(prestate)); ret = @@ -222,8 +235,8 @@ void udp_server(const char *name, int port, int mtu) } } } + gnutls_deinit(session); } - gnutls_deinit(session); } /* Wait for data to be received within a timeout period in milliseconds diff --git a/tests/Makefile.am b/tests/Makefile.am index ce9264fe60..148f09fa4e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -460,7 +460,8 @@ dist_check_SCRIPTS += fastopen.sh pkgconfig.sh starttls.sh starttls-ftp.sh start ocsp-tests/ocsp-tls-connection ocsp-tests/ocsp-must-staple-connection \ ocsp-tests/ocsp-test cipher-listings.sh sni-hostname.sh server-multi-keys.sh \ psktool.sh ocsp-tests/ocsp-load-chain gnutls-cli-save-data.sh gnutls-cli-debug.sh \ - sni-resume.sh ocsp-tests/ocsptool cert-reencoding.sh pkcs7-cat.sh long-crl.sh + sni-resume.sh ocsp-tests/ocsptool cert-reencoding.sh pkcs7-cat.sh long-crl.sh \ + serv-udp.sh dist_check_SCRIPTS += gnutls-cli-self-signed.sh gnutls-cli-invalid-crl.sh diff --git a/tests/serv-udp.sh b/tests/serv-udp.sh new file mode 100755 index 0000000000..9db3a32a42 --- /dev/null +++ b/tests/serv-udp.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +# Copyright (C) 2010-2016 Free Software Foundation, Inc. +# +# Author: Nikos Mavrogiannopoulos +# +# 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 General Public License +# along with GnuTLS; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +srcdir="${srcdir:-.}" +SERV="${SERV:-../src/gnutls-serv${EXEEXT}}" +CLI="${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 -z "${VALGRIND}"; then + VALGRIND="${LIBTOOL:-libtool} --mode=execute ${VALGRIND} --error-exitcode=15" +fi + + +SERV="${SERV} -q" + +. "${srcdir}/scripts/common.sh" + +echo "Checking whether UDP server works" + +KEY1=${srcdir}/../doc/credentials/x509/key-rsa.pem +CERT1=${srcdir}/../doc/credentials/x509/cert-rsa.pem + +eval "${GETPORT}" +launch_server $$ --x509keyfile ${KEY1} --x509certfile ${CERT1} --udp -d 2 +PID=$! + +wait_udp_server $PID + +${VALGRIND} "${CLI}" -p "${PORT}" 127.0.0.1 --insecure --udp </dev/null >/dev/null || \ + fail ${PID} "1. handshake should have succeeded!" + +#retry +${VALGRIND} "${CLI}" -p "${PORT}" 127.0.0.1 --insecure --udp </dev/null >/dev/null || \ + fail ${PID} "2. handshake should have succeeded!" + + +kill ${PID} +wait + +exit 0 diff --git a/tests/suite/Makefile.am b/tests/suite/Makefile.am index f6e413ee56..8dccbc5726 100644 --- a/tests/suite/Makefile.am +++ b/tests/suite/Makefile.am @@ -92,7 +92,8 @@ scripts_to_test = chain.sh \ testrng.sh testcompat-polarssl.sh testcompat-openssl.sh \ testrandom.sh tls-fuzzer/tls-fuzzer-nocert.sh \ tls-fuzzer/tls-fuzzer-cert.sh tls-fuzzer/tls-fuzzer-alpn.sh \ - tls-fuzzer/tls-fuzzer-nocert-tls13.sh tls-fuzzer/tls-fuzzer-psk.sh + tls-fuzzer/tls-fuzzer-nocert-tls13.sh tls-fuzzer/tls-fuzzer-psk.sh \ + multi-ticket-reception.sh TESTS_ENVIRONMENT = EXEEXT=$(EXEEXT) \ LC_ALL="C" \ diff --git a/tests/suite/multi-ticket-reception.sh b/tests/suite/multi-ticket-reception.sh new file mode 100755 index 0000000000..63de24e904 --- /dev/null +++ b/tests/suite/multi-ticket-reception.sh @@ -0,0 +1,99 @@ +#!/bin/sh + +# Copyright (C) 2019 Red Hat, Inc. +# +# Author: Nikos Mavrogiannopoulos +# +# 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 General Public License +# along with GnuTLS; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +srcdir="${srcdir:-.}" +TLSPY_SERV="${srcdir}/tls-fuzzer/tlslite-ng/scripts/tls.py" +PYPATH="${srcdir}/tls-fuzzer/tlsfuzzer/" +CLI="${CLI:-../../src/gnutls-cli${EXEEXT}}" +unset RETCODE + +if ! test -x "${TLSPY_SERV}"; then + exit 77 +fi + +if ! test -x "${CLI}"; then + exit 77 +fi + +if test "${WINDIR}" != ""; then + exit 77 +fi + +if ! test -z "${VALGRIND}"; then + VALGRIND="${LIBTOOL:-libtool} --mode=execute ${VALGRIND} --error-exitcode=15" +fi + +. "${srcdir}/../scripts/common.sh" + +KEY1=${srcdir}/tls-fuzzer/tlslite-ng/tests/serverX509Key.pem +CERT1=${srcdir}/tls-fuzzer/tlsfuzzer/tests/serverX509Cert.pem + +#create links necessary for tlslite to function +pushd "${srcdir}/tls-fuzzer/tlsfuzzer" +test -L ecdsa || ln -s ../python-ecdsa/src/ecdsa ecdsa +test -L tlslite || ln -s ../tlslite-ng/tlslite tlslite 2>/dev/null +popd + +echo "Checking whether receiving 1 ticket succeeds (sanity)" + +eval "${GETPORT}" +PYTHONPATH="${PYPATH}" ${TLSPY_SERV} server --tickets 1 -k ${KEY1} -c ${CERT1} 127.0.0.1:${PORT} & +PID=$! +wait_server ${PID} + +${VALGRIND} "${CLI}" -p "${PORT}" 127.0.0.1 --priority NORMAL:-VERS-ALL:+VERS-TLS1.3 --insecure </dev/null || \ + fail ${PID} "1. handshake should have succeeded!" + + +kill ${PID} +wait + +echo "Checking whether receiving 3 tickets in the same record succeeds" + +eval "${GETPORT}" +PYTHONPATH="${PYPATH}" ${TLSPY_SERV} server --tickets 3 -k ${KEY1} -c ${CERT1} 127.0.0.1:${PORT} & +PID=$! +wait_server ${PID} + +${VALGRIND} "${CLI}" -p "${PORT}" 127.0.0.1 --priority NORMAL:-VERS-ALL:+VERS-TLS1.3 --insecure </dev/null || \ + fail ${PID} "2. handshake should have succeeded!" + + +kill ${PID} +wait + +echo "Checking whether receiving multiple tickets that span many records succeeds" + +eval "${GETPORT}" +PYTHONPATH="${PYPATH}" ${TLSPY_SERV} server --tickets 1512 -k ${KEY1} -c ${CERT1} 127.0.0.1:${PORT} & +PID=$! +wait_server ${PID} + +${VALGRIND} "${CLI}" -p "${PORT}" 127.0.0.1 --priority NORMAL:-VERS-ALL:+VERS-TLS1.3 --insecure </dev/null || \ + fail ${PID} "3. handshake should have succeeded!" + + +kill ${PID} +wait + + +exit 0 |