mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 13:53:31 +01:00
r16215@tombo: nickm | 2008-06-12 18:39:03 -0400
Implement code to manually force the OpenSSL client cipher list to match the one recommended in proposal 124, *even if* we do not know all those ciphers. This is a bit of a kludge, but it is at least decently well commented. svn:r15173
This commit is contained in:
parent
555450ba73
commit
617843988c
@ -19,6 +19,12 @@ Changes in version 0.2.1.1-alpha - 2008-??-??
|
||||
service, with the 30 seconds being the current voodoo saying that
|
||||
a descriptor is stable.
|
||||
|
||||
o Major features:
|
||||
- Modify the list of ciphers advertised by OpenSSL in client mode
|
||||
to even more closely resemble a common web browser. We cheat a
|
||||
little so that we can advertise ciphers that the locally
|
||||
installed OpenSSL doesn't know about.
|
||||
|
||||
o Minor features:
|
||||
- Allow separate log levels to be configured for different logging
|
||||
domains. For example, this allows one to log all notices, warnings,
|
||||
@ -68,6 +74,8 @@ Changes in version 0.2.1.1-alpha - 2008-??-??
|
||||
- Never use OpenSSL compression: it wastes RAM and CPU trying to
|
||||
compress cells, which are basically all encrypted, compressed, or
|
||||
both.
|
||||
- Use the TLS1 hostname extension to more closely resemble browser
|
||||
behavior.
|
||||
|
||||
o Code simplifications and refactoring:
|
||||
- Refactor code using connection_ap_handshake_attach_circuit() to
|
||||
|
6
doc/TODO
6
doc/TODO
@ -105,10 +105,10 @@ N - Take our draft research proposal for how to safely collect and
|
||||
. Test
|
||||
- More back-end work:
|
||||
N - Additional TLS-camouflage work (spoofing FF cipher suite, etc.)
|
||||
- spoof the cipher suites
|
||||
- spoof the extensions list
|
||||
o spoof the cipher suites
|
||||
o spoof the extensions list
|
||||
- red-team testing (a.k.a, look at a packet dump and compare),
|
||||
- investigate the feasibility of handing connections off to a
|
||||
. investigate the feasibility of handing connections off to a
|
||||
local apache if they don't look like Tor or if they don't
|
||||
portknock or whatever.
|
||||
- Get closer to downloading far fewer descriptors
|
||||
|
@ -174,7 +174,10 @@ see tor-design.pdf.
|
||||
handshake is complete, the initiator renegotiates the handshake, with each
|
||||
parties sending a two-certificate chain as in "certificates up-front".
|
||||
The initiator's ClientHello MUST include at least once ciphersuite not in
|
||||
the list above.
|
||||
the list above. The responder SHOULD NOT select any ciphersuite besides
|
||||
those in the list above.
|
||||
[The above "should not" is because some of the ciphers that
|
||||
clients list may be fake.]
|
||||
|
||||
In "backwards-compatible renegotiation", the connection initiator's
|
||||
ClientHello MUST include at least one ciphersuite other than those listed
|
||||
|
@ -13,4 +13,4 @@ libor_a_SOURCES = log.c util.c compat.c container.c mempool.c memarea.c \
|
||||
$(libor_extra_source)
|
||||
libor_crypto_a_SOURCES = crypto.c aes.c tortls.c torgzip.c
|
||||
|
||||
noinst_HEADERS = log.h crypto.h test.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h
|
||||
noinst_HEADERS = log.h crypto.h test.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h ciphers.inc
|
||||
|
143
src/common/ciphers.inc
Normal file
143
src/common/ciphers.inc
Normal file
@ -0,0 +1,143 @@
|
||||
/* This is an include file used to define the list of ciphers clients should
|
||||
* advertise. Before including it, you should define the CIPHER and XCPIHER
|
||||
* macros. */
|
||||
#ifdef TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
|
||||
CIPHER(0xc00a, TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc00a, TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA
|
||||
CIPHER(0xc014, TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc014, TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_RSA_WITH_AES_256_SHA
|
||||
CIPHER(0x0039, TLS1_TXT_DHE_RSA_WITH_AES_256_SHA)
|
||||
#else
|
||||
XCIPHER(0x0039, TLS1_TXT_DHE_RSA_WITH_AES_256_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_DSS_WITH_AES_256_SHA
|
||||
CIPHER(0x0038, TLS1_TXT_DHE_DSS_WITH_AES_256_SHA)
|
||||
#else
|
||||
XCIPHER(0x0038, TLS1_TXT_DHE_DSS_WITH_AES_256_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA
|
||||
CIPHER(0xc00f, TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc00f, TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA
|
||||
CIPHER(0xc005, TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc005, TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_RSA_WITH_AES_256_SHA
|
||||
CIPHER(0x0035, TLS1_TXT_RSA_WITH_AES_256_SHA)
|
||||
#else
|
||||
XCIPHER(0x0035, TLS1_TXT_RSA_WITH_AES_256_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA
|
||||
CIPHER(0xc007, TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA)
|
||||
#else
|
||||
XCIPHER(0xc007, TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
|
||||
CIPHER(0xc009, TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc009, TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA
|
||||
CIPHER(0xc011, TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA)
|
||||
#else
|
||||
XCIPHER(0xc011, TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA
|
||||
CIPHER(0xc013, TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc013, TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_RSA_WITH_AES_128_SHA
|
||||
CIPHER(0x0033, TLS1_TXT_DHE_RSA_WITH_AES_128_SHA)
|
||||
#else
|
||||
XCIPHER(0x0033, TLS1_TXT_DHE_RSA_WITH_AES_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_DSS_WITH_AES_128_SHA
|
||||
CIPHER(0x0032, TLS1_TXT_DHE_DSS_WITH_AES_128_SHA)
|
||||
#else
|
||||
XCIPHER(0x0032, TLS1_TXT_DHE_DSS_WITH_AES_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA
|
||||
CIPHER(0xc00c, TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA)
|
||||
#else
|
||||
XCIPHER(0xc00c, TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA
|
||||
CIPHER(0xc00e, TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc00e, TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA
|
||||
CIPHER(0xc002, TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA)
|
||||
#else
|
||||
XCIPHER(0xc002, TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA
|
||||
CIPHER(0xc004, TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc004, TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA)
|
||||
#endif
|
||||
#ifdef SSL3_TXT_RSA_RC4_128_MD5
|
||||
CIPHER(0x0004, SSL3_TXT_RSA_RC4_128_MD5)
|
||||
#else
|
||||
XCIPHER(0x0004, SSL3_TXT_RSA_RC4_128_MD5)
|
||||
#endif
|
||||
#ifdef SSL3_TXT_RSA_RC4_128_SHA
|
||||
CIPHER(0x0005, SSL3_TXT_RSA_RC4_128_SHA)
|
||||
#else
|
||||
XCIPHER(0x0005, SSL3_TXT_RSA_RC4_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_RSA_WITH_AES_128_SHA
|
||||
CIPHER(0x002f, TLS1_TXT_RSA_WITH_AES_128_SHA)
|
||||
#else
|
||||
XCIPHER(0x002f, TLS1_TXT_RSA_WITH_AES_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA
|
||||
CIPHER(0xc008, TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0xc008, TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA
|
||||
CIPHER(0xc012, TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0xc012, TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
#ifdef SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA
|
||||
CIPHER(0x0016, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0x0016, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
#ifdef SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA
|
||||
CIPHER(0x0013, SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0x0013, SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA
|
||||
CIPHER(0xc00d, TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0xc00d, TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA
|
||||
CIPHER(0xc003, TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0xc003, TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
#ifdef SSL3_TXT_RSA_FIPS_WITH_3DES_EDE_CBC_SHA
|
||||
CIPHER(0xfeff, SSL3_TXT_RSA_FIPS_WITH_3DES_EDE_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xfeff, SSL3_TXT_RSA_FIPS_WITH_3DES_EDE_CBC_SHA)
|
||||
#endif
|
||||
#ifdef SSL3_TXT_RSA_DES_192_CBC3_SHA
|
||||
CIPHER(0x000a, SSL3_TXT_RSA_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0x000a, SSL3_TXT_RSA_DES_192_CBC3_SHA)
|
||||
#endif
|
@ -101,6 +101,16 @@ struct tor_tls_t {
|
||||
void *callback_arg;
|
||||
};
|
||||
|
||||
#ifdef V2_HANDSHAKE_CLIENT
|
||||
/** An array of fake SSL_CIPHER objects that we use in order to trick OpenSSL
|
||||
* in client mode into advertising the ciphers we want. See
|
||||
* rectify_client_ciphers for details. */
|
||||
static SSL_CIPHER *CLIENT_CIPHER_DUMMIES = NULL;
|
||||
/** A stack of SSL_CIPHER objects, some real, some fake.
|
||||
* See rectify_client_ciphers for details. */
|
||||
static STACK_OF(SSL_CIPHER) *CLIENT_CIPHER_STACK = NULL;
|
||||
#endif
|
||||
|
||||
/** Helper: compare tor_tls_t objects by its SSL. */
|
||||
static INLINE int
|
||||
tor_tls_entries_eq(const tor_tls_t *a, const tor_tls_t *b)
|
||||
@ -318,6 +328,12 @@ tor_tls_free_all(void)
|
||||
log_warn(LD_MM, "Still have entries in the tlsmap at shutdown.");
|
||||
}
|
||||
HT_CLEAR(tlsmap, &tlsmap_root);
|
||||
#ifdef V2_HANDSHAKE_CLIENT
|
||||
if (CLIENT_CIPHER_DUMMIES)
|
||||
tor_free(CLIENT_CIPHER_DUMMIES);
|
||||
if (CLIENT_CIPHER_STACK)
|
||||
sk_SSL_CIPHER_free(CLIENT_CIPHER_STACK);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** We need to give OpenSSL a callback to verify certificates. This is
|
||||
@ -427,58 +443,42 @@ tor_tls_create_certificate(crypto_pk_env_t *rsa,
|
||||
return x509;
|
||||
}
|
||||
|
||||
#define SERVER_CIPHER_LIST \
|
||||
(TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":" \
|
||||
TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" \
|
||||
/** List of ciphers that servers should select from.*/
|
||||
#define SERVER_CIPHER_LIST \
|
||||
(TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":" \
|
||||
TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" \
|
||||
SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
|
||||
/* Note: for setting up your own private testing network with link crypto
|
||||
* disabled, set the cipher lists to your cipher list to
|
||||
* SSL3_TXT_RSA_NULL_SHA. If you do this, you won't be able to communicate
|
||||
* with any of the "real" Tors, though. */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908020l
|
||||
#define CLIENT_CIPHER_LIST \
|
||||
(TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ":" \
|
||||
TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA ":" \
|
||||
TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":" \
|
||||
TLS1_TXT_DHE_DSS_WITH_AES_256_SHA ":" \
|
||||
TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA ":" \
|
||||
TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA ":" \
|
||||
TLS1_TXT_RSA_WITH_AES_256_SHA ":" \
|
||||
TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA ":" \
|
||||
TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ":" \
|
||||
TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA ":" \
|
||||
TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA ":" \
|
||||
TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" \
|
||||
TLS1_TXT_DHE_DSS_WITH_AES_128_SHA ":" \
|
||||
TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA":" \
|
||||
TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA":" \
|
||||
TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA ":" \
|
||||
TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA ":" \
|
||||
SSL3_TXT_RSA_RC4_128_MD5 ":" \
|
||||
SSL3_TXT_RSA_RC4_128_SHA ":" \
|
||||
TLS1_TXT_RSA_WITH_AES_128_SHA ":" \
|
||||
TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA ":" \
|
||||
TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA ":" \
|
||||
SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA ":" \
|
||||
SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA ":" \
|
||||
TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA ":" \
|
||||
TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA ":" \
|
||||
/*SSL3_TXT_RSA_FIPS_WITH_3DES_EDE_CBC_SHA ":"*/ \
|
||||
SSL3_TXT_RSA_DES_192_CBC3_SHA)
|
||||
/* SSL3_TXT_RSA_FIPS_WITH_3DES_EDE_CBC_SHA is commented out because it doesn't
|
||||
* really exist; if I understand correctly, it's a bit of silliness that
|
||||
* netscape did on its own before any standard for what they wanted was
|
||||
* formally approved. Nonetheless, Firefox still uses it, so we need to
|
||||
* fake it at some point soon. XXXX021 -NM */
|
||||
#else
|
||||
/* Ug. We don't have as many ciphers with openssl 0.9.7 as we'd like. Fix
|
||||
* this list into something that sucks less. */
|
||||
#define CLIENT_CIPHER_LIST \
|
||||
(TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":" \
|
||||
TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" \
|
||||
SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA ":" \
|
||||
SSL3_TXT_RSA_RC4_128_SHA)
|
||||
#ifdef V2_HANDSHAKE_CLIENT
|
||||
#define CIPHER(id, name) name ":"
|
||||
#define XCIPHER(id, name)
|
||||
/** List of ciphers that clients should advertise, omitting items that
|
||||
* our openssl doesn't know about. */
|
||||
static const char CLIENT_CIPHER_LIST[] =
|
||||
#include "./ciphers.inc"
|
||||
;
|
||||
#undef CIPHER
|
||||
#undef XCIPHER
|
||||
|
||||
/** Holds a cipher that we want to advertise, and its 2-byte ID. */
|
||||
typedef struct cipher_info_t { unsigned id; const char *name; } cipher_info_t;
|
||||
/** A list of all the ciphers that clients should advertise, including items
|
||||
* that openssl might not know about. */
|
||||
static const cipher_info_t CLIENT_CIPHER_INFO_LIST[] = {
|
||||
#define CIPHER(id, name) { id, name },
|
||||
#define XCIPHER(id, name) { id, #name },
|
||||
#include "./ciphers.inc"
|
||||
#undef CIPHER
|
||||
#undef XCIPHER
|
||||
};
|
||||
|
||||
/** The length of CLIENT_CIPHER_INFO_LIST and CLIENT_CIPHER_DUMMIES. */
|
||||
static const int N_CLIENT_CIPHERS =
|
||||
sizeof(CLIENT_CIPHER_INFO_LIST)/sizeof(CLIENT_CIPHER_INFO_LIST[0]);
|
||||
#endif
|
||||
|
||||
#ifndef V2_HANDSHAKE_CLIENT
|
||||
@ -730,6 +730,76 @@ tor_tls_server_info_callback(const SSL *ssl, int type, int val)
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Replace *<b>ciphers</b> with a new list of SSL ciphersuites: specifically,
|
||||
* a list designed to mimic a common web browser. Some of the cipher in the
|
||||
* list won't actually be implemented by OpenSSL: that's okay so long as the
|
||||
* server doesn't select them, and the server won't select anything besides
|
||||
* what's in SERVER_CIPHER_LIST.
|
||||
*
|
||||
* [If the server <b>does</b> select a bogus cipher, we won't crash or
|
||||
* anything; we'll just fail later when we try to look up the cipher in
|
||||
* ssl->cipher_list_by_id.]
|
||||
*/
|
||||
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.*/
|
||||
int i = 0, j = 0;
|
||||
|
||||
/* First, create a dummy SSL_CIPHER for every cipher. */
|
||||
CLIENT_CIPHER_DUMMIES =
|
||||
tor_malloc_zero(sizeof(SSL_CIPHER)*N_CLIENT_CIPHERS);
|
||||
for (i=0; i < N_CLIENT_CIPHERS; ++i) {
|
||||
CLIENT_CIPHER_DUMMIES[i].valid = 1;
|
||||
CLIENT_CIPHER_DUMMIES[i].id = CLIENT_CIPHER_INFO_LIST[i].id | (3<<24);
|
||||
CLIENT_CIPHER_DUMMIES[i].name = CLIENT_CIPHER_INFO_LIST[i].name;
|
||||
}
|
||||
|
||||
CLIENT_CIPHER_STACK = sk_SSL_CIPHER_new_null();
|
||||
tor_assert(CLIENT_CIPHER_STACK);
|
||||
|
||||
log_debug(LD_NET, "List was: %s", CLIENT_CIPHER_LIST);
|
||||
for (j = 0; j < sk_SSL_CIPHER_num(*ciphers); ++j) {
|
||||
SSL_CIPHER *cipher = sk_SSL_CIPHER_value(*ciphers, j);
|
||||
log_debug(LD_NET, "Cipher %d: %lx %s", j, cipher->id, cipher->name);
|
||||
}
|
||||
|
||||
/* Then copy as many ciphers as we can from the good list, inserting
|
||||
* dummies as needed. */
|
||||
j=0;
|
||||
for (i = 0; i < N_CLIENT_CIPHERS; ) {
|
||||
SSL_CIPHER *cipher = NULL;
|
||||
if (j < sk_SSL_CIPHER_num(*ciphers))
|
||||
cipher = sk_SSL_CIPHER_value(*ciphers, j);
|
||||
if (cipher && ((cipher->id >> 24) & 0xff) != 3) {
|
||||
log_debug(LD_NET, "Skipping v2 cipher %s", cipher->name);
|
||||
++j;
|
||||
} else if (cipher &&
|
||||
(cipher->id & 0xffff) == CLIENT_CIPHER_INFO_LIST[i].id) {
|
||||
log_debug(LD_NET, "Found cipher %s", cipher->name);
|
||||
sk_SSL_CIPHER_push(CLIENT_CIPHER_STACK, cipher);
|
||||
++j;
|
||||
++i;
|
||||
} else {
|
||||
log_debug(LD_NET, "Inserting fake %s", CLIENT_CIPHER_DUMMIES[i].name);
|
||||
sk_SSL_CIPHER_push(CLIENT_CIPHER_STACK, &CLIENT_CIPHER_DUMMIES[i]);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sk_SSL_CIPHER_free(*ciphers);
|
||||
*ciphers = sk_SSL_CIPHER_dup(CLIENT_CIPHER_STACK);
|
||||
tor_assert(*ciphers);
|
||||
|
||||
#else
|
||||
(void)ciphers;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Create a new TLS object from a file descriptor, and a flag to
|
||||
* determine whether it is functioning as a server.
|
||||
*/
|
||||
@ -745,12 +815,25 @@ tor_tls_new(int sock, int isServer)
|
||||
tor_free(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef SSL_set_tlsext_host_name
|
||||
/* Browsers use the TLS hostname extension, so we should too. */
|
||||
{
|
||||
char *fake_hostname = crypto_random_hostname(4,25, "www.",".com");
|
||||
SSL_set_tlsext_host_name(result->ssl, fake_hostname);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!SSL_set_cipher_list(result->ssl,
|
||||
isServer ? SERVER_CIPHER_LIST : CLIENT_CIPHER_LIST)) {
|
||||
tls_log_errors(NULL, LOG_WARN, "setting ciphers");
|
||||
log_warn(LD_NET, "WTF?");
|
||||
SSL_free(result->ssl);
|
||||
tor_free(result);
|
||||
return NULL;
|
||||
}
|
||||
if (!isServer)
|
||||
rectify_client_ciphers(&result->ssl->cipher_list);
|
||||
result->socket = sock;
|
||||
#ifdef USE_BSOCKETS
|
||||
bio = BIO_new_bsocket(sock, BIO_NOCLOSE);
|
||||
@ -982,7 +1065,10 @@ tor_tls_handshake(tor_tls_t *tls)
|
||||
if (cert)
|
||||
X509_free(cert);
|
||||
#endif
|
||||
SSL_set_cipher_list(tls->ssl, SERVER_CIPHER_LIST);
|
||||
if (SSL_set_cipher_list(tls->ssl, SERVER_CIPHER_LIST) == 0) {
|
||||
tls_log_errors(NULL, LOG_WARN, "re-setting ciphers");
|
||||
r = TOR_TLS_ERROR_MISC;
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
|
Loading…
Reference in New Issue
Block a user