When Tor is compiled with NSS, don't claim support for LinkAuth=1

Closes ticket 27288
This commit is contained in:
Nick Mathewson 2018-08-23 11:30:18 -04:00
parent 035166e7bf
commit 991bec67ee
10 changed files with 94 additions and 17 deletions

View File

@ -2641,6 +2641,12 @@ connection_or_send_certs_cell(or_connection_t *conn)
return 0; 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 /** Return true iff <b>challenge_type</b> is an AUTHCHALLENGE type that
* we can send and receive. */ * we can send and receive. */
int int
@ -2648,6 +2654,11 @@ authchallenge_type_is_supported(uint16_t challenge_type)
{ {
switch (challenge_type) { switch (challenge_type) {
case AUTHTYPE_RSA_SHA256_TLSSECRET: 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: case AUTHTYPE_ED25519_SHA256_RFC5705:
return 1; return 1;
case AUTHTYPE_RSA_SHA256_RFC5705: 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); tor_assert(sizeof(ac->challenge) == 32);
crypto_rand((char*)ac->challenge, sizeof(ac->challenge)); 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 /* Disabled, because everything that supports this method also supports
* the much-superior ED25519_SHA256_RFC5705 */ * the much-superior ED25519_SHA256_RFC5705 */
/* auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_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_set_n_methods(ac,
auth_challenge_cell_getlen_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 */ /* HMAC of clientrandom and serverrandom using master key : 32 octets */
if (old_tlssecrets_algorithm) { 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 { } else {
char label[128]; char label[128];
tor_snprintf(label, sizeof(label), tor_snprintf(label, sizeof(label),

View File

@ -160,6 +160,7 @@ STATIC void note_or_connect_failed(const or_connection_t *or_conn);
#ifdef TOR_UNIT_TESTS #ifdef TOR_UNIT_TESTS
extern int certs_cell_ed25519_disabled_for_testing; extern int certs_cell_ed25519_disabled_for_testing;
extern int testing__connection_or_pretend_TLSSECRET_is_supported;
#endif #endif
#endif /* !defined(TOR_CONNECTION_OR_H) */ #endif /* !defined(TOR_CONNECTION_OR_H) */

View File

@ -374,7 +374,11 @@ protover_get_supported_protocols(void)
"HSIntro=3-4 " "HSIntro=3-4 "
"HSRend=1-2 " "HSRend=1-2 "
"Link=1-5 " "Link=1-5 "
#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
"LinkAuth=1,3 " "LinkAuth=1,3 "
#else
"LinkAuth=3 "
#endif
"Microdesc=1-2 " "Microdesc=1-2 "
"Relay=1-2"; "Relay=1-2";
} }
@ -920,4 +924,3 @@ protover_free_all(void)
} }
#endif /* !defined(HAVE_RUST) */ #endif /* !defined(HAVE_RUST) */

View File

@ -191,3 +191,14 @@ crypto_get_header_version_string(void)
return crypto_nss_get_header_version_str(); return crypto_nss_get_header_version_str();
#endif #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
}

View File

@ -31,4 +31,6 @@ const char *crypto_get_library_name(void);
const char *crypto_get_library_version_string(void); const char *crypto_get_library_version_string(void);
const char *crypto_get_header_version_string(void); const char *crypto_get_header_version_string(void);
int tor_is_using_nss(void);
#endif /* !defined(TOR_CRYPTO_H) */ #endif /* !defined(TOR_CRYPTO_H) */

View File

@ -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, MOCK_DECL(int,tor_tls_cert_matches_key,(const tor_tls_t *tls,
const struct tor_x509_cert_t *cert)); const struct tor_x509_cert_t *cert));
MOCK_DECL(int,tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out)); 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,( MOCK_DECL(int,tor_tls_export_key_material,(
tor_tls_t *tls, uint8_t *secrets_out, tor_tls_t *tls, uint8_t *secrets_out,
const uint8_t *context, const uint8_t *context,

View File

@ -26,3 +26,13 @@ pub fn c_tor_version_as_new_as(platform: &str, cutoff: &str) -> bool {
result == 1 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() }
}

View File

@ -10,6 +10,7 @@ use std::str::FromStr;
use std::string::String; use std::string::String;
use external::c_tor_version_as_new_as; use external::c_tor_version_as_new_as;
use external::c_tor_is_using_nss;
use errors::ProtoverError; use errors::ProtoverError;
use protoset::ProtoSet; use protoset::ProtoSet;
@ -141,18 +142,31 @@ impl From<Protocol> for UnknownProtocol {
/// ///
// C_RUST_COUPLED: protover.c `protover_get_supported_protocols` // C_RUST_COUPLED: protover.c `protover_get_supported_protocols`
pub(crate) fn get_supported_protocols_cstr() -> &'static CStr { pub(crate) fn get_supported_protocols_cstr() -> &'static CStr {
cstr!( if c_tor_is_using_nss() {
"Cons=1-2 \ cstr!("Cons=1-2 \
Desc=1-2 \ Desc=1-2 \
DirCache=1-2 \ DirCache=1-2 \
HSDir=1-2 \ HSDir=1-2 \
HSIntro=3-4 \ HSIntro=3-4 \
HSRend=1-2 \ HSRend=1-2 \
Link=1-5 \ Link=1-5 \
LinkAuth=1,3 \ LinkAuth=3 \
Microdesc=1-2 \ Microdesc=1-2 \
Relay=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. /// A map of protocol names to the versions of them which are supported.

View File

@ -942,15 +942,25 @@ test_link_handshake_send_authchallenge(void *arg)
cell1 = mock_got_var_cell; cell1 = mock_got_var_cell;
tt_int_op(0, OP_EQ, connection_or_send_auth_challenge_cell(c1)); tt_int_op(0, OP_EQ, connection_or_send_auth_challenge_cell(c1));
cell2 = mock_got_var_cell; 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, cell1->payload_len);
tt_int_op(38, OP_EQ, cell2->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, cell1->circ_id);
tt_int_op(0, OP_EQ, cell2->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, cell1->command);
tt_int_op(CELL_AUTH_CHALLENGE, OP_EQ, cell2->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, cell1->payload + 32, 6);
tt_mem_op("\x00\x02\x00\x01\x00\x03", OP_EQ, cell2->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); tt_mem_op(cell1->payload, OP_NE, cell2->payload, 32);
done: done:
@ -992,6 +1002,8 @@ static void *
recv_authchallenge_setup(const struct testcase_t *test) recv_authchallenge_setup(const struct testcase_t *test)
{ {
(void)test; (void)test;
testing__connection_or_pretend_TLSSECRET_is_supported = 1;
authchallenge_data_t *d = tor_malloc_zero(sizeof(*d)); authchallenge_data_t *d = tor_malloc_zero(sizeof(*d));
d->c = or_connection_new(CONN_TYPE_OR, AF_INET); d->c = or_connection_new(CONN_TYPE_OR, AF_INET);
d->chan = tor_malloc_zero(sizeof(*d->chan)); 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)); authenticate_data_t *d = tor_malloc_zero(sizeof(*d));
int is_ed = d->is_ed = (test->setup_data == (void*)3); int is_ed = d->is_ed = (test->setup_data == (void*)3);
testing__connection_or_pretend_TLSSECRET_is_supported = 1;
scheduler_init(); scheduler_init();
MOCK(connection_or_write_var_cell_to_buf, mock_write_var_cell); MOCK(connection_or_write_var_cell_to_buf, mock_write_var_cell);

View File

@ -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. */ /* Legacy LinkAuth does not appear anywhere in the code. */
tt_assert(protocol_list_supports_protocol(supported_protocols, tt_assert(protocol_list_supports_protocol(supported_protocols,
PRT_LINKAUTH, PRT_LINKAUTH,
PROTOVER_LINKAUTH_V1)); PROTOVER_LINKAUTH_V1));
#endif
/* Latest LinkAuth is not exposed in the headers. */ /* Latest LinkAuth is not exposed in the headers. */
tt_assert(protocol_list_supports_protocol(supported_protocols, tt_assert(protocol_list_supports_protocol(supported_protocols,
PRT_LINKAUTH, PRT_LINKAUTH,
@ -641,4 +643,3 @@ struct testcase_t protover_tests[] = {
PV_TEST(vote_roundtrip, 0), PV_TEST(vote_roundtrip, 0),
END_OF_TESTCASES END_OF_TESTCASES
}; };