diff options
35 files changed, 847 insertions, 135 deletions
diff --git a/.gitignore b/.gitignore index b17924c6b3..98275484ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *~ /ABOUT-NLS +AUTHORS ABOUT-NLS aclocal.m4 autom4te.cache/ @@ -624,6 +625,7 @@ tests/resume-lifetime tests/resume-psk tests/resume-with-false-start tests/resume-with-previous-stek +tests/resume-with-record-size-limit tests/resume-with-stek-expiration tests/resume-x509 tests/rng-fork diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6a7652ddeb..cc67461034 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -31,6 +31,7 @@ variables: DEBIAN_X86_CROSS_BUILD: buildenv-debian-x86-cross FEDORA28_BUILD: buildenv-f28 FEDORA_BUILD: buildenv-f29 + ALPINE_BASE_BUILD: buildenv-alpine-base CPPCHECK_OPTIONS: "--enable=warning --enable=style --enable=performance --enable=portability --std=c99 --suppressions-list=devel/cppcheck.suppressions --template='{id}:{file}:{line},{severity},{message}'" GET_SOURCES_ATTEMPTS: "3" @@ -38,6 +39,23 @@ variables: # Stage 1, documentation, and advanced checks ################################################## +commit-check: + stage: stage1-testing + image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$ALPINE_BASE_BUILD + before_script: + - /bin/true + after_script: + - /bin/true + cache: + # do not load cache files + key: none + policy: pull + script: + # we want $ALPINE_BASE_BUILD without git, so add it here + - apk add git + - devel/check_if_signed + retry: 0 + doc-dist.Fedora: stage: stage1-testing image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000000..0a00a34071 --- /dev/null +++ b/.mailmap @@ -0,0 +1,21 @@ +Andreas Metzler <ametzler@debian.org> <ametzler@bebt.de> +Andreas Metzler <ametzler@debian.org> <ametzler@downhill.at.eu.org> +Daiki Ueno <ueno@gnu.org> <dueno@redhat.com> +Daiki Ueno <ueno@gnu.org> <ueno@redhat.com> +Daiki Ueno <ueno@gnu.org> <ueno@unixuser.org> +David Woodhouse <dwmw2@infradead.org> <david.woodhouse@intel.com> +Giuseppe Scrivano <gscrivano@gnu.org> <giuseppe@southpole.se> +Ludovic Courtès <ludo@gnu.org> +Ludovic Courtès <ludo@gnu.org> <ludo@chbouib.org> +Nikos Mavrogiannopoulos <nmav@gnutls.org> <nikos@esat.kuleuven.be> +Nikos Mavrogiannopoulos <nmav@gnutls.org> <nikos@thingfish.esat.kuleuven.be> +Nikos Mavrogiannopoulos <nmav@gnutls.org> <nmav@crystal.(none)> +Nikos Mavrogiannopoulos <nmav@gnutls.org> <nmav@redhat.com> +Nikos Mavrogiannopoulos <nmav@gnutls.org> <n.mavrogiannopoulos@gmail.com> +Nikos Mavrogiannopoulos <nmav@gnutls.org> <nmav@turtle.(none)> +Simon Josefsson <jas@josefsson.org> <jas@mocca.josefsson.org> +Simon Josefsson <jas@josefsson.org> <simon@josefsson.org> +Stefan Berger <stefanb@linux.ibm.com> <stefanb@linux.vnet.ibm.com> +Stef Walter <stefw@redhat.com> <stefw@collabora.co.uk> +Tim Rühsen <tim.ruehsen@gmx.de> Tim Ruehsen <tim.ruehsen@gmx.de> +Tom Vrancken <dev@tomvrancken.nl> <email@tomvrancken.nl> diff --git a/.travis.yml b/.travis.yml index d060703983..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 @@ -27,7 +26,7 @@ before_install: fi script: - - PATH=/usr/local/opt/gettext/bin:$PATH make autoreconf + - PATH=/usr/local/opt/gettext/bin:$PATH ./bootstrap - PATH=/usr/local/opt/gettext/bin:$PATH ./configure --disable-full-test-suite --disable-valgrind-tests --disable-doc --disable-guile --disable-dependency-tracking - make -j$(sysctl -n hw.ncpu) - make -j$(sysctl -n hw.ncpu) check gl_public_submodule_commit= diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index e0e7809de1..0000000000 --- a/AUTHORS +++ /dev/null @@ -1,56 +0,0 @@ -GnuTLS AUTHORS -- Information about the authors. -Copyright (C) 2000-2012 Free Software Foundation, Inc. -See the end for copying conditions. - -The copyright holder for GnuTLS is Free Software Foundation, Inc., 51 -Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -Simon Josefsson *simon [at] josefsson.org* -Previous maintainer; draft TLS 1.2 support. - -Nikos Mavrogiannopoulos *nmav [at] gnutls.org* -Original author and maintainer of GnuTLS. - -Fabio Fiorina *Fabio.Fiorina [at] alcatel.it* -ASN.1 structures parser library (libtasn1). - -Timo Schulz *twoaday [at] freakmail.de* -OpenPGP support (OpenCDK library). - -Andrew McDonald *andrew [at] mcdonald.org.uk* -OpenSSL compatible interface. - -Ludovic Courtes *ludo [at] gnu.org* -Guile bindings, OpenPGP bug fixes. - -Stefan Walter *stef [at] memberwebs.com* -PKCS8 fix, PKCS #11 backend move to p11-kit. - -Yoshisato YANAGISAWA *yanagisawa [at] csg.is.titech.ac.jp* -Initial Camellia-CBC support. - -Daiki Ueno *ueno [at] unixuser.org* -TLS Session Ticket (RFC 5077) support, -finished client-side TLS 1.2 support. - -Jonathan Bastien-Filiatrault *joe [at] x2a.org* -Fix TLS-version checks. -Redesign and implementation of the buffering layer. -Initial DTLS implementation. - -Andy Polyakov *appro [at] openssl.org* -AES-NI and Padlock assembler code (at lib/accelerated/intel/asm/) - -David Woodhouse *dwmw2 [at] infradead.org* -DTLS 0.9 implementation. - -Martin Storjo *martin [at] martin.st* -DTLS-SRTP support. - -Alessandro Ghedini *alessandro [at] ghedini.me* -TLS Fallback SCSV support (RFC7507). - ----------------------------------------------------------------------- -Copying and distribution of this file, with or without modification, -are permitted in any medium without royalty provided the copyright -notice and this notice are preserved. diff --git a/Makefile.am b/Makefile.am index 57e42359bf..f3944b9366 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,6 +55,14 @@ ACLOCAL_AMFLAGS = -I m4 -I src/libopts/m4 -I src/gl/m4 -I lib/unistring/m4 --ins EXTRA_DIST = cfg.mk maint.mk CONTRIBUTING.md README.md LICENSE AUTHORS NEWS \ ChangeLog THANKS INSTALL.md symbols.last +DISTCLEANFILES = AUTHORS + +AUTHORS: + @echo -e "The authors list is autogenerated from the git history; sorted by number of commits\n" >AUTHORS + @git shortlog -sen| cut -f 2 | sed 's/@/ at /g' >> AUTHORS + @echo -e "\n\nThe translators list is autogenerated from po file history\n" >>AUTHORS + @sed -n 's/.*Last-Translator: *\(.*\) *<.*/\1/p' po/*.po | sort -u >>AUTHORS + pic-check: @echo "Checking for position dependent code" readelf -d $(builddir)/lib/.libs/libgnutls.so|grep TEXTREL; if test $$? = 0;then \ @@ -169,4 +177,4 @@ dist-hook: libopts-check symbol-check mv ChangeLog $(distdir) touch $(distdir)/doc/*.html $(distdir)/doc/*.pdf $(distdir)/doc/*.info -.PHONY: abi-check abi-dump pic-check symbol-check local-code-coverage-output files-update libopts-check +.PHONY: abi-check abi-dump pic-check symbol-check local-code-coverage-output files-update libopts-check AUTHORS @@ -20,6 +20,9 @@ See the end for copying conditions. This solves a regression since 3.5.x and improves compatibility of the server side with certain clients. +** libgnutls: We no longer mark RSA keys in PKCS#11 tokens as RSA-PSS capable if + the CKA_SIGN is not set (#667). + ** GNUTLS_X509_NO_WELL_DEFINED_EXPIRATION was marked as deprecated. The previous definition was buggy and non-functional. @@ -41,7 +41,7 @@ local-checks-to-skip = sc_GPL_version sc_bindtextdomain \ sc_unmarked_diagnostics sc_useless_cpp_parens \ sc_two_space_separator_in_usage -VC_LIST_ALWAYS_EXCLUDE_REGEX = ^maint.mk|gtk-doc.make|m4/pkg|doc/fdl-1.3.texi|src/crywrap/|(devel/perlasm/|lib/accelerated/x86/|build-aux/|gl/|src/libopts/|tests/suite/ecore/|doc/protocol/).*$$ +VC_LIST_ALWAYS_EXCLUDE_REGEX = ^maint.mk|gtk-doc.make|m4/pkg|doc/fdl-1.3.texi|src/.*\.bak|src/crywrap/|(devel/perlasm/|lib/accelerated/x86/|build-aux/|gl/|src/libopts/|tests/suite/ecore/|doc/protocol/).*$$ update-copyright-env = UPDATE_COPYRIGHT_USE_INTERVALS=1 # Explicit syntax-check exceptions. diff --git a/configure.ac b/configure.ac index a2267b8671..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]) @@ -365,17 +371,17 @@ AC_ARG_WITH(included-unistring, AS_HELP_STRING([--with-included-unistring], if test "$included_unistring" = yes;then ac_have_unistring=no else - AC_LIB_HAVE_LINKFLAGS(unistring,, [#include <uninorm.h>], [u8_normalize(0, 0, 0, 0, 0);]) - - if test "$HAVE_LIBUNISTRING" = "yes";then + AC_SEARCH_LIBS(u8_normalize, unistring, [ included_unistring=no ac_have_unistring=yes - else - AC_MSG_ERROR([[ + AC_SUBST([LIBUNISTRING], [$ac_cv_search_u8_normalize]) + ], [ + ac_cv_libunistring=no + AC_MSG_ERROR([[ *** *** Libunistring was not found. To use the included one, use --with-included-unistring - ]]) - fi + ]]) + ]) fi AM_CONDITIONAL(HAVE_LIBUNISTRING, test "$ac_have_unistring" = "yes") @@ -708,11 +714,9 @@ AM_MISSING_PROG([AUTOGEN], [autogen]) included_libopts=no if test "$enable_tools" != "no" || test "$enable_doc" != "no"; then - AC_MSG_CHECKING([whether autogen is recent enough]) - if $PKG_CONFIG --atleast-version=41.1.16 autoopts 2>&1 >/dev/null; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) + AC_CHECK_PROGS([autogen], [autogen]) + + if test -z "$autogen"; then AC_MSG_WARN([[ *** *** autogen not found. Will not link against system libopts. @@ -984,6 +988,7 @@ AC_CONFIG_FILES([ lib/unistring/Makefile po/Makefile.in src/Makefile + src/args-std.def src/gl/Makefile tests/Makefile tests/windows/Makefile diff --git a/devel/check_if_signed b/devel/check_if_signed new file mode 100755 index 0000000000..a053bbc0c8 --- /dev/null +++ b/devel/check_if_signed @@ -0,0 +1,25 @@ +#!/usr/bin/env sh + +if test -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"; then + CI_MERGE_REQUEST_TARGET_BRANCH_NAME="master" +fi + +echo "target=$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" +echo "source=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" + +# create list of commits of the current branch +commits=$(git rev-list --no-merges $CI_MERGE_REQUEST_TARGET_BRANCH_NAME..$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME) + +# check if author's email matches email in 'Signed-off-by' +for hash in $commits; do + author=$(git log --format='%ae' ${hash}^\!) + signed=$(git log --format='%b' ${hash}^\! | grep -i "Signed-off-by:") + if test $? -ne 0; then + echo "Missing Signed-off-by" + exit 1 + fi + if ! echo $signed | grep -q "Signed-off-by:.*<${author}>"; then + echo "Author '${author}' doesn't match" + exit 1 + fi +done diff --git a/gnulib b/gnulib -Subproject 4652c7bafa60332145f1e05a7de5f48e1bc5622 +Subproject 6c0f109fb98501fc8d65ea2c83501b45a80b00a 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/alert.c b/lib/alert.c index a7770da676..15f5183430 100644 --- a/lib/alert.c +++ b/lib/alert.c @@ -184,7 +184,7 @@ gnutls_alert_send(gnutls_session_t session, gnutls_alert_level_t level, * renegotiation will be performed. * * If there is no mapping to a valid alert the alert to indicate - * internal error is returned. + * internal error (%GNUTLS_A_INTERNAL_ERROR) is returned. * * Returns: the alert code to use for a particular error code. **/ @@ -257,6 +257,8 @@ int gnutls_error_to_alert(int err, int *level) case GNUTLS_E_UNKNOWN_PK_ALGORITHM: case GNUTLS_E_UNWANTED_ALGORITHM: case GNUTLS_E_NO_COMMON_KEY_SHARE: + case GNUTLS_E_ECC_NO_SUPPORTED_CURVES: + case GNUTLS_E_ECC_UNSUPPORTED_CURVE: ret = GNUTLS_A_HANDSHAKE_FAILURE; _level = GNUTLS_AL_FATAL; break; @@ -338,7 +340,7 @@ int gnutls_error_to_alert(int err, int *level) /** * gnutls_alert_send_appropriate: * @session: is a #gnutls_session_t type. - * @err: is an integer + * @err: is an error code returned by another GnuTLS function * * Sends an alert to the peer depending on the error code returned by * a gnutls function. This function will call gnutls_error_to_alert() @@ -347,8 +349,11 @@ int gnutls_error_to_alert(int err, int *level) * This function may also return %GNUTLS_E_AGAIN, or * %GNUTLS_E_INTERRUPTED. * - * If the return value is %GNUTLS_E_INVALID_REQUEST, then no alert has - * been sent to the peer. + * This function historically was always sending an alert to the + * peer, even if @err was inappropriate to respond with an alert + * (e.g., %GNUTLS_E_SUCCESS). Since 3.6.6 this function returns + * success without transmitting any data on error codes that + * should not result to an alert. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise * an error code is returned. @@ -358,10 +363,11 @@ int gnutls_alert_send_appropriate(gnutls_session_t session, int err) int alert; int level; + if (err != GNUTLS_E_REHANDSHAKE && (!gnutls_error_is_fatal(err) || + err == GNUTLS_E_FATAL_ALERT_RECEIVED)) + return gnutls_assert_val(0); + alert = gnutls_error_to_alert(err, &level); - if (alert < 0) { - return alert; - } return gnutls_alert_send(session, (gnutls_alert_level_t)level, alert); } diff --git a/lib/constate.c b/lib/constate.c index 11fedab533..fbbff886e9 100644 --- a/lib/constate.c +++ b/lib/constate.c @@ -738,8 +738,6 @@ int _gnutls_epoch_set_keys(gnutls_session_t session, uint16_t epoch, hs_stage_t memcpy(dst->server_random, src->server_random, GNUTLS_RANDOM_SIZE); \ dst->ext_master_secret = src->ext_master_secret; \ dst->etm = src->etm; \ - dst->max_record_recv_size = src->max_record_recv_size; \ - dst->max_record_send_size = src->max_record_send_size; \ dst->prf = src->prf; \ dst->grp = src->grp; \ dst->pversion = src->pversion; \ @@ -757,8 +755,15 @@ void _gnutls_set_resumed_parameters(gnutls_session_t session) security_parameters_st *src = &session->internals.resumed_security_parameters; security_parameters_st *dst = &session->security_parameters; + const version_entry_st *ver = get_version(session); + + CPY_COMMON(ver->tls13_sem); - CPY_COMMON(get_version(session)->tls13_sem); + if (!ver->tls13_sem && + !(session->internals.hsk_flags & HSK_RECORD_SIZE_LIMIT_NEGOTIATED)) { + dst->max_record_recv_size = src->max_record_recv_size; + dst->max_record_send_size = src->max_record_send_size; + } } /* Sets the current connection session to conform with the diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c index 3d24c3aede..c2ad7d72fb 100644 --- a/lib/crypto-selftests.c +++ b/lib/crypto-selftests.c @@ -579,7 +579,7 @@ static int test_cipher(gnutls_cipher_algorithm_t cipher, ret = gnutls_cipher_decrypt2(hd, - vectors[i].ciphertext, + vectors[i].ciphertext, vectors[i].plaintext_size, tmp, sizeof(tmp)); if (ret < 0) { @@ -1293,7 +1293,7 @@ static int test_digest(gnutls_digest_algorithm_t dig, gnutls_hash_deinit(hd, data); data_size = gnutls_hash_get_len(dig); - if (ret < 0) + if (data_size <= 0) return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); if (data_size != vectors[i].output_size || @@ -1482,7 +1482,7 @@ static int test_mac(gnutls_mac_algorithm_t mac, gnutls_hmac_deinit(hd, data); data_size = gnutls_hmac_get_len(mac); - if (ret < 0) + if (data_size <= 0) return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); if (data_size != vectors[i].output_size || diff --git a/lib/ext/record_size_limit.c b/lib/ext/record_size_limit.c index 811e2ea93f..c74ae81e4b 100644 --- a/lib/ext/record_size_limit.c +++ b/lib/ext/record_size_limit.c @@ -39,7 +39,7 @@ const hello_ext_entry_st ext_mod_record_size_limit = { .name = "Record Size Limit", .tls_id = 28, .gid = GNUTLS_EXTENSION_RECORD_SIZE_LIMIT, - .parse_type = GNUTLS_EXT_TLS, + .parse_type = GNUTLS_EXT_MANDATORY, .validity = GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_DTLS | GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_EE | GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO, .recv_func = _gnutls_record_size_limit_recv_params, @@ -54,6 +54,8 @@ _gnutls_record_size_limit_recv_params(gnutls_session_t session, ssize_t data_size = _data_size; DECR_LEN(data_size, 2); + if (data_size != 0) + return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); new_size = _gnutls_read_uint16(data); /* protocol error */ 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/pkcs11_privkey.c b/lib/pkcs11_privkey.c index bf69b69ce4..53a2d8a937 100644 --- a/lib/pkcs11_privkey.c +++ b/lib/pkcs11_privkey.c @@ -581,17 +581,25 @@ gnutls_pkcs11_privkey_import_url(gnutls_pkcs11_privkey_t pkey, if (pkey->pk_algorithm == GNUTLS_PK_RSA) { /* determine whether it can do rsa-pss */ + ck_bool_t tval = 0; + a[0].type = CKA_MODULUS; a[0].value = NULL; a[0].value_len = 0; - if (pkcs11_get_attribute_value(pkey->sinfo.module, pkey->sinfo.pks, pkey->ref, a, 1) + a[1].type = CKA_SIGN; + a[1].value = &tval; + a[1].value_len = sizeof(tval); + if (pkcs11_get_attribute_value(pkey->sinfo.module, pkey->sinfo.pks, pkey->ref, a, 2) == CKR_OK) { pkey->bits = a[0].value_len*8; } ret = gnutls_pkcs11_token_check_mechanism(url, CKM_RSA_PKCS_PSS, NULL, 0, 0); - if (ret != 0) + if (ret != 0 && tval) { pkey->rsa_pss_ok = 1; + } else { + _gnutls_debug_log("Detected incompatible with TLS1.3 RSA key! (%s)\n", url); + } } a[0].type = CKA_ALWAYS_AUTHENTICATE; 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/lib/str-idna.c b/lib/str-idna.c index 30a09407c0..4f275aebfb 100644 --- a/lib/str-idna.c +++ b/lib/str-idna.c @@ -81,6 +81,14 @@ int gnutls_idna_map(const char *input, unsigned ilen, gnutls_datum_t *out, unsig idn2_tflags |= IDN2_TRANSITIONAL; #endif + /* This avoids excessive CPU usage with libidn2 < 2.1.1 */ + if (ilen > 2048) { + gnutls_assert(); + _gnutls_debug_log("unable to convert name '%.*s' to IDNA format: %s\n", + (int) ilen, input, idn2_strerror(IDN2_TOO_BIG_DOMAIN)); + return GNUTLS_E_INVALID_UTF8_STRING; + } + if (ilen == 0) { out->data = (uint8_t*)gnutls_strdup(""); out->size = 0; diff --git a/src/Makefile.am b/src/Makefile.am index 329cfdfd0f..35a3855c00 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,6 +33,24 @@ ARGS_BUILT = \ tpmtool-args.c tpmtool-args.h \ systemkey-args.c systemkey-args.h +# We bundle autogen-generated files as *.bak files. This is awkward, +# but it covers the common use-cases where autogen/libopts is +# installed or not. Do not attempt to simplify it unless autogen +# gains a support for better handling of intermediate files with +# autotools. +ARGS_BAK = \ + srptool-args.c.bak srptool-args.h.bak \ + psktool-args.c.bak psktool-args.h.bak \ + ocsptool-args.h.bak ocsptool-args.c.bak \ + serv-args.c.bak serv-args.h.bak \ + cli-args.c.bak cli-args.h.bak \ + cli-debug-args.c.bak cli-debug-args.h.bak \ + certtool-args.c.bak certtool-args.h.bak \ + danetool-args.c.bak danetool-args.h.bak \ + p11tool-args.c.bak p11tool-args.h.bak \ + tpmtool-args.c.bak tpmtool-args.h.bak \ + systemkey-args.c.bak systemkey-args.h.bak + ARGS_STAMPS = \ certtool-args.stamp cli-debug-args.stamp cli-args.stamp tpmtool-args.stamp \ systemkey-args.stamp srptool-args.stamp ocsptool-args.stamp p11tool-args.stamp \ @@ -40,11 +58,11 @@ ARGS_STAMPS = \ BUILT_SOURCES = $(ARGS_BUILT) mech-list.h -DISTCLEANFILES = mech-list.h +DISTCLEANFILES = $(BUILT_SOURCES) $(ARGS_STAMPS) -EXTRA_DIST = gen-mech-list.sh args-std.def.in args-std.def $(ARGS_BUILT) $(ARGS_STAMPS) +EXTRA_DIST = gen-mech-list.sh $(ARGS_BAK) -MAINTAINERCLEANFILES = args-std.def $(ARGS_BUILT) $(ARGS_STAMPS) +MAINTAINERCLEANFILES = $(ARGS_BAK) AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS) AM_CPPFLAGS = \ @@ -251,17 +269,23 @@ nodist_libcmd_systemkey_la_SOURCES = systemkey-args.c systemkey-args.h libcmd_systemkey_la_LIBADD = ../lib/libgnutls.la gl/libgnu_gpl.la ../gl/libgnu.la libcmd_systemkey_la_LIBADD += $(LTLIBREADLINE) $(INET_PTON_LIB) $(LIB_CLOCK_GETTIME) -args-std.def: args-std.def.in - $(AM_V_GEN) sed \ - -e 's|@VERSION[@]|$(VERSION)|g' \ - -e 's|@YEAR[@]|$(YEAR)|g' \ - -e 's|@PACKAGE_BUGREPORT[@]|$(PACKAGE_BUGREPORT)|g' \ - $< > $@.tmp && mv $@.tmp $@ - -SUFFIXES = .stamp .def +SUFFIXES = .stamp .def .c.bak .h.bak .def.stamp: - $(AM_V_GEN) $(AUTOGEN) $< && touch $@ + $(AM_V_GEN) $(AUTOGEN) $< || { \ + srcdir=''; \ + b=`echo $@ | sed 's/.stamp$$//'`; \ + test -f ./$${b}.def || srcdir=$(srcdir)/; \ + cp -p $${srcdir}$${b}.c.bak $${b}.c; \ + cp -p $${srcdir}$${b}.h.bak $${b}.h; \ + } && \ + touch $@ + +.c.c.bak: + $(AM_V_GEN) cp -p $< $@ + +.h.h.bak: + $(AM_V_GEN) cp -p $< $@ danetool-args.h: danetool-args.stamp danetool-args.c: danetool-args.stamp diff --git a/src/certtool-args.def b/src/certtool-args.def index d5336eda7b..55880ca9f0 100644 --- a/src/certtool-args.def +++ b/src/certtool-args.def @@ -200,8 +200,7 @@ flag = { arg-type = string; descrip = "Specify the key type to use on key generation"; doc = "This option can be combined with --generate-privkey, to specify - the key type to be generated. Valid options are, 'rsa', 'rsa-pss', -'dsa', 'ecdsa', and 'ed25519'."; +the key type to be generated. Valid options are, 'rsa', 'rsa-pss', 'dsa', 'ecdsa', and 'ed25519'."; }; flag = { @@ -312,9 +311,9 @@ flag = { value = e; descrip = "Verify a PEM encoded certificate chain"; doc = "Verifies the validity of a certificate chain. That is, an ordered set of - certificates where each one is the issuer of the previous, and the first is - the end-certificate to be validated. In a proper chain the last certificate - is a self signed one. It can be combined with --verify-purpose or --verify-hostname."; +certificates where each one is the issuer of the previous, and the first is +the end-certificate to be validated. In a proper chain the last certificate +is a self signed one. It can be combined with --verify-purpose or --verify-hostname."; }; flag = { diff --git a/src/certtool-cfg.c b/src/certtool-cfg.c index 8d5f63417d..05764dec21 100644 --- a/src/certtool-cfg.c +++ b/src/certtool-cfg.c @@ -2583,7 +2583,7 @@ int get_data_encipherment_status(void) if (batch) { return cfg.data_encipherment; } else { - return read_yesno("Will the certificate be used for data encryption? (Y/n): ", 1); + return read_yesno("Will the certificate be used for data encryption? (y/N): ", 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 56149cce5e..148f09fa4e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -400,7 +400,8 @@ endif if HAVE_FORK ctests += x509self x509dn anonself pskself dhepskself \ setcredcrash tls12-resume-x509 tls12-resume-psk tls12-resume-anon \ - tls13-resume-x509 tls13-resume-psk tls13-early-data tls13-early-data-neg + tls13-resume-x509 tls13-resume-psk tls13-early-data tls13-early-data-neg \ + resume-with-record-size-limit endif gc_CPPFLAGS = $(AM_CPPFLAGS) \ @@ -459,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/pkcs11/tls-neg-pkcs11-key.c b/tests/pkcs11/tls-neg-pkcs11-key.c index 764e93b6ad..f91414a6af 100644 --- a/tests/pkcs11/tls-neg-pkcs11-key.c +++ b/tests/pkcs11/tls-neg-pkcs11-key.c @@ -280,6 +280,14 @@ static const test_st tests[] = { .exp_kx = GNUTLS_KX_RSA, .needs_decryption = 1 }, + {.name = "tls1.2: rsa-decryption key, signatures prioritized", + .pk = GNUTLS_PK_RSA, + .prio = "NORMAL:-KX-ALL:+ECDHE-RSA:+RSA:-VERS-TLS-ALL:+VERS-TLS1.2:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", + .cert = &server_ca3_localhost_cert, + .key = &server_ca3_key, + .exp_kx = GNUTLS_KX_RSA, + .needs_decryption = 1 + }, {.name = "tls1.2: ecc key", .pk = GNUTLS_PK_ECDSA, .prio = "NORMAL:-KX-ALL:+ECDHE-RSA:+ECDHE-ECDSA:-VERS-TLS-ALL:+VERS-TLS1.2", diff --git a/tests/resume-with-record-size-limit.c b/tests/resume-with-record-size-limit.c new file mode 100644 index 0000000000..49801a2f64 --- /dev/null +++ b/tests/resume-with-record-size-limit.c @@ -0,0 +1,424 @@ +/* + * Copyright (C) 2004-2016 Free Software Foundation, Inc. + * Copyright (C) 2013 Adam Sampson <ats@offog.org> + * Copyright (C) 2016-2019 Red Hat, Inc. + * + * Author: Simon Josefsson, Nikos Mavrogiannopoulos, 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 <http://www.gnu.org/licenses/> + */ + +/* Parts copied from GnuTLS example programs. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> + +#if defined(_WIN32) + +/* socketpair isn't supported on Win32. */ +int main(int argc, char **argv) +{ + exit(77); +} + +#else + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#include <string.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/socket.h> +#if !defined(_WIN32) +#include <sys/wait.h> +#endif +#include <unistd.h> +#include <gnutls/gnutls.h> +#include <sys/wait.h> +#include <signal.h> +#include <assert.h> +#include "utils.h" +#include "cert-common.h" +#include "virt-time.h" + +#define SKIP8(pos, total) { \ + uint8_t _s; \ + if (pos+1 > total) fail("error\n"); \ + _s = msg->data[pos]; \ + if ((size_t)(pos+1+_s) > total) fail("error\n"); \ + pos += 1+_s; \ + } + +pid_t child; + +/* A very basic TLS client, with anonymous authentication. + */ + +#define SESSIONS 2 +#define MAX_BUF 5*1024 +#define MSG "Hello TLS" + +/* 2^13, which is not supported by max_fragment_length */ +#define MAX_DATA_SIZE 8192 + +#define HANDSHAKE_SESSION_ID_POS (2+32) + +static void tls_log_func(int level, const char *str) +{ + fprintf(stderr, "%s |<%d>| %s", child ? "server" : "client", level, + str); +} + +static int ext_callback(void *ctx, unsigned tls_id, const unsigned char *data, unsigned size) +{ + if (tls_id == 28) { /* record size limit */ + uint16_t max_data_size; + + assert(size == 2); + max_data_size = (data[0] << 8) | data[1]; + if (max_data_size == MAX_DATA_SIZE) + fail("record_size_limit is not reset: %u == %u\n", + max_data_size, MAX_DATA_SIZE); + } + return 0; +} + +static int handshake_callback(gnutls_session_t session, unsigned int htype, + unsigned post, unsigned int incoming, const gnutls_datum_t *msg) +{ + int ret; + unsigned pos; + gnutls_datum_t mmsg; + + if (!post) + return 0; + + switch (htype) { + case GNUTLS_HANDSHAKE_ENCRYPTED_EXTENSIONS: + ret = gnutls_ext_raw_parse(NULL, ext_callback, msg, 0); + assert(ret >= 0); + break; + case GNUTLS_HANDSHAKE_SERVER_HELLO: + assert(msg->size >= HANDSHAKE_SESSION_ID_POS); + pos = HANDSHAKE_SESSION_ID_POS; + SKIP8(pos, msg->size); + pos += 3; + + mmsg.data = &msg->data[pos]; + mmsg.size = msg->size - pos; + ret = gnutls_ext_raw_parse(NULL, ext_callback, &mmsg, 0); + assert(ret >= 0); + break; + default: + break; + } + return 0; +} + +static void client(int sds[], const char *prio) +{ + int ret, ii; + gnutls_session_t session; + char buffer[MAX_BUF + 1]; + gnutls_certificate_credentials_t clientx509cred; + + /* variables used in session resuming + */ + int t; + gnutls_datum_t session_data = {NULL, 0}; + + if (debug) { + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(4); + } + + gnutls_certificate_allocate_credentials(&clientx509cred); + + assert(gnutls_certificate_set_x509_key_mem(clientx509cred, + &cli_cert, &cli_key, + GNUTLS_X509_FMT_PEM) >= 0); + + for (t = 0; t < SESSIONS; t++) { + int sd = sds[t]; + + assert(gnutls_init(&session, GNUTLS_CLIENT)>=0); + + ret = gnutls_priority_set_direct(session, prio, NULL); + if (ret < 0) { + fail("prio: %s\n", gnutls_strerror(ret)); + } + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, clientx509cred); + + if (t == 0) { + ret = gnutls_record_set_max_size(session, MAX_DATA_SIZE); + if (ret < 0) + fail("gnutls_set_max_size: %s\n", gnutls_strerror(ret)); + } + + if (t > 0) { + /* if this is not the first time we connect */ + gnutls_session_set_data(session, session_data.data, + session_data.size); + + gnutls_handshake_set_hook_function(session, + GNUTLS_HANDSHAKE_ANY, + GNUTLS_HOOK_POST, + handshake_callback); + } + + gnutls_transport_set_int(session, sd); + + /* Perform the TLS handshake + */ + gnutls_handshake_set_timeout(session, 20 * 1000); + do { + ret = gnutls_handshake(session); + } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); + + if (ret < 0) { + fail("client: Handshake failed\n"); + gnutls_perror(ret); + break; + } else { + if (debug) + success + ("client: Handshake was completed\n"); + } + + if (t == 0) { + /* get the session data size */ + ret = + gnutls_session_get_data2(session, + &session_data); + if (ret < 0) + fail("Getting resume data failed\n"); + + } else { /* the second time we connect */ + /* check if we actually resumed the previous session */ + if (gnutls_session_is_resumed(session) == 0) { + fail("- Previous session was resumed but NOT expected\n"); + } + } + + gnutls_record_send(session, MSG, strlen(MSG)); + + do { + ret = gnutls_record_recv(session, buffer, MAX_BUF); + } while (ret == GNUTLS_E_AGAIN); + if (ret == 0) { + if (debug) + success + ("client: Peer has closed the TLS connection\n"); + break; + } else if (ret < 0) { + fail("client: Error: %s\n", gnutls_strerror(ret)); + } + + if (debug) { + printf("- Received %d bytes: ", ret); + for (ii = 0; ii < ret; ii++) { + fputc(buffer[ii], stdout); + } + fputs("\n", stdout); + } + + gnutls_bye(session, GNUTLS_SHUT_RDWR); + + close(sd); + + gnutls_deinit(session); + } + gnutls_free(session_data.data); + + gnutls_certificate_free_credentials(clientx509cred); +} + +/* These are global */ +static gnutls_datum_t session_ticket_key = { NULL, 0 }; + + +gnutls_certificate_credentials_t serverx509cred; + +static void global_stop(void) +{ + if (debug) + success("global stop\n"); + + gnutls_certificate_free_credentials(serverx509cred); +} + +static void server(int sds[], const char *prio) +{ + int t; + int ret; + gnutls_session_t session; + char buffer[MAX_BUF + 1]; + unsigned iflags = GNUTLS_SERVER; + + virt_time_init(); + + /* this must be called once in the program, it is mostly for the server. + */ + if (debug) { + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(4); + } + + gnutls_certificate_allocate_credentials(&serverx509cred); + assert(gnutls_certificate_set_x509_key_mem(serverx509cred, + &server_cert, &server_key, GNUTLS_X509_FMT_PEM) >= 0); + + gnutls_session_ticket_key_generate(&session_ticket_key); + + for (t = 0; t < SESSIONS; t++) { + int sd = sds[t]; + + assert(gnutls_init(&session, iflags) >= 0); + + /* avoid calling all the priority functions, since the defaults + * are adequate. + */ + assert(gnutls_priority_set_direct(session, prio, NULL) >= 0); + + + gnutls_session_ticket_enable_server(session, + &session_ticket_key); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, serverx509cred); + gnutls_transport_set_int(session, sd); + gnutls_handshake_set_timeout(session, 20 * 1000); + + do { + ret = gnutls_handshake(session); + } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); + if (ret < 0) { + close(sd); + gnutls_deinit(session); + kill(child, SIGTERM); + fail("server: Handshake has failed (%s)\n\n", + gnutls_strerror(ret)); + return; + } + if (debug) + success("server: Handshake was completed\n"); + + if (t > 0) { + ret = gnutls_session_is_resumed(session); + if (ret == 0) { + fail("server: session_is_resumed error (%d)\n", t); + } + } + + /* see the Getting peer's information example */ + /* print_info(session); */ + + for (;;) { + memset(buffer, 0, MAX_BUF + 1); + ret = gnutls_record_recv(session, buffer, MAX_BUF); + + if (ret == 0) { + if (debug) + success + ("server: Peer has closed the GnuTLS connection\n"); + break; + } else if (ret < 0) { + kill(child, SIGTERM); + fail("server: Received corrupted data(%d). Closing...\n", ret); + break; + } else if (ret > 0) { + /* echo data back to the client + */ + gnutls_record_send(session, buffer, + strlen(buffer)); + } + } + /* do not wait for the peer to close the connection. + */ + gnutls_bye(session, GNUTLS_SHUT_WR); + + close(sd); + + gnutls_deinit(session); + } + + gnutls_free(session_ticket_key.data); + session_ticket_key.data = NULL; + + if (debug) + success("server: finished\n"); +} + +static void run(const char *prio) +{ + int client_sds[SESSIONS], server_sds[SESSIONS]; + int j; + int err; + + signal(SIGCHLD, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + + for (j = 0; j < SESSIONS; j++) { + int sockets[2]; + + err = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); + if (err == -1) { + perror("socketpair"); + fail("socketpair failed\n"); + return; + } + + server_sds[j] = sockets[0]; + client_sds[j] = sockets[1]; + } + + child = fork(); + if (child < 0) { + perror("fork"); + fail("fork\n"); + return; + } + + if (child) { + int status = 0; + /* parent */ + for (j = 0; j < SESSIONS; j++) + close(client_sds[j]); + server(server_sds, prio); + + waitpid(child, &status, 0); + check_wait_status(status); + global_stop(); + } else { + for (j = 0; j < SESSIONS; j++) + close(server_sds[j]); + client(client_sds, prio); + exit(0); + } +} + +void doit(void) +{ + run("NORMAL:-VERS-ALL:+VERS-TLS1.2"); + run("NORMAL:-VERS-ALL:+VERS-TLS1.3"); +} + +#endif /* _WIN32 */ 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 diff --git a/tests/suite/tls-fuzzer/gnutls-nocert.json b/tests/suite/tls-fuzzer/gnutls-nocert.json index 6e2a2ea47c..04376f40ea 100644 --- a/tests/suite/tls-fuzzer/gnutls-nocert.json +++ b/tests/suite/tls-fuzzer/gnutls-nocert.json @@ -230,6 +230,28 @@ "-e", "non fragmented, over fragmentation limit: 65535 fragment - 16332B extension", "-e", "small, maximum fragmentation: 1 fragment - 20B extension", "-e", "medium, maximum fragmentation: 1 fragment - 1024B extension"]}, + {"name" : "test-record-size-limit.py", + "comment" : "These tests rely on too small lower limit we don't support; TLS 1.3 high limit is not what we expect; 1/n-1 splitting is not supported in TLS 1.0; we don't reject too large appliation_data records in TLS 1.2 #676", + "arguments" : ["-p", "@PORT@", "--reply-AD-size", "{expected_size}", + "-e", "change size in TLS 1.2 resumption", + "-e", "change size in TLS 1.3 session resumption", + "-e", "check if server accepts maximum size in TLS 1.0", + "-e", "check if server accepts maximum size in TLS 1.3", + "-e", "check if server accepts minimal size in TLS 1.0", + "-e", "check if server accepts minimal size in TLS 1.1", + "-e", "check if server accepts minimal size in TLS 1.2", + "-e", "check if server accepts minimal size in TLS 1.3", + "-e", "check interaction with sha256 prf", + "-e", "check interaction with sha384 prf", + "-e", "check server sent size in TLS 1.0", + "-e", "check server sent size in TLS 1.3", + "-e", "drop extension in TLS 1.3 session resumption", + "-e", "HRR sanity", + "-e", "modified extension in 2nd CH in HRR handshake", + "-e", "renegotiation with changed limit", + "-e", "renegotiation with dropped extension", + "-e", "too large record in TLS 1.2", + "-e", "too large record payload in TLS 1.3"] }, {"name" : "test-sessionID-resumption.py", "arguments" : ["-p", "@PORT@"] }, {"name" : "test-serverhello-random.py", diff --git a/tests/suite/tls-fuzzer/tls-fuzzer-common.sh b/tests/suite/tls-fuzzer/tls-fuzzer-common.sh index 111fd44970..b41f068a07 100755 --- a/tests/suite/tls-fuzzer/tls-fuzzer-common.sh +++ b/tests/suite/tls-fuzzer/tls-fuzzer-common.sh @@ -44,7 +44,7 @@ retval=0 tls_fuzzer_prepare -PYTHONPATH=. python tests/scripts_retention.py ${TMPFILE} ${SERV} +PYTHONPATH=. python tests/scripts_retention.py ${TMPFILE} ${SERV} 821 retval=$? rm -f ${TMPFILE} diff --git a/tests/suite/tls-fuzzer/tlsfuzzer b/tests/suite/tls-fuzzer/tlsfuzzer -Subproject b9dec4fde7bedfac90850b86c2c3f644349f6c3 +Subproject 7b2ebe4c8bd06e5a1059a8aeb5bfe2b014e2b52 diff --git a/tests/suite/tls-fuzzer/tlslite-ng b/tests/suite/tls-fuzzer/tlslite-ng -Subproject 3696909715ba73ee807d3959a26d36b56f718ba +Subproject 029425144f6b26d5ab8acc3a79e3ead79253ad7 diff --git a/tests/x509dn.c b/tests/x509dn.c index 820e414b53..056351c19d 100644 --- a/tests/x509dn.c +++ b/tests/x509dn.c @@ -136,7 +136,7 @@ cert_callback(gnutls_session_t session, static void client(int sd, const char *prio) { int ret, ii; - gnutls_session_t session; + gnutls_session_t session = NULL; char buffer[MAX_BUF + 1]; gnutls_certificate_credentials_t xcred; |