]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
r16432@catbus: nickm | 2007-11-05 14:18:57 -0500
authorNick Mathewson <nickm@torproject.org>
Mon, 5 Nov 2007 19:19:46 +0000 (19:19 +0000)
committerNick Mathewson <nickm@torproject.org>
Mon, 5 Nov 2007 19:19:46 +0000 (19:19 +0000)
 Send and parse link_auth cells properly.

svn:r12386

doc/TODO
src/common/tortls.c
src/common/tortls.h
src/or/command.c
src/or/connection_or.c
src/or/or.h

index de40e63d5ea1e77829d9fd896d8e7017dd20bc3c..893e3dee09cfd96ae276c428fdc9d93b45e4b618 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
@@ -43,7 +43,7 @@ Things we'd like to do in 0.2.0.x:
         o Keep copies of X509 certs around, not necessarily associated with
           connection.
       - LINK_AUTH cells
-        . Code to generate
+        o Code to generate
           o Remember certificate digests from TLS
         o Code to parse and check
         - Unit tests
@@ -56,7 +56,7 @@ Things we'd like to do in 0.2.0.x:
       - Revised handshake: post-TLS.
         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.
+        o After we send NETINFO, send CERT and LINK_AUTH if needed.
         - Once we get a good LINK_AUTH, the connection is OPEN.
         - Ban most cell types on a non-OPEN connection.
       o Make code work right wrt TLS context rotation.
index 6c04a362a8842da3c12aeae7f5fe9fc5e98bcd41..1075de977e69910155ebdc603757f4c29cb8f455 100644 (file)
@@ -47,6 +47,7 @@ typedef struct tor_tls_context_t {
   SSL_CTX *ctx;
   X509 *my_cert;
   X509 *my_id_cert;
+  crypto_pk_env_t *key;
 } tor_tls_context_t;
 
 /** Holds a SSL object and its associated data.  Members are only
@@ -355,6 +356,7 @@ tor_tls_context_decref(tor_tls_context_t *ctx)
     SSL_CTX_free(ctx->ctx);
     X509_free(ctx->my_cert);
     X509_free(ctx->my_id_cert);
+    crypto_free_pk_env(ctx->key);
     tor_free(ctx);
   }
 }
@@ -410,6 +412,7 @@ tor_tls_context_new(crypto_pk_env_t *identity, const char *nickname,
   result->refcnt = 1;
   result->my_cert = X509_dup(cert);
   result->my_id_cert = X509_dup(idcert);
+  result->key = crypto_pk_dup_key(rsa);
 
 #ifdef EVERYONE_HAS_AES
   /* Tell OpenSSL to only use TLS1 */
@@ -734,6 +737,13 @@ tor_tls_get_cert_digests(tor_tls_t *tls,
   return 0;
 }
 
+/** DOCDOC */
+crypto_pk_env_t *
+tor_tls_dup_private_key(tor_tls_t *tls)
+{
+  return crypto_pk_dup_key(tls->context->key);
+}
+
 /** DOCDOC */
 char *
 tor_tls_encode_my_certificate(tor_tls_t *tls, size_t *size_out,
index 639502e378a7321bd1e17b55cd7f269bdf3fb4ee..a0fad8488ac836a2d4dcbd9330b5e1dc15d0ac09 100644 (file)
@@ -57,6 +57,7 @@ int tor_tls_get_cert_digests(tor_tls_t *tls, char *my_digest_out,
                              char *peer_digest_out);
 char *tor_tls_encode_my_certificate(tor_tls_t *tls, size_t *size_out,
                                     int conn_cert);
+crypto_pk_env_t *tor_tls_dup_private_key(tor_tls_t *tls);
 int tor_tls_verify_v1(int severity, tor_tls_t *tls,
                       crypto_pk_env_t **identity);
 int tor_tls_check_lifetime(tor_tls_t *tls, int tolerance);
index dcb713f73c951533bb93730e64c463b1b6479e96..e33fe8036b7d09cadde9200b4b99ee8fd36225f8 100644 (file)
@@ -432,15 +432,22 @@ command_process_versions_cell(cell_t *cell, or_connection_t *conn)
   if (!highest_supported_version) {
     log_fn(LOG_PROTOCOL_WARN, LD_OR,
            "Couldn't find a version in common; defaulting to v1.");
-    /*XXXX020 just break the connection?*/
+    /*XXXX020 just break the connection*/
     conn->link_proto = 1;
     return;
   }
   conn->link_proto = highest_supported_version;
   conn->handshake_state->received_versions = 1;
 
-  if (highest_supported_version >= 2)
+  if (highest_supported_version >= 2) {
+    /*XXXX020 check return values. */
     connection_or_send_netinfo(conn);
+    connection_or_send_cert(conn);
+    if (conn->handshake_state->started_here)
+      connection_or_send_link_auth(conn);
+  } else {
+    /* XXXX020 finish v1 verification. */
+  }
 }
 
 /** Process a 'netinfo' cell. DOCDOC say more. */
@@ -576,6 +583,7 @@ command_process_link_auth_cell(cell_t *cell, or_connection_t *conn)
 {
   or_handshake_state_t *s;
   char hmac[DIGEST_LEN];
+  uint16 len;
   size_t sig_len;
   const char *sig;
   char *checked = NULL;
@@ -599,7 +607,13 @@ command_process_link_auth_cell(cell_t *cell, or_connection_t *conn)
            "closing the connection");
     goto err;
   }
-  if (cell->payload[0] != 0x00) {
+  len = ntohs(get_uint16(cell.payload));
+  if (len < 2 || 2+len > CELL_PAYLOAD_SIZE) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR, "Bad length field (%d) on LINK_AUTH cell;"
+           " closing the connection", (int)len);
+    goto err;
+  }
+  if (cell->payload[2] != 0x00) {
     log_fn(LOG_PROTOCOL_WARN, LD_OR, "Unrecognized LINK_AUTH signature "
            "version; closing the connection");
     goto err;
@@ -608,9 +622,8 @@ command_process_link_auth_cell(cell_t *cell, or_connection_t *conn)
 
   tor_assert(s->signing_key);
 
-  /*XXXX020 these two are wrong; fix when protocol is revised. */
-  sig = cell->payload+1;
-  sig_len = 128;
+  sig = cell->payload+3;
+  sig_len = len-1;
   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) {
index a75d6df7d829d2f7d6245f1d35bb0e8a79e3a291..93f4d5d7b197f33b90a8fc4722ba423bc870e9c9 100644 (file)
@@ -980,4 +980,47 @@ connection_or_compute_link_auth_hmac(or_connection_t *conn,
   return 0;
 }
 
+/**DOCDOC*/
+int
+connection_or_send_cert(or_connection_t *conn)
+{
+  (void)conn;
+  /*XXX020 implement.*/
+  return 0;
+}
+
+/**DOCDOC*/
+int
+connection_or_send_link_auth(or_connection_t *conn)
+{
+  cell_t cell;
+  char hmac[DIGEST_LEN];
+  crypto_pk_env_t *key;
+  int r, len;
 
+  tor_assert(conn);
+  tor_assert(conn->tls);
+  tor_assert(conn->handshake_state);
+  tor_assert(conn->handshake_state->started_here == 1);
+  tor_assert(conn->handshake_state->received_certs == 1);
+
+  memset(&cell, 0, sizeof(cell));
+  cell.command = CELL_LINK_AUTH;
+  key = tor_tls_dup_private_key(conn->tls);
+  connection_or_compute_link_auth_hmac(conn, hmac);
+
+  cell.payload[2] = 0x00; /* Signature version */
+  r = crypto_pk_private_sign(key, cell.payload+3, hmac, sizeof(hmac));
+  crypto_free_pk_env(key);
+  if (r<0)
+    return -1;
+  len = r + 1;
+
+  set_uint16(cell.payload, htons(len));
+
+  connection_or_write_cell_to_buf(&cell, conn);
+
+  /* XXXX020 at this point, as a client, we can consider ourself
+   * authenticated. */
+  return 0;
+}
index 87914e3c3c8b58975288bb556bdf017392c3120d..8dd6dc806c324d6a682ccd391132457a9a2e6fb5 100644 (file)
@@ -2780,7 +2780,7 @@ void connection_or_write_cell_to_buf(const cell_t *cell,
 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_cert(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);