Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
base repository: Yawning/tor
base: master
head repository: Yawning/tor
compare: bug15760
Checking mergeability… Don’t worry, you can still create the pull request.
  • 2 commits
  • 6 files changed
  • 0 comments
  • 1 contributor
Commits on Apr 23, 2015
OpenSSL 1.1.0 must be built with "enable-deprecated", and compiled with
`OPENSSL_USE_DEPRECATED` for this to work, so instead, use the newer
routine as appropriate.
WARNING:
 * This breaks v2 client/server support.
 * This breaks logging OpenSSL buffer statistics on SIGUSR1.
 * This breaks `AUTHENTICATE` cell processing.
Showing with 88 additions and 20 deletions.
  1. +3 −0 changes/bug15760
  2. +8 −0 src/common/crypto.c
  3. +66 −10 src/common/tortls.c
  4. +3 −3 src/common/tortls.h
  5. +2 −1 src/or/connection_or.c
  6. +6 −6 src/or/main.c
@@ -0,0 +1,3 @@
o Minor bugfixes (compilation):
- Compile correctly with (unreleased) OpenSSL 1.1.0 headers.
Addresses ticket 15760.
@@ -405,7 +405,11 @@ crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
void
crypto_thread_cleanup(void)
{
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
ERR_remove_thread_state(NULL);
#else
ERR_remove_state(0);
#endif
}

/** used by tortls.c: wrap an RSA* in a crypto_pk_t. */
@@ -2912,7 +2916,11 @@ int
crypto_global_cleanup(void)
{
EVP_cleanup();
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
ERR_remove_thread_state(NULL);
#else
ERR_remove_state(0);
#endif
ERR_free_strings();

if (dh_param_p)
@@ -81,8 +81,10 @@

/* Enable the "v2" TLS handshake.
*/
#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
#define V2_HANDSHAKE_SERVER
#define V2_HANDSHAKE_CLIENT
#endif

/* Copied from or.h */
#define LEGAL_NICKNAME_CHARACTERS \
@@ -1359,11 +1361,15 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime,
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
}
#ifndef OPENSSL_NO_COMP
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
/* Don't actually allow compression; it uses ram and time, but the data
* we transmit is all encrypted anyway. */
SSL_CTX_set_options(result->ctx, SSL_OP_NO_COMPRESSION);
#else
if (result->ctx->comp_methods)
result->ctx->comp_methods = NULL;
#endif
#endif
#ifdef SSL_MODE_RELEASE_BUFFERS
SSL_CTX_set_mode(result->ctx, SSL_MODE_RELEASE_BUFFERS);
#endif
@@ -1724,7 +1730,8 @@ tor_tls_server_info_callback(const SSL *ssl, int type, int val)
}
#endif

#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,0)
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,0) && \
OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
/** Callback to get invoked on a server after we've read the list of ciphers
* the client supports, but before we pick our own ciphersuite.
*
@@ -1766,6 +1773,7 @@ tor_tls_setup_session_secret_cb(tor_tls_t *tls)
#define tor_tls_setup_session_secret_cb(tls) STMT_NIL
#endif

#ifdef V2_HANDSHAKE_CLIENT
/** Explain which ciphers we're missing. */
static void
log_unsupported_ciphers(smartlist_t *unsupported)
@@ -1789,7 +1797,9 @@ log_unsupported_ciphers(smartlist_t *unsupported)
log_info(LD_NET, "The unsupported ciphers were: %s", joined);
tor_free(joined);
}
#endif

#ifdef V2_HANDSHAKE_CLIENT
/** Replace *<b>ciphers</b> with a new list of SSL ciphersuites: specifically,
* a list designed to mimic a common web browser. We might not be able to do
* that if OpenSSL doesn't support all the ciphers we want. Some of the
@@ -1803,7 +1813,6 @@ log_unsupported_ciphers(smartlist_t *unsupported)
static void
rectify_client_ciphers(STACK_OF(SSL_CIPHER) **ciphers)
{
#ifdef V2_HANDSHAKE_CLIENT
if (PREDICT_UNLIKELY(!CLIENT_CIPHER_STACK)) {
/* We need to set CLIENT_CIPHER_STACK to an array of the ciphers
* we want to use/advertise. */
@@ -1879,11 +1888,8 @@ rectify_client_ciphers(STACK_OF(SSL_CIPHER) **ciphers)
sk_SSL_CIPHER_free(*ciphers);
*ciphers = sk_SSL_CIPHER_dup(CLIENT_CIPHER_STACK);
tor_assert(*ciphers);

#else
(void)ciphers;
#endif
}
#endif

/** Create a new TLS object from a file descriptor, and a flag to
* determine whether it is functioning as a server.
@@ -1924,8 +1930,10 @@ tor_tls_new(int sock, int isServer)
tor_free(result);
goto err;
}
#ifdef V2_HANDSHAKE_CLIENT
if (!isServer)
rectify_client_ciphers(&result->ssl->cipher_list);
#endif
result->socket = sock;
bio = BIO_new_socket(sock, BIO_NOCLOSE);
if (! bio) {
@@ -2018,9 +2026,11 @@ tor_tls_unblock_renegotiation(tor_tls_t *tls)
{
/* Yes, we know what we are doing here. No, we do not treat a renegotiation
* as authenticating any earlier-received data. */
#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
if (use_unsafe_renegotiation_flag) {
tls->ssl->s3->flags |= SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
}
#endif
if (use_unsafe_renegotiation_op) {
SSL_set_options(tls->ssl,
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
@@ -2034,17 +2044,27 @@ tor_tls_unblock_renegotiation(tor_tls_t *tls)
void
tor_tls_block_renegotiation(tor_tls_t *tls)
{
tls->ssl->s3->flags &= ~SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
if (use_unsafe_renegotiation_flag) {
tls->ssl->s3->flags &= ~SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
}
#endif
if (use_unsafe_renegotiation_op) {
SSL_clear_options(tls->ssl,
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
}
}

/** Assert that the flags that allow legacy renegotiation are still set */
void
tor_tls_assert_renegotiation_unblocked(tor_tls_t *tls)
{
#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0)
if (use_unsafe_renegotiation_flag) {
tor_assert(0 != (tls->ssl->s3->flags &
SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
}
#endif
if (use_unsafe_renegotiation_op) {
long options = SSL_get_options(tls->ssl);
tor_assert(0 != (options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
@@ -2175,11 +2195,16 @@ tor_tls_handshake(tor_tls_t *tls)
{
int r;
int oldstate;
int newstate;
tor_assert(tls);
tor_assert(tls->ssl);
tor_assert(tls->state == TOR_TLS_ST_HANDSHAKE);
check_no_tls_errors();
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
oldstate = SSL_state(tls->ssl);
#else
oldstate = tls->ssl->state;
#endif
if (tls->isServer) {
log_debug(LD_HANDSHAKE, "About to call SSL_accept on %p (%s)", tls,
SSL_state_string_long(tls->ssl));
@@ -2189,7 +2214,12 @@ tor_tls_handshake(tor_tls_t *tls)
SSL_state_string_long(tls->ssl));
r = SSL_connect(tls->ssl);
}
if (oldstate != tls->ssl->state)
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
newstate = SSL_state(tls->ssl);
#else
newstate = tls->ssl->state;
#endif
if (oldstate != newstate)
log_debug(LD_HANDSHAKE, "After call, %p was in state %s",
tls, SSL_state_string_long(tls->ssl));
/* We need to call this here and not earlier, since OpenSSL has a penchant
@@ -2225,7 +2255,12 @@ tor_tls_finish_handshake(tor_tls_t *tls)
SSL_set_info_callback(tls->ssl, NULL);
SSL_set_verify(tls->ssl, SSL_VERIFY_PEER, always_accept_verify_cb);
/* There doesn't seem to be a clear OpenSSL API to clear mode flags. */
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
long mode = SSL_get_mode(tls->ssl);
SSL_set_mode(tls->ssl, mode & ~SSL_MODE_NO_AUTO_CHAIN);
#else
tls->ssl->mode &= ~SSL_MODE_NO_AUTO_CHAIN;
#endif
#ifdef V2_HANDSHAKE_SERVER
if (tor_tls_client_is_using_v2_ciphers(tls->ssl)) {
/* This check is redundant, but back when we did it in the callback,
@@ -2823,6 +2858,13 @@ tor_tls_server_got_renegotiate(tor_tls_t *tls)
int
tor_tls_get_tlssecrets(tor_tls_t *tls, uint8_t *secrets_out)
{
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
/* As far as I can tell there is no way to get this in OpenSSL 1.1.0. */
(void)tls;
(void)secrets_out;

return -1;
#else
#define TLSSECRET_MAGIC "Tor V3 handshake TLS cross-certification"
char buf[128];
size_t len;
@@ -2844,18 +2886,29 @@ tor_tls_get_tlssecrets(tor_tls_t *tls, uint8_t *secrets_out)
buf, len);
memwipe(buf, 0, sizeof(buf));
return 0;
#endif
}

/** Examine the amount of memory used and available for buffers in <b>tls</b>.
* Set *<b>rbuf_capacity</b> to the amount of storage allocated for the read
* buffer and *<b>rbuf_bytes</b> to the amount actually used.
* Set *<b>wbuf_capacity</b> to the amount of storage allocated for the write
* buffer and *<b>wbuf_bytes</b> to the amount actually used. */
void
* buffer and *<b>wbuf_bytes</b> to the amount actually used. Return 0 on
* success, -1 on failure. */
int
tor_tls_get_buffer_sizes(tor_tls_t *tls,
size_t *rbuf_capacity, size_t *rbuf_bytes,
size_t *wbuf_capacity, size_t *wbuf_bytes)
{
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
(void)tls;
(void)rbuf_capacity;
(void)rbuf_bytes;
(void)wbuf_capacity;
(void)wbuf_bytes;

return -1;
#else
if (tls->ssl->s3->rbuf.buf)
*rbuf_capacity = tls->ssl->s3->rbuf.len;
else
@@ -2866,6 +2919,9 @@ tor_tls_get_buffer_sizes(tor_tls_t *tls,
*wbuf_capacity = 0;
*rbuf_bytes = tls->ssl->s3->rbuf.left;
*wbuf_bytes = tls->ssl->s3->wbuf.left;

return 0;
#endif
}

#ifdef USE_BUFFEREVENTS
@@ -92,9 +92,9 @@ size_t tor_tls_get_forced_write_size(tor_tls_t *tls);
void tor_tls_get_n_raw_bytes(tor_tls_t *tls,
size_t *n_read, size_t *n_written);

void tor_tls_get_buffer_sizes(tor_tls_t *tls,
size_t *rbuf_capacity, size_t *rbuf_bytes,
size_t *wbuf_capacity, size_t *wbuf_bytes);
int tor_tls_get_buffer_sizes(tor_tls_t *tls,
size_t *rbuf_capacity, size_t *rbuf_bytes,
size_t *wbuf_capacity, size_t *wbuf_bytes);

MOCK_DECL(double, tls_get_write_overhead_ratio, (void));

@@ -2406,7 +2406,8 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn,
}

/* HMAC of clientrandom and serverrandom using master key : 32 octets */
tor_tls_get_tlssecrets(conn->tls, ptr);
if (tor_tls_get_tlssecrets(conn->tls, ptr) < 0)
return -1;
ptr += 32;

tor_assert(ptr - out == V3_AUTH_FIXED_PART_LEN);
@@ -2332,12 +2332,12 @@ dumpstats(int severity)
if (conn->type == CONN_TYPE_OR) {
or_connection_t *or_conn = TO_OR_CONN(conn);
if (or_conn->tls) {
tor_tls_get_buffer_sizes(or_conn->tls, &rbuf_cap, &rbuf_len,
&wbuf_cap, &wbuf_len);
tor_log(severity, LD_GENERAL,
"Conn %d: %d/%d bytes used on OpenSSL read buffer; "
"%d/%d bytes used on write buffer.",
i, (int)rbuf_len, (int)rbuf_cap, (int)wbuf_len, (int)wbuf_cap);
if (tor_tls_get_buffer_sizes(or_conn->tls, &rbuf_cap, &rbuf_len,
&wbuf_cap, &wbuf_len))
tor_log(severity, LD_GENERAL,
"Conn %d: %d/%d bytes used on OpenSSL read buffer; "
"%d/%d bytes used on write buffer.",
i, (int)rbuf_len, (int)rbuf_cap, (int)wbuf_len, (int)wbuf_cap);
}
}
}

No commit comments for this range