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

[or-cvs] r12382: Remember X509 certificates in the context. Store peer/self c (in tor/trunk: . doc src/common src/or)



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

Modified:
   tor/trunk/
   tor/trunk/doc/TODO
   tor/trunk/src/common/tortls.c
   tor/trunk/src/common/tortls.h
   tor/trunk/src/or/connection_or.c
   tor/trunk/src/or/or.h
Log:
 r16411@catbus:  nickm | 2007-11-05 11:27:37 -0500
 Remember X509 certificates in the context.  Store peer/self certificate digests in handshake state.



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

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-11-05 18:15:47 UTC (rev 12381)
+++ tor/trunk/doc/TODO	2007-11-05 18:15:50 UTC (rev 12382)
@@ -43,6 +43,7 @@
           connection.
       - LINK_AUTH cells
         - Code to generate
+          o Remember certificate digests from TLS
         - Code to parse and check
         - Unit tests
       - Revised handshake: TLS
@@ -57,6 +58,7 @@
         - 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.
+      - Make code work right wrt TLS context rotation.
       - NETINFO fallout
         - Don't extend a circuit over a noncanonical connection with
           mismatched address.

Modified: tor/trunk/src/common/tortls.c
===================================================================
--- tor/trunk/src/common/tortls.c	2007-11-05 18:15:47 UTC (rev 12381)
+++ tor/trunk/src/common/tortls.c	2007-11-05 18:15:50 UTC (rev 12382)
@@ -44,6 +44,8 @@
 /** Structure holding the TLS state for a single connection. */
 typedef struct tor_tls_context_t {
   SSL_CTX *ctx;
+  X509 *my_cert;
+  X509 *my_id_cert;
 } tor_tls_context_t;
 
 /** Holds a SSL object and its associated data.  Members are only
@@ -64,6 +66,7 @@
   unsigned long last_read_count;
 };
 
+static void tor_tls_context_free(tor_tls_context_t *ctx);
 static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
                                         crypto_pk_env_t *rsa_sign,
                                         const char *cname,
@@ -211,8 +214,7 @@
 tor_tls_free_all(void)
 {
   if (global_tls_context) {
-    SSL_CTX_free(global_tls_context->ctx);
-    tor_free(global_tls_context);
+    tor_tls_context_free(global_tls_context);
     global_tls_context = NULL;
   }
 }
@@ -341,6 +343,16 @@
 #error "Tor requires OpenSSL version 0.9.7 or later, for AES support."
 #endif
 
+/** DOCDOC */
+static void
+tor_tls_context_free(tor_tls_context_t *ctx)
+{
+  SSL_CTX_free(ctx->ctx);
+  X509_free(ctx->my_cert);
+  X509_free(ctx->my_id_cert);
+  tor_free(ctx);
+}
+
 /** Create a new TLS context for use with Tor TLS handshakes.
  * <b>identity</b> should be set to the identity key used to sign the
  * certificate, and <b>nickname</b> set to the nickname to use.
@@ -382,6 +394,9 @@
   }
 
   result = tor_malloc_zero(sizeof(tor_tls_context_t));
+  result->my_cert = X509_dup(cert);
+  result->my_id_cert = X509_dup(idcert);
+
 #ifdef EVERYONE_HAS_AES
   /* Tell OpenSSL to only use TLS1 */
   if (!(result->ctx = SSL_CTX_new(TLSv1_method())))
@@ -431,8 +446,7 @@
   if (global_tls_context) {
     /* This is safe even if there are open connections: OpenSSL does
      * reference counting with SSL and SSL_CTX objects. */
-    SSL_CTX_free(global_tls_context->ctx);
-    tor_free(global_tls_context);
+    tor_tls_context_free(global_tls_context);
   }
   global_tls_context = result;
   if (rsa)
@@ -679,6 +693,29 @@
   return 1;
 }
 
+/** DOCDOC */
+int
+tor_tls_get_cert_digests(tor_tls_t *tls,
+                         char *my_digest_out,
+                         char *peer_digest_out)
+{
+  X509 *cert;
+  unsigned int len;
+  cert = SSL_get_certificate(tls->ssl);
+  if (cert) {
+    X509_digest(cert, EVP_sha1(), (unsigned char*)my_digest_out, &len);
+    if (len != DIGEST_LEN)
+      return -1;
+  }
+  cert = SSL_get_peer_certificate(tls->ssl);
+  if (cert) {
+    X509_digest(cert, EVP_sha1(), (unsigned char*)peer_digest_out, &len);
+    if (len != DIGEST_LEN)
+      return -1;
+  }
+  return 0;
+}
+
 /** Warn that a certificate lifetime extends through a certain range. */
 static void
 log_cert_lifetime(X509 *cert, const char *problem)
@@ -736,7 +773,7 @@
  * 0.  Else, return -1 and log complaints with log-level <b>severity</b>.
  */
 int
-tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_env_t **identity_key)
+tor_tls_verify_v1(int severity, tor_tls_t *tls, crypto_pk_env_t **identity_key)
 {
   X509 *cert = NULL, *id_cert = NULL;
   STACK_OF(X509) *chain = NULL;
@@ -932,4 +969,3 @@
   return 0;
 }
 
-

Modified: tor/trunk/src/common/tortls.h
===================================================================
--- tor/trunk/src/common/tortls.h	2007-11-05 18:15:47 UTC (rev 12381)
+++ tor/trunk/src/common/tortls.h	2007-11-05 18:15:50 UTC (rev 12382)
@@ -53,9 +53,10 @@
 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);
-int tor_tls_get_peer_cert_nickname(int severity, tor_tls_t *tls,
-                                   char *buf, size_t buflen);
-int tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_env_t **identity);
+int tor_tls_get_cert_digests(tor_tls_t *tls, char *my_digest_out,
+                             char *peer_digest_out);
+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);
 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);

Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c	2007-11-05 18:15:47 UTC (rev 12381)
+++ tor/trunk/src/or/connection_or.c	2007-11-05 18:15:50 UTC (rev 12382)
@@ -17,6 +17,8 @@
 static int connection_tls_finish_handshake(or_connection_t *conn);
 static int connection_or_process_cells_from_inbuf(or_connection_t *conn);
 static int connection_or_send_versions(or_connection_t *conn);
+static int connection_init_or_handshake_state(or_connection_t *conn,
+                                              int started_here);
 
 /**************************************************************/
 
@@ -629,8 +631,8 @@
   check_no_tls_errors();
 
   if (has_cert) {
-    int v = tor_tls_verify(started_here?severity:LOG_INFO,
-                           conn->tls, &identity_rcvd);
+    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.",
@@ -725,10 +727,11 @@
   int started_here = connection_or_nonopen_was_started_here(conn);
 
   log_debug(LD_OR,"tls handshake done. verifying.");
+  /* V1 only XXXX020 */
   if (connection_or_check_valid_handshake(conn, started_here, digest_rcvd) < 0)
     return -1;
 
-  if (!started_here) { /* V1 only XXX020 */
+  if (!started_here) { /* V1 only XXXX020 */
     connection_or_init_conn_from_address(conn,conn->_base.addr,
                                          conn->_base.port, digest_rcvd, 0);
   }
@@ -740,16 +743,36 @@
     return connection_or_set_state_open(conn);
   } else {
     conn->_base.state = OR_CONN_STATE_OR_HANDSHAKING;
-    conn->handshake_state = tor_malloc_zero(sizeof(or_handshake_state_t));
-    conn->handshake_state->started_here = started_here ? 1 : 0;
-    if (tor_tls_get_random_values(conn->tls,
-                                  conn->handshake_state->client_random,
-                                  conn->handshake_state->server_random) < 0)
+    if (connection_init_or_handshake_state(conn, started_here) < 0)
       return -1;
     return connection_or_send_versions(conn);
   }
 }
 
+/** DOCDOC */
+static int
+connection_init_or_handshake_state(or_connection_t *conn, int started_here)
+{
+  or_handshake_state_t *s;
+  s = conn->handshake_state = tor_malloc_zero(sizeof(or_handshake_state_t));
+  s->started_here = started_here ? 1 : 0;
+  if (tor_tls_get_random_values(conn->tls,
+                                conn->handshake_state->client_random,
+                                conn->handshake_state->server_random) < 0)
+    return -1;
+  if (started_here) {
+    if (tor_tls_get_cert_digests(conn->tls,
+                                 s->client_cert_digest,
+                                 s->server_cert_digest)<0)
+      return -1;
+  } else {
+    if (tor_tls_get_cert_digests(conn->tls,
+                                 s->server_cert_digest,
+                                 s->client_cert_digest)<0)
+      return -1;
+  }
+  return 0;
+}
 
 /** DOCDOC */
 void

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-11-05 18:15:47 UTC (rev 12381)
+++ tor/trunk/src/or/or.h	2007-11-05 18:15:50 UTC (rev 12382)
@@ -868,8 +868,10 @@
   unsigned int authenticated : 1;
 
   /* from tls */
-  char client_random[32];
-  char server_random[32];
+  char client_random[TOR_TLS_RANDOM_LEN];
+  char server_random[TOR_TLS_RANDOM_LEN];
+  char client_cert_digest[DIGEST_LEN]; /* may also be set by netinfo */
+  char server_cert_digest[DIGEST_LEN];
 
   /* from netinfo */
   long apparent_skew;