[tor-commits] [tor/master] Functions to send cert and auth_challenge cells.

nickm at torproject.org nickm at torproject.org
Tue Oct 11 03:22:15 UTC 2011


commit df78daa5da0fd27fdd2fd8ad13aa12e74696a4ef
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Sep 13 11:38:38 2011 -0400

    Functions to send cert and auth_challenge cells.
---
 src/or/connection_or.c |   81 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/or/connection_or.h |    3 ++
 src/or/or.h            |   15 ++++++++-
 3 files changed, 98 insertions(+), 1 deletions(-)

diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index b146efb..dcb838b 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -1761,3 +1761,84 @@ connection_or_send_netinfo(or_connection_t *conn)
   return 0;
 }
 
+/** DOCDOC */
+#define OR_CERT_TYPE_TLS_LINK 1
+#define OR_CERT_TYPE_ID_1024 2
+
+/** Send a CERT cell on the connection <b>conn</b>.  Return 0 on success, -1
+ * on failure. */
+int
+connection_or_send_cert_cell(or_connection_t *conn)
+{
+  const tor_cert_t *link_cert = NULL, *id_cert = NULL;
+  const uint8_t *link_encoded = NULL, *id_encoded = NULL;
+  size_t link_len, id_len;
+  var_cell_t *cell;
+  size_t cell_len;
+  int pos;
+
+  tor_assert(conn->_base.state == OR_CONN_STATE_OR_HANDSHAKING_V3);
+
+  if (! conn->handshake_state)
+    return -1;
+  if (tor_tls_get_my_certs(! conn->handshake_state->started_here,
+                           &link_cert, &id_cert) < 0)
+    return -1;
+  tor_cert_get_der(link_cert, &link_encoded, &link_len);
+  tor_cert_get_der(id_cert, &id_encoded, &id_len);
+
+  cell_len = 1 /* 1 octet: num certs in cell */ +
+             2 * ( 1 + 2 ) /* For each cert: 1 octet for type, 2 for length */ +
+             link_len + id_len;
+  cell = var_cell_new(cell_len);
+  cell->command = CELL_CERT;
+  cell->payload[0] = 2;
+  pos = 1;
+
+  cell->payload[pos] = OR_CERT_TYPE_TLS_LINK; /* Link cert  */
+  set_uint16(&cell->payload[pos+1], htons(link_len));
+  memcpy(&cell->payload[pos+3], link_encoded, link_len);
+  pos += 3 + link_len;
+
+  cell->payload[pos] = OR_CERT_TYPE_ID_1024; /* ID cert */
+  set_uint16(&cell->payload[pos+1], htons(id_len));
+  memcpy(&cell->payload[pos+3], id_encoded, id_len);
+  pos += 3 + id_len;
+
+  tor_assert(pos == (int)cell_len); /* Otherwise we just smashed the heap */
+
+  connection_or_write_var_cell_to_buf(cell, conn);
+  var_cell_free(cell);
+
+  return 0;
+}
+
+/** Send an AUTH_CHALLENGE cell on the connection <b>conn</b>. Return 0
+ * on success, -1 on failure. */
+int
+connection_or_send_auth_challenge_cell(or_connection_t *conn)
+{
+  var_cell_t *cell;
+  uint8_t *cp;
+  uint8_t challenge[OR_AUTH_CHALLENGE_LEN];
+  tor_assert(conn->_base.state == OR_CONN_STATE_OR_HANDSHAKING_V3);
+
+  if (! conn->handshake_state)
+    return -1;
+
+  if (crypto_rand((char*)challenge, OR_AUTH_CHALLENGE_LEN) < 0)
+    return -1;
+  cell = var_cell_new(OR_AUTH_CHALLENGE_LEN + 4);
+  cell->command = CELL_AUTH_CHALLENGE;
+  memcpy(cell->payload, challenge, OR_AUTH_CHALLENGE_LEN);
+  cp = cell->payload + OR_AUTH_CHALLENGE_LEN;
+  set_uint16(cp, htons(1)); /* We recognize one authentication type. */
+  set_uint16(cp+2, htons(AUTHTYPE_RSA_SHA256_TLSSECRET));
+
+  connection_or_write_var_cell_to_buf(cell, conn);
+  var_cell_free(cell);
+  memset(challenge, 0, sizeof(challenge));
+
+  return 0;
+}
+
diff --git a/src/or/connection_or.h b/src/or/connection_or.h
index 072edbd..6e50e29 100644
--- a/src/or/connection_or.h
+++ b/src/or/connection_or.h
@@ -50,6 +50,9 @@ void connection_or_write_var_cell_to_buf(const var_cell_t *cell,
 int connection_or_send_destroy(circid_t circ_id, or_connection_t *conn,
                                int reason);
 int connection_or_send_netinfo(or_connection_t *conn);
+int connection_or_send_cert_cell(or_connection_t *conn);
+int connection_or_send_auth_challenge_cell(or_connection_t *conn);
+
 int is_or_protocol_version_known(uint16_t version);
 
 void cell_pack(packed_cell_t *dest, const cell_t *src);
diff --git a/src/or/or.h b/src/or/or.h
index ef4ddbd..ebf9ab5 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1084,7 +1084,10 @@ typedef struct listener_connection_t {
 
 } listener_connection_t;
 
-/** Stores flags and information related to the portion of a v2 Tor OR
+/** Minimum length of the random part of an AUTH_CHALLENGE cell. */
+#define OR_AUTH_CHALLENGE_LEN 32
+
+/** Stores flags and information related to the portion of a v2/v3 Tor OR
  * connection handshake that happens after the TLS handshake is finished.
  */
 typedef struct or_handshake_state_t {
@@ -1095,6 +1098,16 @@ typedef struct or_handshake_state_t {
   unsigned int started_here : 1;
   /** True iff we have received and processed a VERSIONS cell. */
   unsigned int received_versions : 1;
+
+  /** Digests of the cells that we have sent or received as part of a V3
+   * handshake.  Used for making and checking AUTHENTICATE cells.
+   *
+   * @{
+   */
+  crypto_digest_env_t *digest_sent;
+  crypto_digest_env_t *digest_received;
+  /** @} */
+
 } or_handshake_state_t;
 
 /** Subtype of connection_t for an "OR connection" -- that is, one that speaks





More information about the tor-commits mailing list