diff options
Diffstat (limited to 'src/common/tortls.c')
-rw-r--r-- | src/common/tortls.c | 145 |
1 files changed, 40 insertions, 105 deletions
diff --git a/src/common/tortls.c b/src/common/tortls.c index 89ad6af939..d61cc2e58a 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -24,18 +24,11 @@ #include <ws2tcpip.h> #endif -#ifdef __GNUC__ -#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -#endif +#include "compat.h" -#if __GNUC__ && GCC_VERSION >= 402 -#if GCC_VERSION >= 406 -#pragma GCC diagnostic push -#endif /* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in * srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */ -#pragma GCC diagnostic ignored "-Wredundant-decls" -#endif +DISABLE_GCC_WARNING(redundant-decls) #include <openssl/opensslv.h> #include "crypto.h" @@ -53,20 +46,7 @@ #include <openssl/bn.h> #include <openssl/rsa.h> -#if __GNUC__ && GCC_VERSION >= 402 -#if GCC_VERSION >= 406 -#pragma GCC diagnostic pop -#else -#pragma GCC diagnostic warning "-Wredundant-decls" -#endif -#endif - -#ifdef USE_BUFFEREVENTS -#include <event2/bufferevent_ssl.h> -#include <event2/buffer.h> -#include <event2/event.h> -#include "compat_libevent.h" -#endif +ENABLE_GCC_WARNING(redundant-decls) #define TORTLS_PRIVATE #include "tortls.h" @@ -572,12 +552,11 @@ MOCK_IMPL(STATIC X509 *, * claiming extra unsupported ciphers in order to avoid fingerprinting. */ #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) + TLS1_TXT_DHE_RSA_WITH_AES_128_SHA) /** List of ciphers that servers should select from when we actually have * our choice of what cipher to use. */ -const char UNRESTRICTED_SERVER_CIPHER_LIST[] = +static const char UNRESTRICTED_SERVER_CIPHER_LIST[] = /* This list is autogenerated with the gen_server_ciphers.py script; * don't hand-edit it. */ #ifdef TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 @@ -613,12 +592,8 @@ const char UNRESTRICTED_SERVER_CIPHER_LIST[] = /* Required */ TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":" /* Required */ - TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" -#ifdef TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA - TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA ":" -#endif - /* Required */ - SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA; + TLS1_TXT_DHE_RSA_WITH_AES_128_SHA + ; /* Note: to set up your own private testing network with link crypto * disabled, set your Tors' cipher list to @@ -702,6 +677,15 @@ MOCK_IMPL(STATIC tor_x509_cert_t *, return cert; } +/** Return a new copy of <b>cert</b>. */ +tor_x509_cert_t * +tor_x509_cert_dup(const tor_x509_cert_t *cert) +{ + tor_assert(cert); + X509 *x509 = cert->cert; + return tor_x509_cert_new(X509_dup(x509)); +} + /** Read a DER-encoded X509 cert, of length exactly <b>certificate_len</b>, * from a <b>certificate</b>. Return a newly allocated tor_x509_cert_t on * success and NULL on failure. */ @@ -1509,6 +1493,10 @@ tor_tls_server_info_callback(const SSL *ssl, int type, int val) tor_tls_t *tls; (void) val; + IF_BUG_ONCE(ssl == NULL) { + return; // LCOV_EXCL_LINE + } + tor_tls_debug_state_callback(ssl, type, val); if (type != SSL_CB_ACCEPT_LOOP) @@ -2030,7 +2018,8 @@ tor_tls_peer_has_cert(tor_tls_t *tls) return 1; } -/** Return the peer certificate, or NULL if there isn't one. */ +/** Return a newly allocated copy of the peer certificate, or NULL if there + * isn't one. */ MOCK_IMPL(tor_x509_cert_t *, tor_tls_get_peer_cert,(tor_tls_t *tls)) { @@ -2042,6 +2031,24 @@ tor_tls_get_peer_cert,(tor_tls_t *tls)) return tor_x509_cert_new(cert); } +/** Return a newly allocated copy of the cerficate we used on the connection, + * or NULL if somehow we didn't use one. */ +MOCK_IMPL(tor_x509_cert_t *, +tor_tls_get_own_cert,(tor_tls_t *tls)) +{ + X509 *cert = SSL_get_certificate(tls->ssl); + tls_log_errors(tls, LOG_WARN, LD_HANDSHAKE, + "getting own-connection certificate"); + if (!cert) + return NULL; + /* Fun inconsistency: SSL_get_peer_certificate increments the reference + * count, but SSL_get_certificate does not. */ + X509 *duplicate = X509_dup(cert); + if (BUG(duplicate == NULL)) + return NULL; + return tor_x509_cert_new(duplicate); +} + /** Warn that a certificate lifetime extends through a certain range. */ static void log_cert_lifetime(int severity, const X509 *cert, const char *problem) @@ -2499,78 +2506,6 @@ tor_tls_get_buffer_sizes(tor_tls_t *tls, #endif } -#ifdef USE_BUFFEREVENTS -/** Construct and return an TLS-encrypting bufferevent to send data over - * <b>socket</b>, which must match the socket of the underlying bufferevent - * <b>bufev_in</b>. The TLS object <b>tls</b> is used for encryption. - * - * This function will either create a filtering bufferevent that wraps around - * <b>bufev_in</b>, or it will free bufev_in and return a new bufferevent that - * uses the <b>tls</b> to talk to the network directly. Do not use - * <b>bufev_in</b> after calling this function. - * - * The connection will start out doing a server handshake if <b>receiving</b> - * is strue, and a client handshake otherwise. - * - * Returns NULL on failure. - */ -struct bufferevent * -tor_tls_init_bufferevent(tor_tls_t *tls, struct bufferevent *bufev_in, - evutil_socket_t socket, int receiving, - int filter) -{ - struct bufferevent *out; - const enum bufferevent_ssl_state state = receiving ? - BUFFEREVENT_SSL_ACCEPTING : BUFFEREVENT_SSL_CONNECTING; - - if (filter || tor_libevent_using_iocp_bufferevents()) { - /* Grab an extra reference to the SSL, since BEV_OPT_CLOSE_ON_FREE - means that the SSL will get freed too. - - This increment makes our SSL usage not-threadsafe, BTW. We should - see if we're allowed to use CRYPTO_add from outside openssl. */ - tls->ssl->references += 1; - out = bufferevent_openssl_filter_new(tor_libevent_get_base(), - bufev_in, - tls->ssl, - state, - BEV_OPT_DEFER_CALLBACKS| - BEV_OPT_CLOSE_ON_FREE); - /* Tell the underlying bufferevent when to accept more data from the SSL - filter (only when it's got less than 32K to write), and when to notify - the SSL filter that it could write more (when it drops under 24K). */ - bufferevent_setwatermark(bufev_in, EV_WRITE, 24*1024, 32*1024); - } else { - if (bufev_in) { - evutil_socket_t s = bufferevent_getfd(bufev_in); - tor_assert(s == -1 || s == socket); - tor_assert(evbuffer_get_length(bufferevent_get_input(bufev_in)) == 0); - tor_assert(evbuffer_get_length(bufferevent_get_output(bufev_in)) == 0); - tor_assert(BIO_number_read(SSL_get_rbio(tls->ssl)) == 0); - tor_assert(BIO_number_written(SSL_get_rbio(tls->ssl)) == 0); - bufferevent_free(bufev_in); - } - - /* Current versions (as of 2.0.x) of Libevent need to defer - * bufferevent_openssl callbacks, or else our callback functions will - * get called reentrantly, which is bad for us. - */ - out = bufferevent_openssl_socket_new(tor_libevent_get_base(), - socket, - tls->ssl, - state, - BEV_OPT_DEFER_CALLBACKS); - } - tls->state = TOR_TLS_ST_BUFFEREVENT; - - /* Unblock _after_ creating the bufferevent, since accept/connect tend to - * clear flags. */ - tor_tls_unblock_renegotiation(tls); - - return out; -} -#endif - /** Check whether the ECC group requested is supported by the current OpenSSL * library instance. Return 1 if the group is supported, and 0 if not. */ |