[tor-commits] [tor/master] Refactor the SSL_set_info_callback() callbacks.

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


commit 69a821ea1c9357acdd5aa1c9e23fd030b01cb5a9
Author: George Kadianakis <desnacked at gmail.com>
Date:   Wed Oct 26 02:05:45 2011 +0200

    Refactor the SSL_set_info_callback() callbacks.
    
    Introduce tor_tls_state_changed_callback(), which handles every SSL
    state change.
    
    The new function tor_tls_got_server_hello() is called every time we
    send a ServerHello during a v2 handshake, and plays the role of the
    previous tor_tls_server_info_callback() function.
---
 src/common/tortls.c |   97 +++++++++++++++++++++++----------------------------
 1 files changed, 44 insertions(+), 53 deletions(-)

diff --git a/src/common/tortls.c b/src/common/tortls.c
index 9a3c02b..6757cfa 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -1280,55 +1280,29 @@ tor_tls_client_is_using_v2_ciphers(const SSL *ssl, const char *address)
   return 1;
 }
 
+/** We sent the ServerHello part of an SSL handshake.  This might mean
+ * that we completed a renegotiation and appropriate actions must be
+ * taken. */
 static void
-tor_tls_debug_state_callback(const SSL *ssl, int type, int val)
+tor_tls_got_server_hello(tor_tls_t *tls)
 {
-  log_debug(LD_HANDSHAKE, "SSL %p is now in state %s [type=%d,val=%d].",
-            ssl, ssl_state_to_string(ssl->state), type, val);
-}
-
-/** Invoked when we're accepting a connection on <b>ssl</b>, and the connection
- * changes state. We use this:
- * <ul><li>To alter the state of the handshake partway through, so we
- *         do not send or request extra certificates in v2 handshakes.</li>
- * <li>To detect renegotiation</li></ul>
- */
-static void
-tor_tls_server_info_callback(const SSL *ssl, int type, int val)
-{
-  tor_tls_t *tls;
-  (void) val;
-
-  tor_tls_debug_state_callback(ssl, type, val);
-
-  if (type != SSL_CB_ACCEPT_LOOP)
-    return;
-  if (ssl->state != SSL3_ST_SW_SRVR_HELLO_A)
-    return;
-
-  tls = tor_tls_get_by_ssl(ssl);
-  if (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*/
-      ++tls->server_handshake_count;
-  } else {
-    log_warn(LD_BUG, "Couldn't look up the tls for an SSL*. How odd!");
-    return;
-  }
+  /* 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*/
+    ++tls->server_handshake_count;
 
   /* Now check the cipher list. */
-  if (tor_tls_client_is_using_v2_ciphers(ssl, ADDR(tls))) {
+  if (tor_tls_client_is_using_v2_ciphers(tls->ssl, ADDR(tls))) {
     /*XXXX_TLS keep this from happening more than once! */
 
     /* Yes, we're casting away the const from ssl.  This is very naughty of us.
      * Let's hope openssl doesn't notice! */
 
     /* Set SSL_MODE_NO_AUTO_CHAIN to keep from sending back any extra certs. */
-    SSL_set_mode((SSL*) ssl, SSL_MODE_NO_AUTO_CHAIN);
+    SSL_set_mode((SSL*) tls->ssl, SSL_MODE_NO_AUTO_CHAIN);
     /* Don't send a hello request. */
-    SSL_set_verify((SSL*) ssl, SSL_VERIFY_NONE, NULL);
+    SSL_set_verify((SSL*) tls->ssl, SSL_VERIFY_NONE, NULL);
 
     if (tls) {
       tls->wasV2Handshake = 1;
@@ -1343,6 +1317,35 @@ tor_tls_server_info_callback(const SSL *ssl, int type, int val)
 }
 #endif
 
+/** This is a callback function for SSL_set_info_callback() and it
+ *  will be called in every SSL state change.
+ *  It logs the SSL state change, and executes any actions that must be
+ *  taken.  */
+static void
+tor_tls_state_changed_callback(const SSL *ssl, int type, int val)
+{
+  log_debug(LD_HANDSHAKE, "SSL %p is now in state %s [type=%d,val=%d].",
+            ssl, ssl_state_to_string(ssl->state), type, val);
+
+#ifdef V2_HANDSHAKE_SERVER
+  if (type == SSL_CB_ACCEPT_LOOP &&
+      ssl->state == SSL3_ST_SW_SRVR_HELLO_A) {
+
+    /* Call tor_tls_got_server_hello() for every SSL ServerHello we
+       send. */
+
+    tor_tls_t *tls = tor_tls_get_by_ssl(ssl);
+    if (!tls) {
+      log_warn(LD_BUG, "Couldn't look up the tls for an SSL*. How odd!");
+      return;
+    }
+
+    tor_tls_got_server_hello(tls);
+  }
+#endif
+
+}
+
 /** Replace *<b>ciphers</b> with a new list of SSL ciphersuites: specifically,
  * a list designed to mimic a common web browser.  Some of the ciphers in the
  * list won't actually be implemented by OpenSSL: that's okay so long as the
@@ -1484,14 +1487,8 @@ tor_tls_new(int sock, int isServer)
     log_warn(LD_NET, "Newly created BIO has read count %lu, write count %lu",
              result->last_read_count, result->last_write_count);
   }
-#ifdef V2_HANDSHAKE_SERVER
-  if (isServer) {
-    SSL_set_info_callback(result->ssl, tor_tls_server_info_callback);
-  } else
-#endif
-  {
-    SSL_set_info_callback(result->ssl, tor_tls_debug_state_callback);
-  }
+
+  SSL_set_info_callback(result->ssl, tor_tls_state_changed_callback);
 
   /* Not expected to get called. */
   tls_log_errors(NULL, LOG_WARN, LD_NET, "creating tor_tls_t object");
@@ -1521,13 +1518,7 @@ tor_tls_set_renegotiate_callback(tor_tls_t *tls,
   tls->negotiated_callback = cb;
   tls->callback_arg = arg;
   tls->got_renegotiate = 0;
-#ifdef V2_HANDSHAKE_SERVER
-  if (cb) {
-    SSL_set_info_callback(tls->ssl, tor_tls_server_info_callback);
-  } else {
-    SSL_set_info_callback(tls->ssl, tor_tls_debug_state_callback);
-  }
-#endif
+  SSL_set_info_callback(tls->ssl, tor_tls_state_changed_callback);
 }
 
 /** If this version of openssl requires it, turn on renegotiation on





More information about the tor-commits mailing list