Browse Source

Reduce log level for someone else sending us weak DH keys.

See task 1114. The most plausible explanation for someone sending us weak
DH keys is that they experiment with their Tor code or implement a new Tor
client. Usually, we don't care about such events, especially not on warn
level. If we really care about someone not following the Tor protocol, we
can set ProtocolWarnings to 1.
Karsten Loesing 14 years ago
parent
commit
d2b4b49ff0
6 changed files with 23 additions and 19 deletions
  1. 9 9
      src/common/crypto.c
  2. 1 1
      src/common/crypto.h
  3. 6 4
      src/or/onion.c
  4. 3 2
      src/or/rendclient.c
  5. 2 1
      src/or/rendservice.c
  6. 2 2
      src/test/test_crypto.c

+ 9 - 9
src/common/crypto.c

@@ -122,7 +122,7 @@ struct crypto_dh_env_t {
 };
 
 static int setup_openssl_threading(void);
-static int tor_check_dh_key(BIGNUM *bn);
+static int tor_check_dh_key(int severity, BIGNUM *bn);
 
 /** Return the number of bytes added by padding method <b>padding</b>.
  */
@@ -1723,7 +1723,7 @@ crypto_dh_generate_public(crypto_dh_env_t *dh)
     crypto_log_errors(LOG_WARN, "generating DH key");
     return -1;
   }
-  if (tor_check_dh_key(dh->dh->pub_key)<0) {
+  if (tor_check_dh_key(LOG_WARN, dh->dh->pub_key)<0) {
     log_warn(LD_CRYPTO, "Weird! Our own DH key was invalid.  I guess once-in-"
              "the-universe chances really do happen.  Trying again.");
     /* Free and clear the keys, so OpenSSL will actually try again. */
@@ -1770,7 +1770,7 @@ crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey, size_t pubkey_len)
  * See http://www.cl.cam.ac.uk/ftp/users/rja14/psandqs.ps.gz for some tips.
  */
 static int
-tor_check_dh_key(BIGNUM *bn)
+tor_check_dh_key(int severity, BIGNUM *bn)
 {
   BIGNUM *x;
   char *s;
@@ -1781,13 +1781,13 @@ tor_check_dh_key(BIGNUM *bn)
     init_dh_param();
   BN_set_word(x, 1);
   if (BN_cmp(bn,x)<=0) {
-    log_warn(LD_CRYPTO, "DH key must be at least 2.");
+    log_fn(severity, LD_CRYPTO, "DH key must be at least 2.");
     goto err;
   }
   BN_copy(x,dh_param_p);
   BN_sub_word(x, 1);
   if (BN_cmp(bn,x)>=0) {
-    log_warn(LD_CRYPTO, "DH key must be at most p-2.");
+    log_fn(severity, LD_CRYPTO, "DH key must be at most p-2.");
     goto err;
   }
   BN_free(x);
@@ -1795,7 +1795,7 @@ tor_check_dh_key(BIGNUM *bn)
  err:
   BN_free(x);
   s = BN_bn2hex(bn);
-  log_warn(LD_CRYPTO, "Rejecting insecure DH key [%s]", s);
+  log_fn(severity, LD_CRYPTO, "Rejecting insecure DH key [%s]", s);
   OPENSSL_free(s);
   return -1;
 }
@@ -1813,7 +1813,7 @@ tor_check_dh_key(BIGNUM *bn)
  * where || is concatenation.)
  */
 ssize_t
-crypto_dh_compute_secret(crypto_dh_env_t *dh,
+crypto_dh_compute_secret(int severity, crypto_dh_env_t *dh,
                          const char *pubkey, size_t pubkey_len,
                          char *secret_out, size_t secret_bytes_out)
 {
@@ -1828,9 +1828,9 @@ crypto_dh_compute_secret(crypto_dh_env_t *dh,
   if (!(pubkey_bn = BN_bin2bn((const unsigned char*)pubkey,
                               (int)pubkey_len, NULL)))
     goto error;
-  if (tor_check_dh_key(pubkey_bn)<0) {
+  if (tor_check_dh_key(severity, pubkey_bn)<0) {
     /* Check for invalid public keys. */
-    log_warn(LD_CRYPTO,"Rejected invalid g^x");
+    log_fn(severity, LD_CRYPTO,"Rejected invalid g^x");
     goto error;
   }
   secret_tmp = tor_malloc(crypto_dh_get_bytes(dh));

+ 1 - 1
src/common/crypto.h

@@ -198,7 +198,7 @@ int crypto_dh_get_bytes(crypto_dh_env_t *dh);
 int crypto_dh_generate_public(crypto_dh_env_t *dh);
 int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey_out,
                          size_t pubkey_out_len);
-ssize_t crypto_dh_compute_secret(crypto_dh_env_t *dh,
+ssize_t crypto_dh_compute_secret(int severity, crypto_dh_env_t *dh,
                              const char *pubkey, size_t pubkey_len,
                              char *secret_out, size_t secret_out_len);
 void crypto_dh_free(crypto_dh_env_t *dh);

+ 6 - 4
src/or/onion.c

@@ -253,8 +253,9 @@ onion_skin_server_handshake(const char *onion_skin, /*ONIONSKIN_CHALLENGE_LEN*/
 
   key_material_len = DIGEST_LEN+key_out_len;
   key_material = tor_malloc(key_material_len);
-  len = crypto_dh_compute_secret(dh, challenge, DH_KEY_LEN,
-                                 key_material, key_material_len);
+  len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, dh, challenge,
+                                 DH_KEY_LEN, key_material,
+                                 key_material_len);
   if (len < 0) {
     log_info(LD_GENERAL, "crypto_dh_compute_secret failed.");
     goto err;
@@ -304,8 +305,9 @@ onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
 
   key_material_len = DIGEST_LEN + key_out_len;
   key_material = tor_malloc(key_material_len);
-  len = crypto_dh_compute_secret(handshake_state, handshake_reply, DH_KEY_LEN,
-                                 key_material, key_material_len);
+  len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, handshake_state,
+                                 handshake_reply, DH_KEY_LEN, key_material,
+                                 key_material_len);
   if (len < 0)
     goto err;
 

+ 3 - 2
src/or/rendclient.c

@@ -621,8 +621,9 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const char *request,
   tor_assert(circ->build_state->pending_final_cpath);
   hop = circ->build_state->pending_final_cpath;
   tor_assert(hop->dh_handshake_state);
-  if (crypto_dh_compute_secret(hop->dh_handshake_state, request, DH_KEY_LEN,
-                               keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
+  if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN, hop->dh_handshake_state,
+                               request, DH_KEY_LEN, keys,
+                               DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
     log_warn(LD_GENERAL, "Couldn't complete DH handshake.");
     goto err;
   }

+ 2 - 1
src/or/rendservice.c

@@ -1090,7 +1090,8 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
     reason = END_CIRC_REASON_INTERNAL;
     goto err;
   }
-  if (crypto_dh_compute_secret(dh, ptr+REND_COOKIE_LEN, DH_KEY_LEN, keys,
+  if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN, dh, ptr+REND_COOKIE_LEN,
+                               DH_KEY_LEN, keys,
                                DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
     log_warn(LD_BUG, "Internal error: couldn't complete DH handshake");
     reason = END_CIRC_REASON_INTERNAL;

+ 2 - 2
src/test/test_crypto.c

@@ -33,8 +33,8 @@ test_crypto_dh(void)
 
   memset(s1, 0, DH_BYTES);
   memset(s2, 0xFF, DH_BYTES);
-  s1len = crypto_dh_compute_secret(dh1, p2, DH_BYTES, s1, 50);
-  s2len = crypto_dh_compute_secret(dh2, p1, DH_BYTES, s2, 50);
+  s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p2, DH_BYTES, s1, 50);
+  s2len = crypto_dh_compute_secret(LOG_WARN, dh2, p1, DH_BYTES, s2, 50);
   test_assert(s1len > 0);
   test_eq(s1len, s2len);
   test_memeq(s1, s2, s1len);