In the v1 handshake we would send two very specialized certificates.
We'd identify that the client wanted to use this handshake by
the ciphers that it sent, or didn't sent.
We already removed client-side support for the v1 link handshake
back in 0.2.8.1-alpha, with ticket 11150.
tor_tls_err_to_string(result));
return -1;
case TOR_TLS_DONE:
- if (! tor_tls_used_v1_handshake(conn->tls)) {
+ {
if (!tor_tls_is_server(conn->tls)) {
tor_assert(conn->base_.state == OR_CONN_STATE_TLS_HANDSHAKING);
return connection_or_launch_v3_or_handshake(conn);
circuit_build_times_network_is_live(get_circuit_build_times_mutable());
- if (tor_tls_used_v1_handshake(conn->tls)) {
- conn->link_proto = 1;
- connection_or_init_conn_from_address(conn, &conn->base_.addr,
- conn->base_.port, digest_rcvd,
- NULL, 0);
- tor_tls_block_renegotiation(conn->tls);
- rep_hist_note_negotiated_link_proto(1, started_here);
- return connection_or_set_state_open(conn);
- } else {
+ {
connection_or_change_state(conn, OR_CONN_STATE_OR_HANDSHAKING_V2);
if (connection_init_or_handshake_state(conn, started_here) < 0)
return -1;
MOCK_DECL(double, tls_get_write_overhead_ratio, (void));
-int tor_tls_used_v1_handshake(tor_tls_t *tls);
int tor_tls_get_num_server_handshakes(tor_tls_t *tls);
int tor_tls_server_got_renegotiate(tor_tls_t *tls);
MOCK_DECL(int,tor_tls_cert_matches_key,(const tor_tls_t *tls,
#ifdef ENABLE_OPENSSL
tor_tls_t *tor_tls_get_by_ssl(const struct ssl_st *ssl);
-int tor_tls_client_is_using_v2_ciphers(const struct ssl_st *ssl);
void tor_tls_debug_state_callback(const struct ssl_st *ssl,
int type, int val);
void tor_tls_server_info_callback(const struct ssl_st *ssl,
return 0.95;
}
-int
-tor_tls_used_v1_handshake(tor_tls_t *tls)
-{
- tor_assert(tls);
- /* We don't support or allow the V1 handshake with NSS.
- */
- return 0;
-}
-
int
tor_tls_server_got_renegotiate(tor_tls_t *tls)
{
result->my_link_cert->cert)) {
goto error;
}
- if (result->my_id_cert) {
- X509_STORE *s = SSL_CTX_get_cert_store(result->ctx);
- tor_assert(s);
- X509_STORE_add_cert(s, result->my_id_cert->cert);
- }
+ // Here we would once add my_id_cert too via X509_STORE_add_cert.
+ //
+ // We no longer do that, since we no longer send multiple certs;
+ // that was part of the obsolete v1 handshake.
}
SSL_CTX_set_session_cache_mode(result->ctx, SSL_SESS_CACHE_OFF);
if (!is_client) {
EC_KEY_free(ec_key);
}
#endif /* defined(SSL_CTX_set1_groups_list) || defined(HAVE_SSL_CTX_SET1...) */
- SSL_CTX_set_verify(result->ctx, SSL_VERIFY_PEER,
- always_accept_verify_cb);
+
+ if (is_client) {
+ SSL_CTX_set_verify(result->ctx, SSL_VERIFY_PEER,
+ always_accept_verify_cb);
+ } else {
+ /* Don't send a certificate request at all if we're not a client. */
+ SSL_set_verify((SSL*) ssl, SSL_VERIFY_NONE, NULL);
+ }
/* let us realloc bufs that we're writing from */
SSL_CTX_set_mode(result->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
return res;
}
-/** Return true iff the cipher list suggested by the client for <b>ssl</b> is
- * a list that indicates that the client knows how to do the v2 TLS connection
- * handshake. */
-int
-tor_tls_client_is_using_v2_ciphers(const SSL *ssl)
-{
- STACK_OF(SSL_CIPHER) *ciphers;
-#ifdef HAVE_SSL_GET_CLIENT_CIPHERS
- ciphers = SSL_get_client_ciphers(ssl);
-#else
- SSL_SESSION *session;
- if (!(session = SSL_get_session((SSL *)ssl))) {
- log_info(LD_NET, "No session on TLS?");
- return CIPHERS_ERR;
- }
- ciphers = session->ciphers;
-#endif /* defined(HAVE_SSL_GET_CLIENT_CIPHERS) */
-
- return tor_tls_classify_client_ciphers(ssl, ciphers) >= CIPHERS_V2;
-}
-
/** Invoked when we're accepting a connection on <b>ssl</b>, and the connection
* changes state. We use this:
* <ul><li>To alter the state of the handshake partway through, so we
}
/* Now check the cipher list. */
- if (tor_tls_client_is_using_v2_ciphers(ssl)) {
+ {
if (tls->wasV2Handshake)
return; /* We already turned this stuff off for the first handshake;
* This is a renegotiation. */
/* Yes, we're casting away the const from ssl. This is very naughty of us.
* Let's hope openssl doesn't notice! */
- /* Set SSL_MODE_NO_AUTO_CHAIN to keep from sending back any extra certs. */
- SSL_set_mode((SSL*) ssl, SSL_MODE_NO_AUTO_CHAIN);
- /* Don't send a hello request. */
- SSL_set_verify((SSL*) ssl, SSL_VERIFY_NONE, NULL);
-
if (tls) {
tls->wasV2Handshake = 1;
} else {
SSL_set_info_callback(tls->ssl, NULL);
SSL_set_verify(tls->ssl, SSL_VERIFY_PEER, always_accept_verify_cb);
SSL_clear_mode(tls->ssl, SSL_MODE_NO_AUTO_CHAIN);
- if (tor_tls_client_is_using_v2_ciphers(tls->ssl)) {
+ {
/* This check is redundant, but back when we did it in the callback,
* we might have not been able to look up the tor_tls_t if the code
* was buggy. Fixing that. */
tls->wasV2Handshake = 1;
log_debug(LD_HANDSHAKE, "Completed V2 TLS handshake with client; waiting"
" for renegotiation.");
- } else {
- tls->wasV2Handshake = 0;
}
} else {
/* Client-side */
tls_log_errors(NULL, LOG_WARN, LD_NET, NULL);
}
-/** Return true iff the initial TLS connection at <b>tls</b> did not use a v2
- * TLS handshake. Output is undefined if the handshake isn't finished. */
-int
-tor_tls_used_v1_handshake(tor_tls_t *tls)
-{
- return ! tls->wasV2Handshake;
-}
-
/** Return true iff the server TLS connection <b>tls</b> got the renegotiation
* request it was waiting for. */
int
tor_free(tls);
}
-static void
-test_tortls_used_v1_handshake(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- tls = tor_malloc_zero(sizeof(tor_tls_t));
-
- // These tests assume both V2 handshake server and client are enabled
- tls->wasV2Handshake = 0;
- ret = tor_tls_used_v1_handshake(tls);
- tt_int_op(ret, OP_EQ, 1);
-
- tls->wasV2Handshake = 1;
- ret = tor_tls_used_v1_handshake(tls);
- tt_int_op(ret, OP_EQ, 0);
-
- done:
- tor_free(tls);
-}
-
static void
test_tortls_server_got_renegotiate(void *ignored)
{
#ifdef ENABLE_OPENSSL
LOCAL_TEST_CASE(tor_tls_get_error, 0),
LOCAL_TEST_CASE(get_forced_write_size, 0),
- LOCAL_TEST_CASE(used_v1_handshake, TT_FORK),
LOCAL_TEST_CASE(server_got_renegotiate, 0),
#endif /* defined(ENABLE_OPENSSL) */
LOCAL_TEST_CASE(evaluate_ecgroup_for_tls, 0),
}
#endif /* !defined(OPENSSL_OPAQUE) */
-static void
-test_tortls_client_is_using_v2_ciphers(void *ignored)
-{
- (void)ignored;
-
-#ifdef HAVE_SSL_GET_CLIENT_CIPHERS
- tt_skip();
- done:
- (void)1;
-#else
- int ret;
- SSL_CTX *ctx;
- SSL *ssl;
- SSL_SESSION *sess;
- STACK_OF(SSL_CIPHER) *ciphers;
-
- library_init();
-
- ctx = SSL_CTX_new(TLSv1_method());
- ssl = SSL_new(ctx);
- sess = SSL_SESSION_new();
-
- ret = tor_tls_client_is_using_v2_ciphers(ssl);
- tt_int_op(ret, OP_EQ, -1);
-
- ssl->session = sess;
- ret = tor_tls_client_is_using_v2_ciphers(ssl);
- tt_int_op(ret, OP_EQ, 0);
-
- ciphers = sk_SSL_CIPHER_new_null();
- SSL_CIPHER *one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
- tt_assert(one);
- one->id = 0x00ff;
- sk_SSL_CIPHER_push(ciphers, one);
- sess->ciphers = ciphers;
- ret = tor_tls_client_is_using_v2_ciphers(ssl);
- tt_int_op(ret, OP_EQ, 1);
- done:
- SSL_free(ssl);
- SSL_CTX_free(ctx);
-#endif /* defined(HAVE_SSL_GET_CLIENT_CIPHERS) */
-}
-
#ifndef OPENSSL_OPAQUE
static int fixed_ssl_pending_result = 0;
INTRUSIVE_TEST_CASE(cert_get_key, 0),
INTRUSIVE_TEST_CASE(get_ciphersuite_name, 0),
INTRUSIVE_TEST_CASE(classify_client_ciphers, 0),
- LOCAL_TEST_CASE(client_is_using_v2_ciphers, 0),
INTRUSIVE_TEST_CASE(get_pending_bytes, 0),
INTRUSIVE_TEST_CASE(get_buffer_sizes, 0),
INTRUSIVE_TEST_CASE(try_to_extract_certs_from_tls, 0),