[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r12385: Function to process link auth cells; stub function for cert (in tor/trunk: . doc src/or)



Author: nickm
Date: 2007-11-05 13:15:56 -0500 (Mon, 05 Nov 2007)
New Revision: 12385

Modified:
   tor/trunk/
   tor/trunk/doc/TODO
   tor/trunk/src/or/command.c
   tor/trunk/src/or/connection_or.c
   tor/trunk/src/or/or.h
Log:
 r16414@catbus:  nickm | 2007-11-05 13:14:46 -0500
 Function to process link auth cells; stub function for cert cell processing



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r16414] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-11-05 18:15:54 UTC (rev 12384)
+++ tor/trunk/doc/TODO	2007-11-05 18:15:56 UTC (rev 12385)
@@ -37,14 +37,15 @@
         - functions to parse x509 certs
         - functions to validate a single x509 cert against a TLS connection
         - functions to validate a chain of x509 certs, and extract a PK.
+        o function to encode x509 certs
         - Parse CERT cells
         - Generate CERT cells
         o Keep copies of X509 certs around, not necessarily associated with
           connection.
       - LINK_AUTH cells
-        - Code to generate
+        . Code to generate
           o Remember certificate digests from TLS
-        - Code to parse and check
+        o Code to parse and check
         - Unit tests
       - Revised handshake: TLS
         - Server checks for new cipher types, and if it finds them, sends
@@ -53,7 +54,7 @@
         - Client sends new cipher list.
         - Client sends correct extension list.
       - Revised handshake: post-TLS.
-        - If in 'handshaking' state (since v2+ conn is in use), accept
+        o If in 'handshaking' state (since v2+ conn is in use), accept
           VERSIONS and NETINFO and CERT and LINK_AUTH.
         - After we send NETINFO, send CERT and LINK_AUTH if needed.
         - Once we get a good LINK_AUTH, the connection is OPEN.

Modified: tor/trunk/src/or/command.c
===================================================================
--- tor/trunk/src/or/command.c	2007-11-05 18:15:54 UTC (rev 12384)
+++ tor/trunk/src/or/command.c	2007-11-05 18:15:56 UTC (rev 12385)
@@ -27,6 +27,8 @@
 uint64_t stats_n_destroy_cells_processed = 0;
 uint64_t stats_n_versions_cells_processed = 0;
 uint64_t stats_n_netinfo_cells_processed = 0;
+uint64_t stats_n_cert_cells_processed = 0;
+uint64_t stats_n_link_auth_cells_processed = 0;
 
 /* These are the main functions for processing cells */
 static void command_process_create_cell(cell_t *cell, or_connection_t *conn);
@@ -35,6 +37,8 @@
 static void command_process_destroy_cell(cell_t *cell, or_connection_t *conn);
 static void command_process_versions_cell(cell_t *cell, or_connection_t *conn);
 static void command_process_netinfo_cell(cell_t *cell, or_connection_t *conn);
+static void command_process_cert_cell(cell_t *cell, or_connection_t *conn);
+static void command_process_link_auth_cell(cell_t *cell,or_connection_t *conn);
 
 #ifdef KEEP_TIMING_STATS
 /** This is a wrapper function around the actual function that processes the
@@ -113,6 +117,8 @@
 #define PROCESS_CELL(tp, cl, cn) command_process_ ## tp ## _cell(cl, cn)
 #endif
 
+  /*XXXX020 reject all but VERSIONS, NETINFO, CERT, LINK_AUTH when
+   * handshaking. */
   switch (cell->command) {
     case CELL_PADDING:
       ++stats_n_padding_cells_processed;
@@ -144,6 +150,14 @@
       ++stats_n_netinfo_cells_processed;
       PROCESS_CELL(netinfo, cell, conn);
       break;
+    case CELL_CERT:
+      ++stats_n_cert_cells_processed;
+      PROCESS_CELL(cert, cell, conn);
+      break;
+    case CELL_LINK_AUTH:
+      ++stats_n_link_auth_cells_processed;
+      PROCESS_CELL(link_auth, cell, conn);
+      break;
     default:
       log_fn(LOG_INFO, LD_PROTOCOL,
              "Cell of unknown type (%d) received. Dropping.", cell->command);
@@ -500,6 +514,7 @@
   conn->handshake_state->received_netinfo = 1;
 }
 
+/*XXXX020 move to connection_or.c */
 /** DOCDOC Called when we're done authenticating; act on stuff we
  * learned in netinfo. */
 void
@@ -536,3 +551,92 @@
     conn->is_canonical = 1;
   }
 }
+
+static void
+command_process_cert_cell(cell_t *cell, or_connection_t *conn)
+{
+  (void) cell;
+  (void) conn;
+
+  /* Parse certs. */
+  /* Verify that identity cert has signed peer cert in SSL, or
+   * peer cert in the cell. */
+  /* Verify that identity cert is self-signed. */
+  /* Learn ID digest. */
+  /* Learn cert digests. */
+  /* Remember peer cert public key. */
+  /* set received_certs. */
+}
+
+#define LINK_AUTH_STRING "Tor initiator certificate verification"
+
+/** DOCDOC */
+static void
+command_process_link_auth_cell(cell_t *cell, or_connection_t *conn)
+{
+  or_handshake_state_t *s;
+  char hmac[DIGEST_LEN];
+  size_t sig_len;
+  const char *sig;
+  char *checked = NULL;
+  int checked_len;
+  tor_assert(conn);
+  if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR,
+           "Received a LINK_AUTH cell on connection in the wrong state; "
+           "dropping.");
+    return;
+  }
+  s = conn->handshake_state;
+  tor_assert(s);
+  if (s->started_here) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR,
+           "Got a LINK_AUTH cell from a server; closing the connection.");
+    goto err;
+  }
+  if (!s->received_netinfo || !s->received_versions || !s->received_certs) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR, "Got a LINK_AUTH cell too early; "
+           "closing the connection");
+    goto err;
+  }
+  if (cell->payload[0] != 0x00) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR, "Unrecognized LINK_AUTH signature "
+           "version; closing the connection");
+    goto err;
+  }
+  connection_or_compute_link_auth_hmac(conn, hmac);
+
+  tor_assert(s->signing_key);
+
+  /*XXXX020 these two are wrong; fix when protocol is revised. */
+  sig = cell->payload+1;
+  sig_len = 128;
+  checked = tor_malloc(crypto_pk_keysize(s->signing_key));
+  checked_len = crypto_pk_public_checksig(s->signing_key,checked,sig,sig_len);
+  if (checked_len < 0) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR, "Bad signature on LINK_AUTH cell; "
+           "closing the connection");
+    goto err;
+  }
+  if (checked_len != DIGEST_LEN) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR, "Bad length (%d) of signed material in "
+           "LINK_AUTH cell; closing the connection", checked_len);
+    goto err;
+  }
+  if (memcmp(checked, hmac, DIGEST_LEN) != 0) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR, "Bad signed data in LINK_AUTH cell; "
+           "closing the connection.");
+    goto err;
+  }
+
+  /* Okay, we're authenticated. */
+  s->authenticated = 1;
+
+  /* XXXX020 act on being authenticated: */
+
+  return;
+ err:
+  tor_free(checked);
+  connection_mark_for_close(TO_CONN(conn));
+}
+

Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c	2007-11-05 18:15:54 UTC (rev 12384)
+++ tor/trunk/src/or/connection_or.c	2007-11-05 18:15:56 UTC (rev 12385)
@@ -947,3 +947,37 @@
   return 0;
 }
 
+#define LINK_AUTH_STRING "Tor initiator certificate verification"
+/** DOCDOC */
+int
+connection_or_compute_link_auth_hmac(or_connection_t *conn,
+                                     char *hmac_out)
+{
+  char buf[64 + 2*TOR_TLS_RANDOM_LEN + 2*DIGEST_LEN];
+  char *cp;
+  or_handshake_state_t *s;
+  tor_assert(conn);
+  tor_assert(conn->handshake_state);
+  tor_assert(conn->tls);
+  s = conn->handshake_state;
+
+  /* Fill the buffer. */
+  strlcpy(buf, LINK_AUTH_STRING, sizeof(buf));
+  cp = buf+strlen(buf);
+  ++cp; /* Skip the NUL */
+  memcpy(cp, s->client_random, TOR_TLS_RANDOM_LEN);
+  cp += TOR_TLS_RANDOM_LEN;
+  memcpy(cp, s->server_random, TOR_TLS_RANDOM_LEN);
+  cp += TOR_TLS_RANDOM_LEN;
+  memcpy(cp, s->client_cert_digest, DIGEST_LEN);
+  cp += DIGEST_LEN;
+  memcpy(cp, s->server_cert_digest, DIGEST_LEN);
+  cp += DIGEST_LEN;
+  tor_assert(cp < buf+sizeof(buf));
+
+  if (tor_tls_hmac_with_master_secret(conn->tls, hmac_out, buf, cp-buf) < 0)
+    return -1;
+  return 0;
+}
+
+

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-11-05 18:15:54 UTC (rev 12384)
+++ tor/trunk/src/or/or.h	2007-11-05 18:15:56 UTC (rev 12385)
@@ -657,6 +657,8 @@
 #define CELL_CREATED_FAST 6
 #define CELL_VERSIONS 7
 #define CELL_NETINFO 8
+#define CELL_CERT 9
+#define CELL_LINK_AUTH 10
 
 /** How long to test reachability before complaining to the user. */
 #define TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT (20*60)
@@ -2778,6 +2780,10 @@
 int connection_or_send_destroy(uint16_t circ_id, or_connection_t *conn,
                                int reason);
 int connection_or_send_netinfo(or_connection_t *conn);
+int connection_or_send_certs(or_connection_t *conn);
+int connection_or_send_link_auth(or_connection_t *conn);
+int connection_or_compute_link_auth_hmac(or_connection_t *conn,
+                                         char *hmac_out);
 
 void cell_pack(packed_cell_t *dest, const cell_t *src);