[tor-commits] [tor/master] Detect and deny excess renegotiations attempts.

nickm at torproject.org nickm at torproject.org
Fri Nov 25 22:22:51 UTC 2011


commit ecd239e3b577705e0669d47293a2e755cf93cec0
Author: George Kadianakis <desnacked at gmail.com>
Date:   Wed Oct 26 03:12:18 2011 +0200

    Detect and deny excess renegotiations attempts.
    
    Switch 'server_handshake_count' from a uint8_t to 2 unsigned int bits.
    Since we won't ever be doing more than 3 handshakes, we don't need the
    extra space.
    
    Toggle tor_tls_t.got_renegotiate based on the server_handshake_count.
    Also assert that when we've done two handshakes as a server (the initial
    SSL handshake, and the renegotiation handshake) we've just
    renegotiated.
    
    Finally, in tor_tls_read() return an error if we see more than 2
    handshakes.
---
 src/common/tortls.c |   20 +++++++++++++++-----
 1 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/common/tortls.c b/src/common/tortls.c
index 79b6d2c..7269785 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -146,7 +146,7 @@ struct tor_tls_t {
   /** True iff we should call negotiated_callback when we're done reading. */
   unsigned int got_renegotiate:1;
   /** Incremented every time we start the server side of a handshake. */
-  uint8_t server_handshake_count;
+  unsigned int server_handshake_count:2;
   size_t wantwrite_n; /**< 0 normally, >0 if we returned wantwrite last
                        * time. */
   /** Last values retrieved from BIO_number_read()/write(); see
@@ -1286,12 +1286,14 @@ tor_tls_client_is_using_v2_ciphers(const SSL *ssl, const char *address)
 static void
 tor_tls_got_server_hello(tor_tls_t *tls)
 {
-  /* Check whether we're watching for renegotiates.  If so, this is one! */
-  if (tls->negotiated_callback)
-    tls->got_renegotiate = 1;
-  if (tls->server_handshake_count < 127) /*avoid any overflow possibility*/
+  if (tls->server_handshake_count < 3)
     ++tls->server_handshake_count;
 
+  if (tls->server_handshake_count == 2) {
+    tor_assert(tls->negotiated_callback);
+    tls->got_renegotiate = 1;
+  }
+
   /* Now check the cipher list. */
   if (tor_tls_client_is_using_v2_ciphers(tls->ssl, ADDR(tls))) {
     /*XXXX_TLS keep this from happening more than once! */
@@ -1625,6 +1627,14 @@ tor_tls_read(tor_tls_t *tls, char *cp, size_t len)
     tls->got_renegotiate = 0;
 
     return r;
+  } else if (tls->server_handshake_count > 2) {
+    /* If we get more than 2 handshakes, it means that our peer is
+       trying to re-renegotiate. Return an error. */
+    tor_assert(tls->server_handshake_count == 3);
+
+    log_info(LD_NET, "Detected excess renegotiation from %s!", ADDR(tls));
+
+    return TOR_TLS_ERROR_MISC;
   }
 #endif
 





More information about the tor-commits mailing list