[tor-commits] [tor/master] When Tor is compiled with NSS, don't claim support for LinkAuth=1

nickm at torproject.org nickm at torproject.org
Sun Sep 16 17:29:03 UTC 2018


commit 991bec67ee41fd7f3c12e9194d96491b51bedd50
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Aug 23 11:30:18 2018 -0400

    When Tor is compiled with NSS, don't claim support for LinkAuth=1
    
    Closes ticket 27288
---
 src/core/or/connection_or.c     | 23 ++++++++++++++++++++---
 src/core/or/connection_or.h     |  1 +
 src/core/or/protover.c          |  5 ++++-
 src/lib/crypt_ops/crypto_init.c | 11 +++++++++++
 src/lib/crypt_ops/crypto_init.h |  2 ++
 src/lib/tls/tortls.h            |  4 ++++
 src/rust/external/external.rs   | 10 ++++++++++
 src/rust/protover/protover.rs   | 38 ++++++++++++++++++++++++++------------
 src/test/test_link_handshake.c  | 14 ++++++++++++++
 src/test/test_protover.c        |  3 ++-
 10 files changed, 94 insertions(+), 17 deletions(-)

diff --git a/src/core/or/connection_or.c b/src/core/or/connection_or.c
index e6b235401..e559e6b98 100644
--- a/src/core/or/connection_or.c
+++ b/src/core/or/connection_or.c
@@ -2641,6 +2641,12 @@ connection_or_send_certs_cell(or_connection_t *conn)
   return 0;
 }
 
+#ifdef TOR_UNIT_TESTS
+int testing__connection_or_pretend_TLSSECRET_is_supported = 0;
+#else
+#define testing__connection_or_pretend_TLSSECRET_is_supported 0
+#endif
+
 /** Return true iff <b>challenge_type</b> is an AUTHCHALLENGE type that
  * we can send and receive. */
 int
@@ -2648,6 +2654,11 @@ authchallenge_type_is_supported(uint16_t challenge_type)
 {
   switch (challenge_type) {
      case AUTHTYPE_RSA_SHA256_TLSSECRET:
+#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
+       return 1;
+#else
+       return testing__connection_or_pretend_TLSSECRET_is_supported;
+#endif
      case AUTHTYPE_ED25519_SHA256_RFC5705:
        return 1;
      case AUTHTYPE_RSA_SHA256_RFC5705:
@@ -2690,11 +2701,13 @@ connection_or_send_auth_challenge_cell(or_connection_t *conn)
   tor_assert(sizeof(ac->challenge) == 32);
   crypto_rand((char*)ac->challenge, sizeof(ac->challenge));
 
-  auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_TLSSECRET);
+  if (authchallenge_type_is_supported(AUTHTYPE_RSA_SHA256_TLSSECRET))
+    auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_TLSSECRET);
   /* Disabled, because everything that supports this method also supports
    * the much-superior ED25519_SHA256_RFC5705 */
   /* auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_RFC5705); */
-  auth_challenge_cell_add_methods(ac, AUTHTYPE_ED25519_SHA256_RFC5705);
+  if (authchallenge_type_is_supported(AUTHTYPE_ED25519_SHA256_RFC5705))
+    auth_challenge_cell_add_methods(ac, AUTHTYPE_ED25519_SHA256_RFC5705);
   auth_challenge_cell_set_n_methods(ac,
                                     auth_challenge_cell_getlen_methods(ac));
 
@@ -2855,7 +2868,11 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn,
 
   /* HMAC of clientrandom and serverrandom using master key : 32 octets */
   if (old_tlssecrets_algorithm) {
-    tor_tls_get_tlssecrets(conn->tls, auth->tlssecrets);
+    if (tor_tls_get_tlssecrets(conn->tls, auth->tlssecrets) < 0) {
+      log_fn(LOG_PROTOCOL_WARN, LD_OR, "Somebody asked us for an older TLS "
+         "authentication method (AUTHTYPE_RSA_SHA256_TLSSECRET) "
+         "which we don't support.");
+    }
   } else {
     char label[128];
     tor_snprintf(label, sizeof(label),
diff --git a/src/core/or/connection_or.h b/src/core/or/connection_or.h
index 2d95fdea1..d4bcdd93e 100644
--- a/src/core/or/connection_or.h
+++ b/src/core/or/connection_or.h
@@ -160,6 +160,7 @@ STATIC void note_or_connect_failed(const or_connection_t *or_conn);
 
 #ifdef TOR_UNIT_TESTS
 extern int certs_cell_ed25519_disabled_for_testing;
+extern int testing__connection_or_pretend_TLSSECRET_is_supported;
 #endif
 
 #endif /* !defined(TOR_CONNECTION_OR_H) */
diff --git a/src/core/or/protover.c b/src/core/or/protover.c
index 362a5beca..70606af41 100644
--- a/src/core/or/protover.c
+++ b/src/core/or/protover.c
@@ -374,7 +374,11 @@ protover_get_supported_protocols(void)
     "HSIntro=3-4 "
     "HSRend=1-2 "
     "Link=1-5 "
+#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
     "LinkAuth=1,3 "
+#else
+    "LinkAuth=3 "
+#endif
     "Microdesc=1-2 "
     "Relay=1-2";
 }
@@ -920,4 +924,3 @@ protover_free_all(void)
 }
 
 #endif /* !defined(HAVE_RUST) */
-
diff --git a/src/lib/crypt_ops/crypto_init.c b/src/lib/crypt_ops/crypto_init.c
index c731662d4..9d6e2da0d 100644
--- a/src/lib/crypt_ops/crypto_init.c
+++ b/src/lib/crypt_ops/crypto_init.c
@@ -191,3 +191,14 @@ crypto_get_header_version_string(void)
   return crypto_nss_get_header_version_str();
 #endif
 }
+
+/** Return true iff Tor is using the NSS library. */
+int
+tor_is_using_nss(void)
+{
+#ifdef ENABLE_NSS
+  return 1;
+#else
+  return 0;
+#endif
+}
diff --git a/src/lib/crypt_ops/crypto_init.h b/src/lib/crypt_ops/crypto_init.h
index 5b6d65d48..b71f14427 100644
--- a/src/lib/crypt_ops/crypto_init.h
+++ b/src/lib/crypt_ops/crypto_init.h
@@ -31,4 +31,6 @@ const char *crypto_get_library_name(void);
 const char *crypto_get_library_version_string(void);
 const char *crypto_get_header_version_string(void);
 
+int tor_is_using_nss(void);
+
 #endif /* !defined(TOR_CRYPTO_H) */
diff --git a/src/lib/tls/tortls.h b/src/lib/tls/tortls.h
index 3f1098bba..81db5ce5a 100644
--- a/src/lib/tls/tortls.h
+++ b/src/lib/tls/tortls.h
@@ -126,6 +126,10 @@ int tor_tls_server_got_renegotiate(tor_tls_t *tls);
 MOCK_DECL(int,tor_tls_cert_matches_key,(const tor_tls_t *tls,
                                         const struct tor_x509_cert_t *cert));
 MOCK_DECL(int,tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out));
+#ifdef ENABLE_OPENSSL
+/* OpenSSL lets us see these master secrets; NSS sensibly does not. */
+#define HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
+#endif
 MOCK_DECL(int,tor_tls_export_key_material,(
                      tor_tls_t *tls, uint8_t *secrets_out,
                      const uint8_t *context,
diff --git a/src/rust/external/external.rs b/src/rust/external/external.rs
index 874c7c315..d342fe096 100644
--- a/src/rust/external/external.rs
+++ b/src/rust/external/external.rs
@@ -26,3 +26,13 @@ pub fn c_tor_version_as_new_as(platform: &str, cutoff: &str) -> bool {
 
     result == 1
 }
+
+extern "C" {
+    fn tor_is_using_nss() -> c_int;
+}
+
+/// Return true if Tor was built to use NSS.
+pub fn c_tor_is_using_nss() -> bool
+{
+    0 != unsafe { tor_is_using_nss() }
+}
diff --git a/src/rust/protover/protover.rs b/src/rust/protover/protover.rs
index 6fbe7c5dc..7b3f808cb 100644
--- a/src/rust/protover/protover.rs
+++ b/src/rust/protover/protover.rs
@@ -10,6 +10,7 @@ use std::str::FromStr;
 use std::string::String;
 
 use external::c_tor_version_as_new_as;
+use external::c_tor_is_using_nss;
 
 use errors::ProtoverError;
 use protoset::ProtoSet;
@@ -141,18 +142,31 @@ impl From<Protocol> for UnknownProtocol {
 ///
 //  C_RUST_COUPLED: protover.c `protover_get_supported_protocols`
 pub(crate) fn get_supported_protocols_cstr() -> &'static CStr {
-    cstr!(
-        "Cons=1-2 \
-         Desc=1-2 \
-         DirCache=1-2 \
-         HSDir=1-2 \
-         HSIntro=3-4 \
-         HSRend=1-2 \
-         Link=1-5 \
-         LinkAuth=1,3 \
-         Microdesc=1-2 \
-         Relay=1-2"
-    )
+    if c_tor_is_using_nss() {
+        cstr!("Cons=1-2 \
+               Desc=1-2 \
+               DirCache=1-2 \
+               HSDir=1-2 \
+               HSIntro=3-4 \
+               HSRend=1-2 \
+               Link=1-5 \
+               LinkAuth=3 \
+               Microdesc=1-2 \
+               Relay=1-2"
+        )
+    } else {
+        cstr!("Cons=1-2 \
+               Desc=1-2 \
+               DirCache=1-2 \
+               HSDir=1-2 \
+               HSIntro=3-4 \
+               HSRend=1-2 \
+               Link=1-5 \
+               LinkAuth=1,3 \
+               Microdesc=1-2 \
+               Relay=1-2"
+        )
+    }
 }
 
 /// A map of protocol names to the versions of them which are supported.
diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c
index df3fa67eb..82a91a9ae 100644
--- a/src/test/test_link_handshake.c
+++ b/src/test/test_link_handshake.c
@@ -942,15 +942,25 @@ test_link_handshake_send_authchallenge(void *arg)
   cell1 = mock_got_var_cell;
   tt_int_op(0, OP_EQ, connection_or_send_auth_challenge_cell(c1));
   cell2 = mock_got_var_cell;
+#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
   tt_int_op(38, OP_EQ, cell1->payload_len);
   tt_int_op(38, OP_EQ, cell2->payload_len);
+#else
+  tt_int_op(36, OP_EQ, cell1->payload_len);
+  tt_int_op(36, OP_EQ, cell2->payload_len);
+#endif
   tt_int_op(0, OP_EQ, cell1->circ_id);
   tt_int_op(0, OP_EQ, cell2->circ_id);
   tt_int_op(CELL_AUTH_CHALLENGE, OP_EQ, cell1->command);
   tt_int_op(CELL_AUTH_CHALLENGE, OP_EQ, cell2->command);
 
+#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
   tt_mem_op("\x00\x02\x00\x01\x00\x03", OP_EQ, cell1->payload + 32, 6);
   tt_mem_op("\x00\x02\x00\x01\x00\x03", OP_EQ, cell2->payload + 32, 6);
+#else
+  tt_mem_op("\x00\x01\x00\x03", OP_EQ, cell1->payload + 32, 4);
+  tt_mem_op("\x00\x01\x00\x03", OP_EQ, cell2->payload + 32, 4);
+#endif
   tt_mem_op(cell1->payload, OP_NE, cell2->payload, 32);
 
  done:
@@ -992,6 +1002,8 @@ static void *
 recv_authchallenge_setup(const struct testcase_t *test)
 {
   (void)test;
+
+  testing__connection_or_pretend_TLSSECRET_is_supported = 1;
   authchallenge_data_t *d = tor_malloc_zero(sizeof(*d));
   d->c = or_connection_new(CONN_TYPE_OR, AF_INET);
   d->chan = tor_malloc_zero(sizeof(*d->chan));
@@ -1205,6 +1217,8 @@ authenticate_data_setup(const struct testcase_t *test)
   authenticate_data_t *d = tor_malloc_zero(sizeof(*d));
   int is_ed = d->is_ed = (test->setup_data == (void*)3);
 
+  testing__connection_or_pretend_TLSSECRET_is_supported = 1;
+
   scheduler_init();
 
   MOCK(connection_or_write_var_cell_to_buf, mock_write_var_cell);
diff --git a/src/test/test_protover.c b/src/test/test_protover.c
index 9a2b6f6be..8da1e9d8a 100644
--- a/src/test/test_protover.c
+++ b/src/test/test_protover.c
@@ -452,10 +452,12 @@ test_protover_supported_protocols(void *arg)
     }
   }
 
+#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
   /* Legacy LinkAuth does not appear anywhere in the code. */
   tt_assert(protocol_list_supports_protocol(supported_protocols,
                                             PRT_LINKAUTH,
                                             PROTOVER_LINKAUTH_V1));
+#endif
   /* Latest LinkAuth is not exposed in the headers. */
   tt_assert(protocol_list_supports_protocol(supported_protocols,
                                             PRT_LINKAUTH,
@@ -641,4 +643,3 @@ struct testcase_t protover_tests[] = {
   PV_TEST(vote_roundtrip, 0),
   END_OF_TESTCASES
 };
-



More information about the tor-commits mailing list