mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Detect and deny excess renegotiations attempts.
Switch 'server_handshake_count' from a uint8_t to 2 unsigned int bits. Since we won't ever be doing more than 3 handshakes, we don't need the extra space. Toggle tor_tls_t.got_renegotiate based on the server_handshake_count. Also assert that when we've done two handshakes as a server (the initial SSL handshake, and the renegotiation handshake) we've just renegotiated. Finally, in tor_tls_read() return an error if we see more than 2 handshakes.
This commit is contained in:
parent
4fd79f9def
commit
ecd239e3b5
@ -146,7 +146,7 @@ struct tor_tls_t {
|
||||
/** True iff we should call negotiated_callback when we're done reading. */
|
||||
unsigned int got_renegotiate:1;
|
||||
/** Incremented every time we start the server side of a handshake. */
|
||||
uint8_t server_handshake_count;
|
||||
unsigned int server_handshake_count:2;
|
||||
size_t wantwrite_n; /**< 0 normally, >0 if we returned wantwrite last
|
||||
* time. */
|
||||
/** Last values retrieved from BIO_number_read()/write(); see
|
||||
@ -1286,12 +1286,14 @@ tor_tls_client_is_using_v2_ciphers(const SSL *ssl, const char *address)
|
||||
static void
|
||||
tor_tls_got_server_hello(tor_tls_t *tls)
|
||||
{
|
||||
/* Check whether we're watching for renegotiates. If so, this is one! */
|
||||
if (tls->negotiated_callback)
|
||||
tls->got_renegotiate = 1;
|
||||
if (tls->server_handshake_count < 127) /*avoid any overflow possibility*/
|
||||
if (tls->server_handshake_count < 3)
|
||||
++tls->server_handshake_count;
|
||||
|
||||
if (tls->server_handshake_count == 2) {
|
||||
tor_assert(tls->negotiated_callback);
|
||||
tls->got_renegotiate = 1;
|
||||
}
|
||||
|
||||
/* Now check the cipher list. */
|
||||
if (tor_tls_client_is_using_v2_ciphers(tls->ssl, ADDR(tls))) {
|
||||
/*XXXX_TLS keep this from happening more than once! */
|
||||
@ -1625,6 +1627,14 @@ tor_tls_read(tor_tls_t *tls, char *cp, size_t len)
|
||||
tls->got_renegotiate = 0;
|
||||
|
||||
return r;
|
||||
} else if (tls->server_handshake_count > 2) {
|
||||
/* If we get more than 2 handshakes, it means that our peer is
|
||||
trying to re-renegotiate. Return an error. */
|
||||
tor_assert(tls->server_handshake_count == 3);
|
||||
|
||||
log_info(LD_NET, "Detected excess renegotiation from %s!", ADDR(tls));
|
||||
|
||||
return TOR_TLS_ERROR_MISC;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user