]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Discard messages that contain a different epoch than the current one.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 20 Feb 2011 20:52:35 +0000 (21:52 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 20 Feb 2011 20:52:35 +0000 (21:52 +0100)
lib/gnutls_constate.h
lib/gnutls_record.c

index 65b609d24bd1db2b6148d7aa89307282c08d7bd3..82744cbd70e120fb769003d4998b563acbe85adc 100644 (file)
@@ -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, &params);
+  if (ret < 0)
+    return 0;
+
+  return 1;
+}
+
+
 static inline int _gnutls_epoch_refcount_inc(gnutls_session_t session, int epoch)
 {
   record_parameters_st * params;
index ebbeede7101c505901ee11cd69bc56654d9ca3d8..10c074f0c28a73c4bc767af5537657e28e908f3d 100644 (file)
@@ -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;
         }