From: Nikos Mavrogiannopoulos Date: Sun, 20 Feb 2011 20:52:35 +0000 (+0100) Subject: Discard messages that contain a different epoch than the current one. X-Git-Tag: gnutls_2_99_0~202 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b4d5df461f27da034da090da355e179d95702721;p=thirdparty%2Fgnutls.git Discard messages that contain a different epoch than the current one. --- diff --git a/lib/gnutls_constate.h b/lib/gnutls_constate.h index 65b609d24b..82744cbd70 100644 --- a/lib/gnutls_constate.h +++ b/lib/gnutls_constate.h @@ -47,6 +47,19 @@ void _gnutls_epoch_gc (gnutls_session_t session); void _gnutls_epoch_free (gnutls_session_t session, record_parameters_st * state); +static inline int _gnutls_epoch_is_valid(gnutls_session_t session, int epoch) +{ + record_parameters_st * params; + int ret; + + ret = _gnutls_epoch_get( session, epoch, ¶ms); + if (ret < 0) + return 0; + + return 1; +} + + static inline int _gnutls_epoch_refcount_inc(gnutls_session_t session, int epoch) { record_parameters_st * params; diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index ebbeede710..10c074f0c2 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -1054,6 +1054,7 @@ begin: return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } + /* ok now we are sure that we can read all the data - so * move on ! */ @@ -1074,8 +1075,23 @@ begin: return ret; } - if (IS_DTLS(session)) - decrypt_sequence = &dtls_sequence; + /* Check if the DTLS epoch is valid */ + if (IS_DTLS(session)) + { + uint16_t epoch = _gnutls_read_uint16(dtls_sequence.i); + + if (_gnutls_epoch_is_valid(session, epoch) == 0) + { + _gnutls_audit_log("Discarded message with invalid epoch 0x%.2x%.2x current: 0x%.4x\n", + (int)dtls_sequence.i[0], (int)dtls_sequence.i[1], (int)record_params->epoch); + + _mbuffer_remove_bytes (&session->internals.record_recv_buffer, + header_size + length); + return GNUTLS_E_AGAIN; + } + + decrypt_sequence = &dtls_sequence; + } else decrypt_sequence = &record_state->sequence_number; @@ -1104,7 +1120,7 @@ begin: ret = _dtls_record_check(session, decrypt_sequence); if (ret < 0) { - _gnutls_audit_log("Duplicate message with sequence %u\n", + _gnutls_audit_log("Discarded duplicate message with sequence %u\n", (unsigned int) _gnutls_uint64touint32 (decrypt_sequence)); return GNUTLS_E_AGAIN; }