]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Completely remove support for the v2 link handshake
authorNick Mathewson <nickm@torproject.org>
Thu, 24 Apr 2025 18:06:12 +0000 (14:06 -0400)
committerNick Mathewson <nickm@torproject.org>
Thu, 24 Apr 2025 18:35:17 +0000 (14:35 -0400)
The v2 link handshake was one of the silliest things we ever did:
in an attempt to avoid sending our funny-looking certs back and forth,
we would first negotiate with a dummy set of certs and ciphers,
and then renegotiate with the ciphersuites we _really_ wanted.

We removed client-side support for this handshake back in
0.2.8.1-alpha, with ticket 11150.

13 files changed:
src/core/mainloop/connection.c
src/core/or/channeltls.c
src/core/or/connection_or.c
src/core/or/connection_or.h
src/core/or/orconn_event.h
src/core/or/protover.c
src/feature/control/btrack_orconn_cevent.c
src/lib/tls/tortls.h
src/lib/tls/tortls_nss.c
src/lib/tls/tortls_openssl.c
src/lib/tls/tortls_st.h
src/test/test_protover.c
src/test/test_tortls.c

index 5a769f38bec6f45e5c1a4aee47f3c401af37df5b..5acb714b9e7c160135ab957a9738afe6169fab11 100644 (file)
@@ -314,12 +314,8 @@ conn_state_to_string(int type, int state)
         case OR_CONN_STATE_CONNECTING: return "connect()ing";
         case OR_CONN_STATE_PROXY_HANDSHAKING: return "handshaking (proxy)";
         case OR_CONN_STATE_TLS_HANDSHAKING: return "handshaking (TLS)";
-        case OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING:
-          return "renegotiating (TLS, v2 handshake)";
         case OR_CONN_STATE_TLS_SERVER_RENEGOTIATING:
           return "waiting for renegotiation or V3 handshake";
-        case OR_CONN_STATE_OR_HANDSHAKING_V2:
-          return "handshaking (Tor, v2 handshake)";
         case OR_CONN_STATE_OR_HANDSHAKING_V3:
           return "handshaking (Tor, v3 handshake)";
         case OR_CONN_STATE_OPEN: return "open";
@@ -4163,8 +4159,7 @@ connection_buf_read_from_socket(connection_t *conn, ssize_t *max_to_read,
     int pending;
     or_connection_t *or_conn = TO_OR_CONN(conn);
     size_t initial_size;
-    if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING ||
-        conn->state == OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING) {
+    if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING) {
       /* continue handshaking even if global token bucket is empty */
       return connection_tls_continue_handshake(or_conn);
     }
@@ -4206,6 +4201,7 @@ connection_buf_read_from_socket(connection_t *conn, ssize_t *max_to_read,
            * again.  Stop waiting for write events now, or else we'll
            * busy-loop until data arrives for us to read.
            * XXX: remove this when v2 handshakes support is dropped. */
+          // XXXX Try to make sense of what is going on here.
           connection_stop_writing(conn);
           if (!connection_is_reading(conn))
             connection_start_reading(conn);
@@ -4493,8 +4489,7 @@ connection_handle_write_impl(connection_t *conn, int force)
       conn->state > OR_CONN_STATE_PROXY_HANDSHAKING) {
     or_connection_t *or_conn = TO_OR_CONN(conn);
     size_t initial_size;
-    if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING ||
-        conn->state == OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING) {
+    if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING) {
       connection_stop_writing(conn);
       if (connection_tls_continue_handshake(or_conn) < 0) {
         /* Don't flush; connection is dead. */
index a14b1991c2476e3b8df8f0a84f94f3e1e2f35c21..c8e62cbaf72895ced58a5cae69f706778d49c5be 100644 (file)
@@ -1238,26 +1238,6 @@ channel_tls_handle_var_cell(var_cell_t *var_cell, or_connection_t *conn)
     return;
 
   switch (TO_CONN(conn)->state) {
-    case OR_CONN_STATE_OR_HANDSHAKING_V2:
-      if (var_cell->command != CELL_VERSIONS) {
-        log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
-               "Received a cell with command %d in unexpected "
-               "orconn state \"%s\" [%d], channel state \"%s\" [%d]; "
-               "closing the connection.",
-               (int)(var_cell->command),
-               conn_state_to_string(CONN_TYPE_OR, TO_CONN(conn)->state),
-               TO_CONN(conn)->state,
-               channel_state_to_string(TLS_CHAN_TO_BASE(chan)->state),
-               (int)(TLS_CHAN_TO_BASE(chan)->state));
-        /*
-         * The code in connection_or.c will tell channel_t to close for
-         * error; it will go to CHANNEL_STATE_CLOSING, and then to
-         * CHANNEL_STATE_ERROR when conn is closed.
-         */
-        connection_or_close_for_error(conn, 0);
-        return;
-      }
-      break;
     case OR_CONN_STATE_TLS_HANDSHAKING:
       /* If we're using bufferevents, it's entirely possible for us to
        * notice "hey, data arrived!" before we notice "hey, the handshake
@@ -1443,7 +1423,6 @@ enter_v3_handshake_with_cell(var_cell_t *cell, channel_tls_t *chan)
            "Received a cell while TLS-handshaking, not in "
            "OR_HANDSHAKING_V3, on a connection we originated.");
   }
-  connection_or_block_renegotiation(chan->conn);
   connection_or_change_state(chan->conn, OR_CONN_STATE_OR_HANDSHAKING_V3);
   if (connection_init_or_handshake_state(chan->conn, started_here) < 0) {
     connection_or_close_for_error(chan->conn, 0);
@@ -1494,7 +1473,6 @@ channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan)
   }
   switch (chan->conn->base_.state)
     {
-    case OR_CONN_STATE_OR_HANDSHAKING_V2:
     case OR_CONN_STATE_OR_HANDSHAKING_V3:
       break;
     case OR_CONN_STATE_TLS_HANDSHAKING:
@@ -1537,15 +1515,6 @@ channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan)
            "handshake. Closing connection.");
     connection_or_close_for_error(chan->conn, 0);
     return;
-  } else if (highest_supported_version != 2 &&
-             chan->conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V2) {
-    /* XXXX This should eventually be a log_protocol_warn */
-    log_fn(LOG_WARN, LD_OR,
-           "Negotiated link with non-2 protocol after doing a v2 TLS "
-           "handshake with %s. Closing connection.",
-           connection_describe_peer(TO_CONN(chan->conn)));
-    connection_or_close_for_error(chan->conn, 0);
-    return;
   }
 
   rep_hist_note_negotiated_link_proto(highest_supported_version, started_here);
@@ -1733,8 +1702,7 @@ can_process_netinfo_cell(const channel_tls_t *chan)
   }
 
   /* Can't process a NETINFO cell if the connection is not handshaking. */
-  if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V2 &&
-      chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3) {
+  if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3) {
     log_fn(LOG_PROTOCOL_WARN, LD_OR,
            "Received a NETINFO cell on non-handshaking connection; dropping.");
     return false;
index 77a8a35d32cf7705b94e46d7932e4e4381880e5c..f406f2986f17710845ae072f5af00187de7ef6cb 100644 (file)
 
 #include "core/or/orconn_event.h"
 
-static int connection_tls_finish_handshake(or_connection_t *conn);
 static int connection_or_launch_v3_or_handshake(or_connection_t *conn);
 static int connection_or_process_cells_from_inbuf(or_connection_t *conn);
-static int connection_or_check_valid_tls_handshake(or_connection_t *conn,
-                                                   int started_here,
-                                                   char *digest_rcvd_out);
-
-static void connection_or_tls_renegotiated_cb(tor_tls_t *tls, void *_conn);
 
 static unsigned int
 connection_or_is_bad_for_new_circs(or_connection_t *or_conn);
@@ -602,9 +596,7 @@ connection_or_process_inbuf(or_connection_t *conn)
       }
 
       return ret;
-    case OR_CONN_STATE_TLS_SERVER_RENEGOTIATING:
     case OR_CONN_STATE_OPEN:
-    case OR_CONN_STATE_OR_HANDSHAKING_V2:
     case OR_CONN_STATE_OR_HANDSHAKING_V3:
       return connection_or_process_cells_from_inbuf(conn);
     default:
@@ -708,7 +700,6 @@ connection_or_finished_flushing(or_connection_t *conn)
       }
       break;
     case OR_CONN_STATE_OPEN:
-    case OR_CONN_STATE_OR_HANDSHAKING_V2:
     case OR_CONN_STATE_OR_HANDSHAKING_V3:
       break;
     default:
@@ -1690,35 +1681,6 @@ connection_tls_start_handshake,(or_connection_t *conn, int receiving))
   return 0;
 }
 
-/** Block all future attempts to renegotiate on 'conn' */
-void
-connection_or_block_renegotiation(or_connection_t *conn)
-{
-  tor_tls_t *tls = conn->tls;
-  if (!tls)
-    return;
-  tor_tls_set_renegotiate_callback(tls, NULL, NULL);
-  tor_tls_block_renegotiation(tls);
-}
-
-/** Invoked on the server side from inside tor_tls_read() when the server
- * gets a successful TLS renegotiation from the client. */
-static void
-connection_or_tls_renegotiated_cb(tor_tls_t *tls, void *_conn)
-{
-  or_connection_t *conn = _conn;
-  (void)tls;
-
-  /* Don't invoke this again. */
-  connection_or_block_renegotiation(conn);
-
-  if (connection_tls_finish_handshake(conn) < 0) {
-    /* XXXX_TLS double-check that it's ok to do this from inside read. */
-    /* XXXX_TLS double-check that this verifies certificates. */
-    connection_or_close_for_error(conn, 0);
-  }
-}
-
 /** Move forward with the tls handshake. If it finishes, hand
  * <b>conn</b> to connection_tls_finish_handshake().
  *
@@ -1747,21 +1709,16 @@ connection_tls_continue_handshake(or_connection_t *conn)
           tor_assert(conn->base_.state == OR_CONN_STATE_TLS_HANDSHAKING);
           return connection_or_launch_v3_or_handshake(conn);
         } else {
-          /* v2/v3 handshake, but we are not a client. */
+          /* v3 handshake, but we are not a client. */
           log_debug(LD_OR, "Done with initial SSL handshake (server-side). "
-                           "Expecting renegotiation or VERSIONS cell");
-          tor_tls_set_renegotiate_callback(conn->tls,
-                                           connection_or_tls_renegotiated_cb,
-                                           conn);
+                           "Expecting VERSIONS cell");
           connection_or_change_state(conn,
-              OR_CONN_STATE_TLS_SERVER_RENEGOTIATING);
+                        OR_CONN_STATE_TLS_SERVER_RENEGOTIATING);
           connection_stop_writing(TO_CONN(conn));
           connection_start_reading(TO_CONN(conn));
           return 0;
         }
       }
-      tor_assert(tor_tls_is_server(conn->tls));
-      return connection_tls_finish_handshake(conn);
     case TOR_TLS_WANTWRITE:
       connection_start_writing(TO_CONN(conn));
       log_debug(LD_OR,"wanted write");
@@ -1792,102 +1749,6 @@ connection_or_nonopen_was_started_here(or_connection_t *conn)
   return !tor_tls_is_server(conn->tls);
 }
 
-/** <b>Conn</b> just completed its handshake. Return 0 if all is well, and
- * return -1 if they are lying, broken, or otherwise something is wrong.
- *
- * If we initiated this connection (<b>started_here</b> is true), make sure
- * the other side sent a correctly formed certificate. If I initiated the
- * connection, make sure it's the right relay by checking the certificate.
- *
- * Otherwise (if we _didn't_ initiate this connection), it's okay for
- * the certificate to be weird or absent.
- *
- * If we return 0, and the certificate is as expected, write a hash of the
- * identity key into <b>digest_rcvd_out</b>, which must have DIGEST_LEN
- * space in it.
- * If the certificate is invalid or missing on an incoming connection,
- * we return 0 and set <b>digest_rcvd_out</b> to DIGEST_LEN NUL bytes.
- * (If we return -1, the contents of this buffer are undefined.)
- *
- * As side effects,
- * 1) Set conn->circ_id_type according to tor-spec.txt.
- * 2) If we're an authdirserver and we initiated the connection: drop all
- *    descriptors that claim to be on that IP/port but that aren't
- *    this relay; and note that this relay is reachable.
- * 3) If this is a bridge and we didn't configure its identity
- *    fingerprint, remember the keyid we just learned.
- */
-static int
-connection_or_check_valid_tls_handshake(or_connection_t *conn,
-                                        int started_here,
-                                        char *digest_rcvd_out)
-{
-  crypto_pk_t *identity_rcvd=NULL;
-  const or_options_t *options = get_options();
-  int severity = server_mode(options) ? LOG_PROTOCOL_WARN : LOG_WARN;
-  const char *conn_type = started_here ? "outgoing" : "incoming";
-  int has_cert = 0;
-
-  check_no_tls_errors();
-  has_cert = tor_tls_peer_has_cert(conn->tls);
-  if (started_here && !has_cert) {
-    log_info(LD_HANDSHAKE,"Tried connecting to router at %s, but it didn't "
-             "send a cert! Closing.",
-             connection_describe_peer(TO_CONN(conn)));
-    return -1;
-  } else if (!has_cert) {
-    log_debug(LD_HANDSHAKE,"Got incoming connection with no certificate. "
-              "That's ok.");
-  }
-  check_no_tls_errors();
-
-  if (has_cert) {
-    int v = tor_tls_verify(started_here?severity:LOG_INFO,
-                           conn->tls, time(NULL), &identity_rcvd);
-    if (started_here && v<0) {
-      log_fn(severity,LD_HANDSHAKE,"Tried connecting to router at %s: It"
-             " has a cert but it's invalid. Closing.",
-             connection_describe_peer(TO_CONN(conn)));
-        return -1;
-    } else if (v<0) {
-      log_info(LD_HANDSHAKE,"Incoming connection gave us an invalid cert "
-               "chain; ignoring.");
-    } else {
-      log_debug(LD_HANDSHAKE,
-                "The certificate seems to be valid on %s connection "
-                "with %s", conn_type,
-                connection_describe_peer(TO_CONN(conn)));
-    }
-    check_no_tls_errors();
-  }
-
-  if (identity_rcvd) {
-    if (crypto_pk_get_digest(identity_rcvd, digest_rcvd_out) < 0) {
-      crypto_pk_free(identity_rcvd);
-      return -1;
-    }
-  } else {
-    memset(digest_rcvd_out, 0, DIGEST_LEN);
-  }
-
-  tor_assert(conn->chan);
-  channel_set_circid_type(TLS_CHAN_TO_BASE(conn->chan), identity_rcvd, 1);
-
-  crypto_pk_free(identity_rcvd);
-
-  if (started_here) {
-    /* A TLS handshake can't teach us an Ed25519 ID, so we set it to NULL
-     * here. */
-    log_debug(LD_HANDSHAKE, "Calling client_learned_peer_id from "
-              "check_valid_tls_handshake");
-    return connection_or_client_learned_peer_id(conn,
-                                        (const uint8_t*)digest_rcvd_out,
-                                        NULL);
-  }
-
-  return 0;
-}
-
 /** Called when we (as a connection initiator) have definitively,
  * authenticatedly, learned that ID of the Tor instance on the other
  * side of <b>conn</b> is <b>rsa_peer_id</b> and optionally <b>ed_peer_id</b>.
@@ -2079,50 +1940,6 @@ connection_or_client_used(or_connection_t *conn)
   } else return 0;
 }
 
-/** The v1/v2 TLS handshake is finished.
- *
- * Make sure we are happy with the peer we just handshaked with.
- *
- * If they initiated the connection, make sure they're not already connected,
- * then initialize conn from the information in router.
- *
- * If all is successful, call circuit_n_conn_done() to handle events
- * that have been pending on the <tls handshake completion. Also set the
- * directory to be dirty (only matters if I'm an authdirserver).
- *
- * If this is a v2 TLS handshake, send a versions cell.
- */
-static int
-connection_tls_finish_handshake(or_connection_t *conn)
-{
-  char digest_rcvd[DIGEST_LEN];
-  int started_here = connection_or_nonopen_was_started_here(conn);
-
-  tor_assert(!started_here);
-
-  log_debug(LD_HANDSHAKE,"%s tls handshake on %s done, using "
-            "ciphersuite %s. verifying.",
-            started_here?"outgoing":"incoming",
-            connection_describe_peer(TO_CONN(conn)),
-            tor_tls_get_ciphersuite_name(conn->tls));
-
-  if (connection_or_check_valid_tls_handshake(conn, started_here,
-                                              digest_rcvd) < 0)
-    return -1;
-
-  circuit_build_times_network_is_live(get_circuit_build_times_mutable());
-
-  {
-    connection_or_change_state(conn, OR_CONN_STATE_OR_HANDSHAKING_V2);
-    if (connection_init_or_handshake_state(conn, started_here) < 0)
-      return -1;
-    connection_or_init_conn_from_address(conn, &conn->base_.addr,
-                                         conn->base_.port, digest_rcvd,
-                                         NULL, 0);
-    return connection_or_send_versions(conn, 0);
-  }
-}
-
 /**
  * Called as client when initial TLS handshake is done, and we notice
  * that we got a v3-handshake signalling certificate from the server.
@@ -2419,8 +2236,8 @@ connection_or_process_cells_from_inbuf(or_connection_t *conn)
   }
 }
 
-/** Array of recognized link protocol versions. */
-static const uint16_t or_protocol_versions[] = { 1, 2, 3, 4, 5 };
+/** Array of supported link protocol versions. */
+static const uint16_t or_protocol_versions[] = { 3, 4, 5 };
 /** Number of versions in <b>or_protocol_versions</b>. */
 static const int n_or_protocol_versions =
   (int)( sizeof(or_protocol_versions)/sizeof(uint16_t) );
index 26608176d3ff0b14774ba4688138b5c00aa2a3e7..f9f4ec02b1e149874e10394d1744ae0daa184896 100644 (file)
@@ -24,7 +24,6 @@ void connection_or_clear_identity(or_connection_t *conn);
 void connection_or_clear_identity_map(void);
 void clear_broken_connection_map(int disable);
 
-void connection_or_block_renegotiation(or_connection_t *conn);
 int connection_or_reached_eof(or_connection_t *conn);
 int connection_or_process_inbuf(or_connection_t *conn);
 ssize_t connection_or_num_cells_writeable(or_connection_t *conn);
index 7e1c679e324e307e51bc41c3da372360b2f0cab7..93034a7c974418fc97df6a26b3cdade4ac195cf4 100644 (file)
 /** State for an OR connection client: SSL is handshaking, not done
  * yet. */
 #define OR_CONN_STATE_TLS_HANDSHAKING 3
-/** State for a connection to an OR: We're doing a second SSL handshake for
- * renegotiation purposes. (V2 handshake only.) */
-#define OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING 4
 /** State for a connection at an OR: We're waiting for the client to
  * renegotiate (to indicate a v2 handshake) or send a versions cell (to
  * indicate a v3 handshake) */
+// XXXX Rename.
 #define OR_CONN_STATE_TLS_SERVER_RENEGOTIATING 5
-/** State for an OR connection: We're done with our SSL handshake, we've done
- * renegotiation, but we haven't yet negotiated link protocol versions and
- * sent a netinfo cell. */
-#define OR_CONN_STATE_OR_HANDSHAKING_V2 6
 /** State for an OR connection: We're done with our SSL handshake, but we
  * haven't yet negotiated link protocol versions, done a V3 handshake, and
  * sent a netinfo cell. */
index aca4ef31a2ccd302047d359ced843050608aa11e..0fefd4dc857fb5d59bf1aa73d832f6bef5463e16 100644 (file)
@@ -395,7 +395,7 @@ protocol_list_supports_protocol_or_later(const char *list,
 #define PR_HSDIR_V     "2"
 #define PR_HSINTRO_V   "4-5"
 #define PR_HSREND_V    "1-2"
-#define PR_LINK_V      "1-5"
+#define PR_LINK_V      "3-5"
 #define PR_LINKAUTH_V  "3"
 #define PR_MICRODESC_V "1-3"
 #define PR_PADDING_V   "2"
index 525f4f5d0d4128d4079d7c39dfdebdcba8e14878..36490c9061ec8aef57d94a18a8699a6891d038f1 100644 (file)
@@ -86,8 +86,6 @@ bto_cevent_anyconn(const bt_orconn_t *bto)
   case OR_CONN_STATE_TLS_HANDSHAKING:
     control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DONE, 0);
     break;
-  case OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING:
-  case OR_CONN_STATE_OR_HANDSHAKING_V2:
   case OR_CONN_STATE_OR_HANDSHAKING_V3:
     control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
     break;
@@ -140,8 +138,6 @@ bto_cevent_apconn(const bt_orconn_t *bto)
   case OR_CONN_STATE_TLS_HANDSHAKING:
     control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_DONE, 0);
     break;
-  case OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING:
-  case OR_CONN_STATE_OR_HANDSHAKING_V2:
   case OR_CONN_STATE_OR_HANDSHAKING_V3:
     control_event_bootstrap(BOOTSTRAP_STATUS_AP_HANDSHAKE, 0);
     break;
index 3186df5b29cd82654c3d13e0121b01cbbc568fdc..9cf25ae28d55d39676211d7f02fa013583c1d834 100644 (file)
@@ -89,9 +89,6 @@ void tor_tls_context_decref(tor_tls_context_t *ctx);
 tor_tls_context_t *tor_tls_context_get(int is_server);
 tor_tls_t *tor_tls_new(tor_socket_t sock, int is_server);
 void tor_tls_set_logged_address(tor_tls_t *tls, const char *address);
-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_release_socket(tor_tls_t *tls);
 void tor_tls_free_(tor_tls_t *tls);
@@ -104,9 +101,6 @@ int tor_tls_verify(int severity, tor_tls_t *tls, time_t now,
 MOCK_DECL(int, tor_tls_read, (tor_tls_t *tls, char *cp, size_t len));
 int tor_tls_write(tor_tls_t *tls, const char *cp, size_t n);
 int tor_tls_handshake(tor_tls_t *tls);
-int tor_tls_finish_handshake(tor_tls_t *tls);
-void tor_tls_unblock_renegotiation(tor_tls_t *tls);
-void tor_tls_block_renegotiation(tor_tls_t *tls);
 int tor_tls_get_pending_bytes(tor_tls_t *tls);
 size_t tor_tls_get_forced_write_size(tor_tls_t *tls);
 
@@ -120,7 +114,6 @@ int tor_tls_get_buffer_sizes(tor_tls_t *tls,
 MOCK_DECL(double, tls_get_write_overhead_ratio, (void));
 
 int tor_tls_get_num_server_handshakes(tor_tls_t *tls);
-int tor_tls_server_got_renegotiate(tor_tls_t *tls);
 MOCK_DECL(int,tor_tls_cert_matches_key,(const tor_tls_t *tls,
                                         const struct tor_x509_cert_t *cert));
 MOCK_DECL(int,tor_tls_export_key_material,(
index dec893c1ca6c8bd4e1a5c482c3daad4d62d717bb..051e9b8f34fef19962efaa7eb78a1d8dae900195 100644 (file)
@@ -464,18 +464,6 @@ tor_tls_new(tor_socket_t sock, int is_server)
   return tls;
 }
 
-void
-tor_tls_set_renegotiate_callback(tor_tls_t *tls,
-                                 void (*cb)(tor_tls_t *, void *arg),
-                                 void *arg)
-{
-  tor_assert(tls);
-  (void)cb;
-  (void)arg;
-
-  /* We don't support renegotiation-based TLS with NSS. */
-}
-
 /**
  * Tell the TLS library that the underlying socket for <b>tls</b> has been
  * closed, and the library should not attempt to free that socket itself.
@@ -636,20 +624,6 @@ tor_tls_finish_handshake(tor_tls_t *tls)
   return TOR_TLS_DONE;
 }
 
-void
-tor_tls_unblock_renegotiation(tor_tls_t *tls)
-{
-  tor_assert(tls);
-  /* We don't support renegotiation with NSS. */
-}
-
-void
-tor_tls_block_renegotiation(tor_tls_t *tls)
-{
-  tor_assert(tls);
-  /* We don't support renegotiation with NSS. */
-}
-
 int
 tor_tls_get_pending_bytes(tor_tls_t *tls)
 {
@@ -713,13 +687,6 @@ tls_get_write_overhead_ratio, (void))
   return 0.95;
 }
 
-int
-tor_tls_server_got_renegotiate(tor_tls_t *tls)
-{
-  tor_assert(tls);
-  return 0; /* We don't support renegotiation with NSS */
-}
-
 MOCK_IMPL(int,
 tor_tls_cert_matches_key,(const tor_tls_t *tls,
                           const struct tor_x509_cert_t *cert))
index 68dadac1040671c16785742cc82c09dde596d0f1..e9231e028f4c1eacb67760f8e7bbaa2c5d5b7f04 100644 (file)
@@ -88,17 +88,6 @@ ENABLE_GCC_WARNING("-Wredundant-decls")
 #define DISABLE_SSL3_HANDSHAKE
 #endif /* OPENSSL_VERSION_NUMBER <  OPENSSL_V(1,0,0,'f') */
 
-/* We redefine these so that we can run correctly even if the vendor gives us
- * a version of OpenSSL that does not match its header files.  (Apple: I am
- * looking at you.)
- */
-#ifndef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
-#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L
-#endif
-#ifndef SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
-#define SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x0010
-#endif
-
 /** Set to true iff openssl bug 7712 has been detected. */
 static int openssl_bug_7712_is_present = 0;
 
@@ -611,13 +600,7 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime,
   SSL_CTX_set_options(result->ctx,
                       SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
 #endif
-  /* Yes, we know what we are doing here.  No, we do not treat a renegotiation
-   * as authenticating any earlier-received data.
-   */
-  {
-    SSL_CTX_set_options(result->ctx,
-                        SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
-  }
+  SSL_CTX_set_options(result->ctx, SSL_OP_NO_RENEGOTIATION);
 
   /* Don't actually allow compression; it uses RAM and time, it makes TLS
    * vulnerable to CRIME-style attacks, and most of the data we transmit over
@@ -740,7 +723,7 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime,
                        always_accept_verify_cb);
   } else {
     /* Don't send a certificate request at all if we're not a client. */
-    SSL_set_verify((SSL*) ssl, SSL_VERIFY_NONE, NULL);
+    SSL_CTX_set_verify(result->ctx, SSL_VERIFY_NONE, NULL);
   }
   /* let us realloc bufs that we're writing from */
   SSL_CTX_set_mode(result->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
@@ -983,59 +966,6 @@ tor_tls_classify_client_ciphers(const SSL *ssl,
   return res;
 }
 
-/** 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>
- */
-void
-tor_tls_server_info_callback(const SSL *ssl, int type, int val)
-{
-  tor_tls_t *tls;
-  (void) val;
-
-  IF_BUG_ONCE(ssl == NULL) {
-    return; // LCOV_EXCL_LINE
-  }
-
-  tor_tls_debug_state_callback(ssl, type, val);
-
-  if (type != SSL_CB_ACCEPT_LOOP)
-    return;
-
-  OSSL_HANDSHAKE_STATE ssl_state = SSL_get_state(ssl);
-  if (! STATE_IS_SW_SERVER_HELLO(ssl_state))
-    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;
-  } else {
-    log_warn(LD_BUG, "Couldn't look up the tls for an SSL*. How odd!");
-    return;
-  }
-
-  /* Now check the cipher list. */
-  {
-    if (tls->wasV2Handshake)
-      return; /* We already turned this stuff off for the first handshake;
-               * This is a renegotiation. */
-
-    /* Yes, we're casting away the const from ssl.  This is very naughty of us.
-     * Let's hope openssl doesn't notice! */
-
-    if (tls) {
-      tls->wasV2Handshake = 1;
-    } else {
-      /* LCOV_EXCL_START this line is not reachable */
-      log_warn(LD_BUG, "Couldn't look up the tls for an SSL*. How odd!");
-      /* LCOV_EXCL_STOP */
-    }
-  }
-}
-
 /** Callback to get invoked on a server after we've read the list of ciphers
  * the client supports, but before we pick our own ciphersuite.
  *
@@ -1151,11 +1081,8 @@ tor_tls_new(tor_socket_t 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);
   }
-  if (isServer) {
-    SSL_set_info_callback(result->ssl, tor_tls_server_info_callback);
-  } else {
-    SSL_set_info_callback(result->ssl, tor_tls_debug_state_callback);
-  }
+
+  SSL_set_info_callback(result->ssl, tor_tls_debug_state_callback);
 
   if (isServer)
     tor_tls_setup_session_secret_cb(result);
@@ -1169,51 +1096,6 @@ tor_tls_new(tor_socket_t sock, int isServer)
   return result;
 }
 
-/** Set <b>cb</b> to be called with argument <b>arg</b> whenever <b>tls</b>
- * next gets a client-side renegotiate in the middle of a read.  Do not
- * invoke this function until <em>after</em> initial handshaking is done!
- */
-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;
-  tls->got_renegotiate = 0;
-  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);
-  }
-}
-
-/** If this version of openssl requires it, turn on renegotiation on
- * <b>tls</b>.
- */
-void
-tor_tls_unblock_renegotiation(tor_tls_t *tls)
-{
-  /* Yes, we know what we are doing here.  No, we do not treat a renegotiation
-   * as authenticating any earlier-received data. */
-  SSL_set_options(tls->ssl,
-                  SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
-}
-
-/** If this version of openssl supports it, turn off renegotiation on
- * <b>tls</b>.  (Our protocol never requires this for security, but it's nice
- * to use belt-and-suspenders here.)
- */
-void
-tor_tls_block_renegotiation(tor_tls_t *tls)
-{
-#ifdef SUPPORT_UNSAFE_RENEGOTIATION_FLAG
-  tls->ssl->s3->flags &= ~SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
-#else
-  (void) tls;
-#endif
-}
-
 /**
  * Tell the TLS library that the underlying socket for <b>tls</b> has been
  * closed, and the library should not attempt to free that socket itself.
@@ -1263,13 +1145,6 @@ tor_tls_read,(tor_tls_t *tls, char *cp, size_t len))
   tor_assert(len<INT_MAX);
   r = SSL_read(tls->ssl, cp, (int)len);
   if (r > 0) {
-    if (tls->got_renegotiate) {
-      /* Renegotiation happened! */
-      log_info(LD_NET, "Got a TLS renegotiation from %s", ADDR(tls));
-      if (tls->negotiated_callback)
-        tls->negotiated_callback(tls, tls->callback_arg);
-      tls->got_renegotiate = 0;
-    }
     return r;
   }
   err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading", LOG_DEBUG, LD_NET);
@@ -1357,9 +1232,7 @@ tor_tls_handshake(tor_tls_t *tls)
   if (oldstate != newstate)
     log_debug(LD_HANDSHAKE, "After call, %p was in state %s",
               tls, SSL_state_string_long(tls->ssl));
-  /* We need to call this here and not earlier, since OpenSSL has a penchant
-   * for clearing its flags when you say accept or connect. */
-  tor_tls_unblock_renegotiation(tls);
+
   r = tor_tls_get_error(tls,r,0, "handshaking", LOG_INFO, LD_HANDSHAKE);
   if (ERR_peek_error() != 0) {
     tls_log_errors(tls, tls->isServer ? LOG_INFO : LOG_WARN, LD_HANDSHAKE,
@@ -1368,53 +1241,10 @@ tor_tls_handshake(tor_tls_t *tls)
   }
   if (r == TOR_TLS_DONE) {
     tls->state = TOR_TLS_ST_OPEN;
-    return tor_tls_finish_handshake(tls);
   }
   return r;
 }
 
-/** Perform the final part of the initial TLS handshake on <b>tls</b>.  This
- * should be called for the first handshake only: it determines whether the v1
- * or the v2 handshake was used, and adjusts things for the renegotiation
- * handshake as appropriate.
- *
- * tor_tls_handshake() calls this on its own; you only need to call this if
- * bufferevent is doing the handshake for you.
- */
-int
-tor_tls_finish_handshake(tor_tls_t *tls)
-{
-  int r = TOR_TLS_DONE;
-  check_no_tls_errors();
-  if (tls->isServer) {
-    SSL_set_info_callback(tls->ssl, NULL);
-    SSL_set_verify(tls->ssl, SSL_VERIFY_PEER, always_accept_verify_cb);
-    SSL_clear_mode(tls->ssl, SSL_MODE_NO_AUTO_CHAIN);
-    {
-      /* This check is redundant, but back when we did it in the callback,
-       * we might have not been able to look up the tor_tls_t if the code
-       * was buggy.  Fixing that. */
-      if (!tls->wasV2Handshake) {
-        log_warn(LD_BUG, "For some reason, wasV2Handshake didn't"
-                 " get set. Fixing that.");
-      }
-      tls->wasV2Handshake = 1;
-      log_debug(LD_HANDSHAKE, "Completed V2 TLS handshake with client; waiting"
-                " for renegotiation.");
-    }
-  } else {
-    /* Client-side */
-    tls->wasV2Handshake = 1;
-    /* XXXX this can move, probably? -NM */
-    if (SSL_set_cipher_list(tls->ssl, SERVER_CIPHER_LIST) == 0) {
-      tls_log_errors(NULL, LOG_WARN, LD_HANDSHAKE, "re-setting ciphers");
-      r = TOR_TLS_ERROR_MISC;
-    }
-  }
-  tls_log_errors(NULL, LOG_WARN, LD_NET, "finishing the handshake");
-  return r;
-}
-
 /** Return true iff this TLS connection is authenticated.
  */
 int
@@ -1587,14 +1417,6 @@ check_no_tls_errors_(const char *fname, int line)
   tls_log_errors(NULL, LOG_WARN, LD_NET, NULL);
 }
 
-/** Return true iff the server TLS connection <b>tls</b> got the renegotiation
- * request it was waiting for. */
-int
-tor_tls_server_got_renegotiate(tor_tls_t *tls)
-{
-  return tls->got_renegotiate;
-}
-
 /** Using the RFC5705 key material exporting construction, and the
  * provided <b>context</b> (<b>context_len</b> bytes long) and
  * <b>label</b> (a NUL-terminated string), compute a 32-byte secret in
index b27e73b15f8678620674efbbce1030e0dd42aebb..a8a50daa74b7e878a231f9137f84a374b5255ea6 100644 (file)
@@ -49,13 +49,6 @@ struct tor_tls_t {
                                        * depending on which operations
                                        * have completed successfully. */
   unsigned int isServer:1; /**< True iff this is a server-side connection */
-  unsigned int wasV2Handshake:1; /**< True iff the original handshake for
-                                  * this connection used the updated version
-                                  * of the connection protocol (client sends
-                                  * different cipher list, server sends only
-                                  * one certificate). */
-  /** True iff we should call negotiated_callback when we're done reading. */
-  unsigned int got_renegotiate:1;
 #ifdef ENABLE_OPENSSL
   /** Return value from tor_tls_classify_client_ciphers, or 0 if we haven't
    * called that function yet. */
index 9a10cf649fec655cb952033fd0ed0b54101b5316..f86921feba1c1051ca27eef805134ef1d54fe314 100644 (file)
@@ -219,15 +219,15 @@ test_protover_all_supported(void *arg)
   tt_str_op(msg, OP_EQ, "Link=6-60");
   tor_free(msg);
   tt_assert(! protover_all_supported("Link=1-3,50-63", &msg));
-  tt_str_op(msg, OP_EQ, "Link=50-63");
+  tt_str_op(msg, OP_EQ, "Link=1-2,50-63");
   tor_free(msg);
   tt_assert(! protover_all_supported("Link=1-3,5-12", &msg));
-  tt_str_op(msg, OP_EQ, "Link=6-12");
+  tt_str_op(msg, OP_EQ, "Link=1-2,6-12");
   tor_free(msg);
 
   /* Mix of protocols we do support and some we don't, where the protocols
    * we do support have some versions we don't support. */
-  tt_assert(! protover_all_supported("Link=1-3,5-12 Quokka=40-41", &msg));
+  tt_assert(! protover_all_supported("Link=3,5-12 Quokka=40-41", &msg));
   tt_str_op(msg, OP_EQ, "Link=6-12 Quokka=40-41");
   tor_free(msg);
 
index 884b93898182a7f015b8eebfdd163a155195754b..9c27b3f95ae0db7937fc81720fed68f8b18df100 100644 (file)
@@ -327,23 +327,6 @@ test_tortls_get_forced_write_size(void *ignored)
  done:
   tor_free(tls);
 }
-
-static void
-test_tortls_server_got_renegotiate(void *ignored)
-{
-  (void)ignored;
-  int ret;
-  tor_tls_t *tls;
-
-  tls = tor_malloc_zero(sizeof(tor_tls_t));
-
-  tls->got_renegotiate = 1;
-  ret = tor_tls_server_got_renegotiate(tls);
-  tt_int_op(ret, OP_EQ, 1);
-
- done:
-  tor_free(tls);
-}
 #endif /* defined(ENABLE_OPENSSL) */
 
 static void
@@ -594,7 +577,6 @@ struct testcase_t tortls_tests[] = {
 #ifdef ENABLE_OPENSSL
   LOCAL_TEST_CASE(tor_tls_get_error, 0),
   LOCAL_TEST_CASE(get_forced_write_size, 0),
-  LOCAL_TEST_CASE(server_got_renegotiate, 0),
 #endif /* defined(ENABLE_OPENSSL) */
   LOCAL_TEST_CASE(evaluate_ecgroup_for_tls, 0),
   LOCAL_TEST_CASE(double_init, TT_FORK),