| 
					
				 | 
			
			
				@@ -53,6 +53,24 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define ADDR(tls) (((tls) && (tls)->address) ? tls->address : "peer") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* We redefine these so that we can run correctly even if the vendor gives us 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * a version of OpenSSL that does not match its header files.  (Apple: I am 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * looking at you.) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifndef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifndef SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x0010 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Does the run-time openssl version look like we need 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION? */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int use_unsafe_renegotiation_op = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Does the run-time openssl version look like we need 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION? */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int use_unsafe_renegotiation_flag = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** Structure holding the TLS state for a single connection. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 typedef struct tor_tls_context_t { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   int refcnt; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -333,8 +351,28 @@ static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 tor_tls_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (!tls_library_is_initialized) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    long version; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     SSL_library_init(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     SSL_load_error_strings(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    version = SSLeay(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (version >= 0x009070c0L && version < 0x00908000L) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      log_notice(LD_GENERAL, "OpenSSL %s looks like version 0.9.7l or later; " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 "I will use SSL3_FLAGS to enable renegotation", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 SSLeay_version(SSLEAY_VERSION)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      use_unsafe_renegotiation_flag = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      use_unsafe_renegotiation_op = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if (version >= 0x009080d0L) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      log_notice(LD_GENERAL, "OpenSSL %s looks like version 0.9.8m or later; " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 "I will use SSL_OP to enable renegotiation", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 SSLeay_version(SSLEAY_VERSION)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      use_unsafe_renegotiation_flag = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      use_unsafe_renegotiation_op = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      log_info(LD_GENERAL, "OpenSSL %s has version %lx", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               SSLeay_version(SSLEAY_VERSION), version); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tls_library_is_initialized = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -591,7 +629,6 @@ tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SSL_CTX_set_options(result->ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                       SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#ifdef SSL_OP_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. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    * 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -600,9 +637,10 @@ tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    * seems) broke anything that used SSL3_FLAGS_* for the purpose.  So we need 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    * to do both.) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  SSL_CTX_set_options(result->ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (use_unsafe_renegotiation_op) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SSL_CTX_set_options(result->ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* Don't actually allow compression; it uses ram and time, but the data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    * we transmit is all encrypted anyway. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (result->ctx->comp_methods) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -943,19 +981,16 @@ tor_tls_set_renegotiate_callback(tor_tls_t *tls, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** 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.) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <b>tls</b>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 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 (use_unsafe_renegotiation_flag) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tls->ssl->s3->flags |= SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** If this version of openssl supports it, turn off renegotiation on 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -965,11 +1000,7 @@ tor_tls_unblock_renegotiation(tor_tls_t *tls) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 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 
			 |