|
@@ -154,6 +154,7 @@ static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
|
|
|
const char *cname,
|
|
|
const char *cname_sign,
|
|
|
unsigned int lifetime);
|
|
|
+static void tor_tls_unblock_renegotiation(tor_tls_t *tls);
|
|
|
|
|
|
/** Global tls context. We keep it here because nobody else needs to
|
|
|
* touch it. */
|
|
@@ -904,6 +905,36 @@ tor_tls_set_renegotiate_callback(tor_tls_t *tls,
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+/** If this version of openssl requires it, turn on renegotiation on
|
|
|
+ * <b>tls</b>. (Our protocol never requires this for security, but it's nice
|
|
|
+ * to use belt-and-suspenders here.)
|
|
|
+ */
|
|
|
+static void
|
|
|
+tor_tls_unblock_renegotiation(tor_tls_t *tls)
|
|
|
+{
|
|
|
+#ifdef SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
|
|
|
+ /* Yes, we know what we are doing here. No, we do not treat a renegotiation
|
|
|
+ * as authenticating any earlier-received data. */
|
|
|
+ tls->ssl->s3->flags |= SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
|
|
|
+#else
|
|
|
+ (void)tls;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+/** If this version of openssl supports it, turn off renegotiation on
|
|
|
+ * <b>tls</b>. (Our protocol never requires this for security, but it's nice
|
|
|
+ * to use belt-and-suspenders here.)
|
|
|
+ */
|
|
|
+void
|
|
|
+tor_tls_block_renegotiation(tor_tls_t *tls)
|
|
|
+{
|
|
|
+#ifdef SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
|
|
|
+ tls->ssl->s3->flags &= ~SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
|
|
|
+#else
|
|
|
+ (void)tls;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
/** Return whether this tls initiated the connect (client) or
|
|
|
* received it (server). */
|
|
|
int
|
|
@@ -1026,6 +1057,9 @@ tor_tls_handshake(tor_tls_t *tls)
|
|
|
} else {
|
|
|
r = SSL_connect(tls->ssl);
|
|
|
}
|
|
|
+ /* We need to call this here and not earlier, since OpenSSL has a penchant
|
|
|
+ * for clearing its flags when you say accept or connect. */
|
|
|
+ tor_tls_unblock_renegotiation(tls);
|
|
|
r = tor_tls_get_error(tls,r,0, "handshaking", LOG_INFO);
|
|
|
if (ERR_peek_error() != 0) {
|
|
|
tls_log_errors(tls, tls->isServer ? LOG_INFO : LOG_WARN,
|