From bbf2fee8ff7bbb8f645b7d973cd84bc97e93ae54 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 2 Jun 2011 12:32:59 -0400 Subject: [PATCH] Reject 128-byte keys that are not 1024-bit When we added the check for key size, we required that the keys be 128 bytes. But RSA_size (which defers to BN_num_bytes) will return 128 for keys of length 1017..1024. This patch adds a new crypto_pk_num_bits() that returns the actual number of significant bits in the modulus, and uses that to enforce key sizes. Also, credit the original bug3318 in the changes file. --- changes/bug3318 | 6 +++++- src/common/crypto.c | 11 +++++++++++ src/common/crypto.h | 1 + src/or/routerparse.c | 4 ++-- src/test/test_crypto.c | 2 ++ 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/changes/bug3318 b/changes/bug3318 index 38991c4b1d..8a3c27825f 100644 --- a/changes/bug3318 +++ b/changes/bug3318 @@ -1,3 +1,7 @@ o Minor bugfixes: - Fix a log message that said "bits" while displaying a value in - bytes. Fixes bug 3318; bugfix on 0.2.0.1-alpha. + bytes. Found by wanoskarnet. Fixes bug 3318; bugfix on + 0.2.0.1-alpha. + - When checking for 1024-bit keys, check for 1024 bits, not 128 + bytes. This allows Tor to correctly discard keys of length + 1017 through 1023. Bugfix on 0.0.9pre5. diff --git a/src/common/crypto.c b/src/common/crypto.c index 1ecc24ce23..d8e6619c9f 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -777,6 +777,17 @@ crypto_pk_keysize(crypto_pk_env_t *env) return (size_t) RSA_size(env->key); } +/** Return the size of the public key modulus of env, in bits. */ +int +crypto_pk_num_bits(crypto_pk_env_t *env) +{ + tor_assert(env); + tor_assert(env->key); + tor_assert(env->key->n); + + return BN_num_bits(env->key->n); +} + /** Increase the reference count of env, and return it. */ crypto_pk_env_t * diff --git a/src/common/crypto.h b/src/common/crypto.h index 54c7a67a3b..1a8c81f837 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -119,6 +119,7 @@ int crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env, int crypto_pk_check_key(crypto_pk_env_t *env); int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b); size_t crypto_pk_keysize(crypto_pk_env_t *env); +int crypto_pk_num_bits(crypto_pk_env_t *env); crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig); crypto_pk_env_t *crypto_pk_copy_full(crypto_pk_env_t *orig); int crypto_pk_key_is_private(const crypto_pk_env_t *key); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 3728e9932b..f855f9d027 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -3765,9 +3765,9 @@ token_check_object(memarea_t *area, const char *kwd, break; case NEED_KEY_1024: /* There must be a 1024-bit public key. */ case NEED_SKEY_1024: /* There must be a 1024-bit private key. */ - if (tok->key && crypto_pk_keysize(tok->key) != PK_BYTES) { + if (tok->key && crypto_pk_num_bits(tok->key) != PK_BYTES*8) { tor_snprintf(ebuf, sizeof(ebuf), "Wrong size on key for %s: %d bits", - kwd, (int)crypto_pk_keysize(tok->key)*8); + kwd, crypto_pk_num_bits(tok->key)); RET_ERR(ebuf); } /* fall through */ diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c index bf2cc48174..121af279c7 100644 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@ -343,7 +343,9 @@ test_crypto_pk(void) test_eq(0, crypto_pk_cmp_keys(pk1, pk2)); test_eq(128, crypto_pk_keysize(pk1)); + test_eq(1024, crypto_pk_num_bits(pk1)); test_eq(128, crypto_pk_keysize(pk2)); + test_eq(1024, crypto_pk_num_bits(pk2)); test_eq(128, crypto_pk_public_encrypt(pk2, data1, sizeof(data1), "Hello whirled.", 15,