diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2014-09-25 12:00:39 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2014-09-25 12:28:33 +0200 |
commit | a90fd3606147a96b305d074115e8303f5043ead1 (patch) | |
tree | fafbd1984f95df1508afa7962b2d998e7458243d | |
parent | bd946640aabc900943f7859ab5348c65f156ae93 (diff) | |
download | gnutls-a90fd3606147a96b305d074115e8303f5043ead1.tar.gz |
protect DTLS clients that don't handle GNUTLS_E_LARGE_PACKET from an infinite loop on handshake
-rw-r--r-- | lib/gnutls_handshake.c | 6 | ||||
-rw-r--r-- | lib/gnutls_int.h | 3 | ||||
-rw-r--r-- | lib/gnutls_state.c | 1 |
3 files changed, 9 insertions, 1 deletions
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index b978b6a9bf..47dc92bb24 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -2589,8 +2589,12 @@ gnutls_handshake_set_timeout(gnutls_session_t session, unsigned int ms) #define IMED_RET( str, ret, allow_alert) do { \ if (ret < 0) { \ /* EAGAIN and INTERRUPTED are always non-fatal */ \ - if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_LARGE_PACKET) \ + if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) \ return ret; \ + if (ret == GNUTLS_E_LARGE_PACKET && session->internals.handshake_large_loops < 16) { \ + session->internals.handshake_large_loops++; \ + return ret; \ + } \ /* a warning alert might interrupt handshake */ \ if (allow_alert != 0 && ret==GNUTLS_E_WARNING_ALERT_RECEIVED) return ret; \ gnutls_assert(); \ diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index f51d219ee2..e76f0ee481 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -944,6 +944,9 @@ typedef struct { /* DTLS session state */ dtls_st dtls; + /* In case of clients that don't handle GNUTLS_E_LARGE_PACKET, don't + * force them into an infinite loop */ + unsigned handshake_large_loops; /* if set it means that the master key was set using * gnutls_session_set_master() rather than being negotiated. */ diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index f2b9af7408..3a4a03cc6d 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -261,6 +261,7 @@ static void _gnutls_handshake_internal_state_init(gnutls_session_t session) session->internals.resumable = RESUME_TRUE; + session->internals.handshake_large_loops = 0; session->internals.dtls.hsk_read_seq = 0; session->internals.dtls.hsk_write_seq = 0; } |