From 617843988cc7dc6ed51c4ac409abe26f5ead5ccf Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 12 Jun 2008 22:39:13 +0000 Subject: [PATCH] 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 --- ChangeLog | 8 +++ doc/TODO | 6 +- doc/spec/tor-spec.txt | 5 +- src/common/Makefile.am | 2 +- src/common/ciphers.inc | 143 +++++++++++++++++++++++++++++++++++++++ src/common/tortls.c | 180 ++++++++++++++++++++++++++++++++++++------------- 6 files changed, 292 insertions(+), 52 deletions(-) create mode 100644 src/common/ciphers.inc diff --git a/ChangeLog b/ChangeLog index eda67fec26..d9db9036b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/doc/TODO b/doc/TODO index 3e512e95d2..4532735a02 100644 --- a/doc/TODO +++ b/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 diff --git a/doc/spec/tor-spec.txt b/doc/spec/tor-spec.txt index b55e088e87..8e7bee3464 100644 --- a/doc/spec/tor-spec.txt +++ b/doc/spec/tor-spec.txt @@ -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 diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 56f3fabb6a..174d8ea99c 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -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 diff --git a/src/common/ciphers.inc b/src/common/ciphers.inc new file mode 100644 index 0000000000..37147e4bfe --- /dev/null +++ b/src/common/ciphers.inc @@ -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 diff --git a/src/common/tortls.c b/src/common/tortls.c index 752ff6f8f8..8edcb3d502 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -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 *ciphers 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 does 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; -- 2.11.4.GIT