diff options
author | Nick Mathewson <nickm@torproject.org> | 2008-12-18 05:28:27 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2008-12-18 05:28:27 +0000 |
commit | cebdf93949c4dc203aca700705dc4032917db96c (patch) | |
tree | cf2c2e635728fe1d69cd9d8868542820f5f0de40 /src | |
parent | 7b5be147ee8ddbbddf866cb94600fde65f12f621 (diff) | |
download | tor-cebdf93949c4dc203aca700705dc4032917db96c.tar.gz tor-cebdf93949c4dc203aca700705dc4032917db96c.zip |
Fix bug 889: share deep-copied keys between threads to avoid races in reference counts. Bugfix on 0.1.0.1-rc.
svn:r17672
Diffstat (limited to 'src')
-rw-r--r-- | src/common/crypto.c | 17 | ||||
-rw-r--r-- | src/common/crypto.h | 1 | ||||
-rw-r--r-- | src/or/router.c | 8 | ||||
-rw-r--r-- | src/or/test.c | 8 |
4 files changed, 30 insertions, 4 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c index f7874844d6..f35620a7a6 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -672,6 +672,23 @@ crypto_pk_dup_key(crypto_pk_env_t *env) return env; } +/** Make a real honest-to-goodness copy of <b>env</b>, and return it. */ +crypto_pk_env_t * +crypto_pk_copy_full(crypto_pk_env_t *env) +{ + RSA *new_key; + tor_assert(env); + tor_assert(env->key); + + if (PRIVATE_KEY_OK(env)) { + new_key = RSAPrivateKey_dup(env->key); + } else { + new_key = RSAPublicKey_dup(env->key); + } + + return _crypto_new_pk_env_rsa(new_key); +} + /** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key * in <b>env</b>, using the padding method <b>padding</b>. On success, * write the result to <b>to</b>, and return the number of bytes diff --git a/src/common/crypto.h b/src/common/crypto.h index a0ddd3da20..86dfa88076 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -92,6 +92,7 @@ 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); 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); int crypto_pk_public_encrypt(crypto_pk_env_t *env, char *to, diff --git a/src/or/router.c b/src/or/router.c index 37172c17ba..8211d68197 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -75,8 +75,8 @@ get_onion_key(void) return onionkey; } -/** Store a copy of the current onion key into *<b>key</b>, and a copy - * of the most recent onion key into *<b>last</b>. +/** Store a full copy of the current onion key into *<b>key</b>, and a full + * copy of the most recent onion key into *<b>last</b>. */ void dup_onion_keys(crypto_pk_env_t **key, crypto_pk_env_t **last) @@ -85,9 +85,9 @@ dup_onion_keys(crypto_pk_env_t **key, crypto_pk_env_t **last) tor_assert(last); tor_mutex_acquire(key_lock); tor_assert(onionkey); - *key = crypto_pk_dup_key(onionkey); + *key = crypto_pk_copy_full(onionkey); if (lastonionkey) - *last = crypto_pk_dup_key(lastonionkey); + *last = crypto_pk_copy_full(lastonionkey); else *last = NULL; tor_mutex_release(key_lock); diff --git a/src/or/test.c b/src/or/test.c index 050217c3a7..bac59b7834 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -740,6 +740,14 @@ test_crypto_pk(void) test_memeq(data1,data3,j); } } + + /* Try copy_full */ + crypto_free_pk_env(pk2); + pk2 = crypto_pk_copy_full(pk1); + test_assert(pk2 != NULL); + test_neq_ptr(pk1, pk2); + test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0); + done: if (pk1) crypto_free_pk_env(pk1); |