[tor-commits] [tor/master] Unit test for basic ext_or_cookie authentication backend

nickm at torproject.org nickm at torproject.org
Thu Aug 15 16:16:46 UTC 2013


commit 4526c3e0b617bd179bb0728ac2ea438e9a2276ed
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Aug 1 11:44:52 2013 -0400

    Unit test for basic ext_or_cookie authentication backend
---
 src/or/ext_orport.c       |    8 ++---
 src/or/ext_orport.h       |    8 +++++
 src/test/test_extorport.c |   71 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/src/or/ext_orport.c b/src/or/ext_orport.c
index f4df1b7..ec7c6c5 100644
--- a/src/or/ext_orport.c
+++ b/src/or/ext_orport.c
@@ -105,11 +105,11 @@ connection_ext_or_transition(or_connection_t *conn)
 
 /** If true, we've set ext_or_auth_cookie to a secret code and stored
  * it to disk. */
-static int ext_or_auth_cookie_is_set = 0;
+STATIC int ext_or_auth_cookie_is_set = 0;
 /** If ext_or_auth_cookie_is_set, a secret cookie that we've stored to disk
  * and which we're using to authenticate controllers.  (If the controller can
  * read it off disk, it has permission to connect.) */
-static char ext_or_auth_cookie[EXT_OR_PORT_AUTH_COOKIE_LEN] = {0};
+STATIC char ext_or_auth_cookie[EXT_OR_PORT_AUTH_COOKIE_LEN] = {0};
 
 /** Helper: Return a newly allocated string containing a path to the
  * file where we store our authentication cookie. */
@@ -198,10 +198,10 @@ connection_ext_or_auth_neg_auth_type(connection_t *conn)
 }
 
 /** DOCDOC */
-static int
+STATIC int
 handle_client_auth_nonce(const char *client_nonce, size_t client_nonce_len,
                          char **client_hash_out,
-                         char**reply_out, size_t *reply_len_out)
+                         char **reply_out, size_t *reply_len_out)
 {
   char server_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
   char server_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
diff --git a/src/or/ext_orport.h b/src/or/ext_orport.h
index 35b92ad..2d15c18 100644
--- a/src/or/ext_orport.h
+++ b/src/or/ext_orport.h
@@ -27,6 +27,14 @@ STATIC int connection_write_ext_or_command(connection_t *conn,
                                            uint16_t command,
                                            const char *body,
                                            size_t bodylen);
+STATIC int handle_client_auth_nonce(const char *client_nonce,
+                         size_t client_nonce_len,
+                         char **client_hash_out,
+                         char **reply_out, size_t *reply_len_out);
+#ifdef TOR_UNIT_TESTS
+extern char ext_or_auth_cookie[];
+extern int ext_or_auth_cookie_is_set;
+#endif
 #endif
 
 #endif
diff --git a/src/test/test_extorport.c b/src/test/test_extorport.c
index 525ac4f..2caf2ac 100644
--- a/src/test/test_extorport.c
+++ b/src/test/test_extorport.c
@@ -144,9 +144,80 @@ test_ext_or_write_command(void *arg)
   UNMOCK(connection_write_to_buf_impl_);
 }
 
+static void
+test_ext_or_cookie_auth(void *arg)
+{
+  char *reply=NULL, *client_hash=NULL;
+  size_t reply_len=0;
+  char hmac1[32], hmac2[32];
+
+  const char client_nonce[32] =
+    "Who is the third who walks alway";
+  char server_hash_input[] =
+    "ExtORPort authentication server-to-client hash"
+    "Who is the third who walks alway"
+    "................................";
+  char client_hash_input[] =
+    "ExtORPort authentication client-to-server hash"
+    "Who is the third who walks alway"
+    "................................";
+
+  (void)arg;
+
+  tt_int_op(strlen(client_hash_input), ==, 46+32+32);
+  tt_int_op(strlen(server_hash_input), ==, 46+32+32);
+
+  memcpy(ext_or_auth_cookie, "s beside you? When I count, ther", 32);
+  ext_or_auth_cookie_is_set = 1;
+
+  /* For this authentication, the client sends 32 random bytes (ClientNonce)
+   * The server replies with 32 byte ServerHash and 32 byte ServerNonce,
+   * where ServerHash is:
+   * HMAC-SHA256(CookieString,
+   *   "ExtORPort authentication server-to-client hash" | ClientNonce |
+   *    ServerNonce)"
+   * The client must reply with 32-byte ClientHash, which we compute as:
+   *   ClientHash is computed as:
+   *        HMAC-SHA256(CookieString,
+   *           "ExtORPort authentication client-to-server hash" | ClientNonce |
+   *            ServerNonce)
+   */
+
+  /* Wrong length */
+  tt_int_op(-1, ==,
+            handle_client_auth_nonce(client_nonce, 33, &client_hash, &reply,
+                                     &reply_len));
+  tt_int_op(-1, ==,
+            handle_client_auth_nonce(client_nonce, 31, &client_hash, &reply,
+                                     &reply_len));
+
+  /* Now let's try this for real! */
+  tt_int_op(0, ==,
+            handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply,
+                                     &reply_len));
+  tt_int_op(reply_len, ==, 64);
+  tt_ptr_op(reply, !=, NULL);
+  tt_ptr_op(client_hash, !=, NULL);
+  /* Fill in the server nonce into the hash inputs... */
+  memcpy(server_hash_input+46+32, reply+32, 32);
+  memcpy(client_hash_input+46+32, reply+32, 32);
+  /* Check the HMACs are correct... */
+  crypto_hmac_sha256(hmac1, ext_or_auth_cookie, 32, server_hash_input,
+                     46+32+32);
+  crypto_hmac_sha256(hmac2, ext_or_auth_cookie, 32, client_hash_input,
+                     46+32+32);
+  test_memeq(hmac1, reply, 32);
+  test_memeq(hmac2, client_hash, 32);
+
+ done:
+  tor_free(reply);
+  tor_free(client_hash);
+}
+
 struct testcase_t extorport_tests[] = {
   { "id_map", test_ext_or_id_map, TT_FORK, NULL, NULL },
   { "write_command", test_ext_or_write_command, TT_FORK, NULL, NULL },
+  { "cookie_auth", test_ext_or_cookie_auth, TT_FORK, NULL, NULL },
   END_OF_TESTCASES
 };
 





More information about the tor-commits mailing list