[or-cvs] r12623: Add support to get a callback invoked when the client renego (in tor/trunk: . doc src/common src/or)

nickm at seul.org nickm at seul.org
Sat Dec 1 08:09:49 UTC 2007


Author: nickm
Date: 2007-12-01 03:09:48 -0500 (Sat, 01 Dec 2007)
New Revision: 12623

Modified:
   tor/trunk/
   tor/trunk/doc/TODO
   tor/trunk/src/common/tortls.c
   tor/trunk/src/common/tortls.h
   tor/trunk/src/or/connection.c
   tor/trunk/src/or/connection_or.c
   tor/trunk/src/or/or.h
Log:
 r15088 at tombo:  nickm | 2007-11-30 23:47:29 -0500
 Add support to get a callback invoked when the client renegotiate a connection.  Also, make clients renegotiate.  (not enabled yet, until they detect that the server acted like a v2 server)



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r15088] on d9e39d38-0f13-419c-a857-e10a0ce2aa0c

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/doc/TODO	2007-12-01 08:09:48 UTC (rev 12623)
@@ -39,7 +39,7 @@
         - Clients only send certificates when asked for them.
         o Servers disable callback once negotiation is finished, so
           that renegotiation happens according to the old rules.
-        - Clients initiate renegotiation immediately on completing
+        o Clients initiate renegotiation immediately on completing
           a v2 connection.
         - Servers detect renegotiation, and if there is now a client
           cert, they adust the client ID.

Modified: tor/trunk/src/common/tortls.c
===================================================================
--- tor/trunk/src/common/tortls.c	2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/src/common/tortls.c	2007-12-01 08:09:48 UTC (rev 12623)
@@ -70,6 +70,8 @@
                        * time. */
   unsigned long last_write_count;
   unsigned long last_read_count;
+  void (*negotiated_callback)(tor_tls_t *tls, void *arg);
+  void *callback_arg;
 };
 
 static void tor_tls_context_decref(tor_tls_context_t *ctx);
@@ -606,6 +608,16 @@
   return result;
 }
 
+/**DOCDOC*/
+void
+tor_tls_set_renegotiate_callback(tor_tls_t *tls,
+                                 void (*cb)(tor_tls_t *, void *arg),
+                                 void *arg)
+{
+  tls->negotiated_callback = cb;
+  tls->callback_arg = arg;
+}
+
 /** Return whether this tls initiated the connect (client) or
  * received it (server). */
 int
@@ -624,6 +636,7 @@
   tor_assert(tls && tls->ssl);
   SSL_free(tls->ssl);
   tls->ssl = NULL;
+  tls->negotiated_callback = NULL;
   if (tls->context)
     tor_tls_context_decref(tls->context);
   tor_free(tls);
@@ -648,7 +661,8 @@
       tls->hadCert = 1;
       /* New certificate! */
       log_info(LD_NET, "Got a TLS renegotiation.");
-      /* XXXX020 call some kind of 'there was a renegotiation' callback. */
+      if (tls->negotiated_callback)
+        tls->negotiated_callback(tls, tls->callback_arg);
     }
 #endif
     return r;

Modified: tor/trunk/src/common/tortls.h
===================================================================
--- tor/trunk/src/common/tortls.h	2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/src/common/tortls.h	2007-12-01 08:09:48 UTC (rev 12623)
@@ -52,6 +52,9 @@
 int tor_tls_context_new(crypto_pk_env_t *rsa,
                         const char *nickname, unsigned int key_lifetime);
 tor_tls_t *tor_tls_new(int sock, int is_server);
+void tor_tls_set_renegotiate_callback(tor_tls_t *tls,
+                                      void (*cb)(tor_tls_t *, void *arg),
+                                      void *arg);
 int tor_tls_is_server(tor_tls_t *tls);
 void tor_tls_free(tor_tls_t *tls);
 int tor_tls_peer_has_cert(tor_tls_t *tls);

Modified: tor/trunk/src/or/connection.c
===================================================================
--- tor/trunk/src/or/connection.c	2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/src/or/connection.c	2007-12-01 08:09:48 UTC (rev 12623)
@@ -89,6 +89,7 @@
         case OR_CONN_STATE_PROXY_FLUSHING: return "proxy flushing";
         case OR_CONN_STATE_PROXY_READING: return "proxy reading";
         case OR_CONN_STATE_TLS_HANDSHAKING: return "handshaking (TLS)";
+        case OR_CONN_STATE_TLS_RENEGOTIATING: return "renegotiating (TLS)";
         case OR_CONN_STATE_OR_HANDSHAKING: return "handshaking (Tor)";
         case OR_CONN_STATE_OPEN: return "open";
       }
@@ -1893,7 +1894,8 @@
       conn->state > OR_CONN_STATE_PROXY_READING) {
     int pending;
     or_connection_t *or_conn = TO_OR_CONN(conn);
-    if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING) {
+    if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING ||
+        conn->state == OR_CONN_STATE_TLS_RENEGOTIATING) {
       /* continue handshaking even if global token bucket is empty */
       return connection_tls_continue_handshake(or_conn);
     }
@@ -2115,7 +2117,8 @@
   if (connection_speaks_cells(conn) &&
       conn->state > OR_CONN_STATE_PROXY_READING) {
     or_connection_t *or_conn = TO_OR_CONN(conn);
-    if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING) {
+    if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING ||
+        conn->state == OR_CONN_STATE_TLS_RENEGOTIATING) {
       connection_stop_writing(conn);
       if (connection_tls_continue_handshake(or_conn) < 0) {
         /* Don't flush; connection is dead. */

Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c	2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/src/or/connection_or.c	2007-12-01 08:09:48 UTC (rev 12623)
@@ -583,13 +583,23 @@
 {
   int result;
   check_no_tls_errors();
-  result = tor_tls_handshake(conn->tls);
+ again:
+  if (conn->_base.state == OR_CONN_STATE_TLS_RENEGOTIATING)
+    result = tor_tls_renegotiate(conn->tls);
+  else
+    result = tor_tls_handshake(conn->tls);
   switch (result) {
     CASE_TOR_TLS_ERROR_ANY:
     log_info(LD_OR,"tls error [%s]. breaking connection.",
              tor_tls_err_to_string(result));
       return -1;
     case TOR_TLS_DONE:
+      if (!tor_tls_is_server(conn->tls) &&
+          !tor_tls_used_v1_handshake(conn->tls) &&
+          conn->_base.state == OR_CONN_STATE_TLS_HANDSHAKING) {
+        conn->_base.state = OR_CONN_STATE_TLS_RENEGOTIATING;
+        goto again;
+      }
       return connection_tls_finish_handshake(conn);
     case TOR_TLS_WANTWRITE:
       connection_start_writing(TO_CONN(conn));
@@ -652,16 +662,9 @@
   const char *safe_address =
     started_here ? conn->_base.address : safe_str(conn->_base.address);
   const char *conn_type = started_here ? "outgoing" : "incoming";
-  int has_cert = 0, has_identity = 0;
-  int v1 = (conn->link_proto == 1);
+  int has_cert = 0, has_identity=0;
 
   check_no_tls_errors();
-  if (v1) {
-    has_cert = tor_tls_peer_has_cert(conn->tls);
-  } else {
-    tor_assert(conn->handshake_state);
-    has_cert = !tor_digest_is_zero(conn->handshake_state->cert_id_digest);
-  }
   has_cert = tor_tls_peer_has_cert(conn->tls);
   if (started_here && !has_cert) {
     log_info(LD_PROTOCOL,"Tried connecting to router at %s:%d, but it didn't "
@@ -674,33 +677,26 @@
   }
   check_no_tls_errors();
 
-  if (v1) {
-    if (has_cert) {
-      int v = tor_tls_verify_v1(started_here?severity:LOG_INFO,
-                                conn->tls, &identity_rcvd);
-      if (started_here && v<0) {
-        log_fn(severity,LD_OR,"Tried connecting to router at %s:%d: It"
-               " has a cert but it's invalid. Closing.",
-               safe_address, conn->_base.port);
+  if (has_cert) {
+    int v = tor_tls_verify_v1(started_here?severity:LOG_INFO,
+                              conn->tls, &identity_rcvd);
+    if (started_here && v<0) {
+      log_fn(severity,LD_OR,"Tried connecting to router at %s:%d: It"
+             " has a cert but it's invalid. Closing.",
+             safe_address, conn->_base.port);
         return -1;
-      } else if (v<0) {
-        log_info(LD_PROTOCOL,"Incoming connection gave us an invalid cert "
-                 "chain; ignoring.");
-      } else {
-        log_debug(LD_OR,"The certificate seems to be valid on %s connection "
-                  "with %s:%d", conn_type, safe_address, conn->_base.port);
-      }
-      check_no_tls_errors();
+    } else if (v<0) {
+      log_info(LD_PROTOCOL,"Incoming connection gave us an invalid cert "
+               "chain; ignoring.");
+    } else {
+      log_debug(LD_OR,"The certificate seems to be valid on %s connection "
+                "with %s:%d", conn_type, safe_address, conn->_base.port);
     }
-  } else {
-    if (conn->handshake_state->authenticated &&
-        conn->handshake_state->identity_key) {
-      identity_rcvd = crypto_pk_dup_key(conn->handshake_state->identity_key);
-    }
+    check_no_tls_errors();
   }
 
   if (identity_rcvd) {
-    has_identity=1;
+    has_identity = 1;
     crypto_pk_get_digest(identity_rcvd, digest_rcvd_out);
     if (crypto_pk_cmp_keys(get_identity_key(), identity_rcvd)<0) {
       conn->circ_id_type = CIRC_ID_TYPE_LOWER;
@@ -759,6 +755,7 @@
   return 0;
 }
 
+#if 0
 /** DOCDOC */
 int
 connection_or_finish_or_handshake(or_connection_t *conn)
@@ -781,6 +778,7 @@
     return -1;
   return connection_or_set_state_open(conn);
 }
+#endif
 
 /** The tls handshake is finished.
  *

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/src/or/or.h	2007-12-01 08:09:48 UTC (rev 12623)
@@ -236,13 +236,15 @@
 #define OR_CONN_STATE_PROXY_READING 3
 /** State for a connection to an OR: SSL is handshaking, not done yet. */
 #define OR_CONN_STATE_TLS_HANDSHAKING 4
+/** DOCDOC */
+#define OR_CONN_STATE_TLS_RENEGOTIATING 5
 /** State for a connection to an OR: We're done with our SSL handshake, but we
  * haven't yet negotiated link protocol versions and finished authenticating.
  */
-#define OR_CONN_STATE_OR_HANDSHAKING 5
+#define OR_CONN_STATE_OR_HANDSHAKING 6
 /** State for a connection to an OR: Ready to send/receive cells. */
-#define OR_CONN_STATE_OPEN 6
-#define _OR_CONN_STATE_MAX 6
+#define OR_CONN_STATE_OPEN 7
+#define _OR_CONN_STATE_MAX 7
 
 #define _EXIT_CONN_STATE_MIN 1
 /** State for an exit connection: waiting for response from dns farm. */
@@ -924,6 +926,7 @@
                                   * connection, which half of the space should
                                   * we use? */
   unsigned int is_canonical:1; /**< DOCDOC */
+  unsigned int have_renegotiated:1; /**DOCDOC */
   uint8_t link_proto; /**< What protocol version are we using? 0 for
                        * "none negotiated yet." */
   uint16_t next_circ_id; /**< Which circ_id do we try to use next on
@@ -2775,7 +2778,9 @@
 int connection_or_flushed_some(or_connection_t *conn);
 int connection_or_finished_flushing(or_connection_t *conn);
 int connection_or_finished_connecting(or_connection_t *conn);
+#if 0
 int connection_or_finish_or_handshake(or_connection_t *conn);
+#endif
 
 or_connection_t *connection_or_connect(uint32_t addr, uint16_t port,
                                     const char *id_digest);



More information about the tor-commits mailing list