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.
This commit is contained in:
Karsten Loesing 2009-10-25 23:47:05 -07:00
parent fa23430496
commit d2b4b49ff0
6 changed files with 23 additions and 19 deletions

View File

@ -122,7 +122,7 @@ struct crypto_dh_env_t {
}; };
static int setup_openssl_threading(void); 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>. /** 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"); crypto_log_errors(LOG_WARN, "generating DH key");
return -1; 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-" log_warn(LD_CRYPTO, "Weird! Our own DH key was invalid. I guess once-in-"
"the-universe chances really do happen. Trying again."); "the-universe chances really do happen. Trying again.");
/* Free and clear the keys, so OpenSSL will actually try 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. * See http://www.cl.cam.ac.uk/ftp/users/rja14/psandqs.ps.gz for some tips.
*/ */
static int static int
tor_check_dh_key(BIGNUM *bn) tor_check_dh_key(int severity, BIGNUM *bn)
{ {
BIGNUM *x; BIGNUM *x;
char *s; char *s;
@ -1781,13 +1781,13 @@ tor_check_dh_key(BIGNUM *bn)
init_dh_param(); init_dh_param();
BN_set_word(x, 1); BN_set_word(x, 1);
if (BN_cmp(bn,x)<=0) { 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; goto err;
} }
BN_copy(x,dh_param_p); BN_copy(x,dh_param_p);
BN_sub_word(x, 1); BN_sub_word(x, 1);
if (BN_cmp(bn,x)>=0) { 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; goto err;
} }
BN_free(x); BN_free(x);
@ -1795,7 +1795,7 @@ tor_check_dh_key(BIGNUM *bn)
err: err:
BN_free(x); BN_free(x);
s = BN_bn2hex(bn); 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); OPENSSL_free(s);
return -1; return -1;
} }
@ -1813,7 +1813,7 @@ tor_check_dh_key(BIGNUM *bn)
* where || is concatenation.) * where || is concatenation.)
*/ */
ssize_t 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, const char *pubkey, size_t pubkey_len,
char *secret_out, size_t secret_bytes_out) 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, if (!(pubkey_bn = BN_bin2bn((const unsigned char*)pubkey,
(int)pubkey_len, NULL))) (int)pubkey_len, NULL)))
goto error; goto error;
if (tor_check_dh_key(pubkey_bn)<0) { if (tor_check_dh_key(severity, pubkey_bn)<0) {
/* Check for invalid public keys. */ /* Check for invalid public keys. */
log_warn(LD_CRYPTO,"Rejected invalid g^x"); log_fn(severity, LD_CRYPTO,"Rejected invalid g^x");
goto error; goto error;
} }
secret_tmp = tor_malloc(crypto_dh_get_bytes(dh)); secret_tmp = tor_malloc(crypto_dh_get_bytes(dh));

View File

@ -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_generate_public(crypto_dh_env_t *dh);
int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey_out, int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey_out,
size_t pubkey_out_len); 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, const char *pubkey, size_t pubkey_len,
char *secret_out, size_t secret_out_len); char *secret_out, size_t secret_out_len);
void crypto_dh_free(crypto_dh_env_t *dh); void crypto_dh_free(crypto_dh_env_t *dh);

View File

@ -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_len = DIGEST_LEN+key_out_len;
key_material = tor_malloc(key_material_len); key_material = tor_malloc(key_material_len);
len = crypto_dh_compute_secret(dh, challenge, DH_KEY_LEN, len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, dh, challenge,
key_material, key_material_len); DH_KEY_LEN, key_material,
key_material_len);
if (len < 0) { if (len < 0) {
log_info(LD_GENERAL, "crypto_dh_compute_secret failed."); log_info(LD_GENERAL, "crypto_dh_compute_secret failed.");
goto err; 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_len = DIGEST_LEN + key_out_len;
key_material = tor_malloc(key_material_len); key_material = tor_malloc(key_material_len);
len = crypto_dh_compute_secret(handshake_state, handshake_reply, DH_KEY_LEN, len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, handshake_state,
key_material, key_material_len); handshake_reply, DH_KEY_LEN, key_material,
key_material_len);
if (len < 0) if (len < 0)
goto err; goto err;

View File

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

View File

@ -1090,7 +1090,8 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
reason = END_CIRC_REASON_INTERNAL; reason = END_CIRC_REASON_INTERNAL;
goto err; 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) { DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
log_warn(LD_BUG, "Internal error: couldn't complete DH handshake"); log_warn(LD_BUG, "Internal error: couldn't complete DH handshake");
reason = END_CIRC_REASON_INTERNAL; reason = END_CIRC_REASON_INTERNAL;

View File

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