aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Ransom <rransom.8774@gmail.com>2010-10-03 22:38:53 -0700
committerSebastian Hahn <sebastian@torproject.org>2011-10-26 14:16:20 +0200
commit59e565e2a258f6ca78273585187ff0ab9052cbe7 (patch)
treed365a32199bcede1027dd435d475abe53368cc1a
parent299a78c5fed3447a450cea3d4f686c2140c7aaed (diff)
downloadtor-59e565e2a258f6ca78273585187ff0ab9052cbe7.tar.gz
tor-59e565e2a258f6ca78273585187ff0ab9052cbe7.zip
Maintain separate server and client identity keys when appropriate.
Fixes a bug described in ticket #988. Conflicts: src/or/main.c src/or/router.c
-rw-r--r--src/or/connection_or.c5
-rw-r--r--src/or/dirserv.c7
-rw-r--r--src/or/hibernate.c4
-rw-r--r--src/or/main.c8
-rw-r--r--src/or/or.h9
-rw-r--r--src/or/router.c119
6 files changed, 105 insertions, 47 deletions
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index d402563fb5..7817db89c3 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -961,6 +961,9 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
const char *safe_address =
started_here ? conn->_base.address : safe_str(conn->_base.address);
const char *conn_type = started_here ? "outgoing" : "incoming";
+ crypto_pk_env_t *our_identity =
+ started_here ? get_client_identity_key() :
+ get_server_identity_key();
int has_cert = 0, has_identity=0;
check_no_tls_errors();
@@ -997,7 +1000,7 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
if (identity_rcvd) {
has_identity = 1;
crypto_pk_get_digest(identity_rcvd, digest_rcvd_out);
- if (crypto_pk_cmp_keys(get_identity_key(), identity_rcvd)<0) {
+ if (crypto_pk_cmp_keys(our_identity, identity_rcvd)<0) {
conn->circ_id_type = CIRC_ID_TYPE_LOWER;
} else {
conn->circ_id_type = CIRC_ID_TYPE_HIGHER;
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index e367cb1c3a..46775805cd 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -1520,7 +1520,8 @@ dirserv_regenerate_directory(void)
{
char *new_directory=NULL;
- if (dirserv_dump_directory_to_string(&new_directory, get_identity_key())) {
+ if (dirserv_dump_directory_to_string(&new_directory,
+ get_server_identity_key())) {
log_warn(LD_BUG, "Error creating directory.");
tor_free(new_directory);
return NULL;
@@ -1550,7 +1551,7 @@ generate_runningrouters(void)
char digest[DIGEST_LEN];
char published[ISO_TIME_LEN+1];
size_t len;
- crypto_pk_env_t *private_key = get_identity_key();
+ crypto_pk_env_t *private_key = get_server_identity_key();
char *identity_pkey; /* Identity key, DER64-encoded. */
size_t identity_pkey_len;
@@ -2441,7 +2442,7 @@ generate_v2_networkstatus_opinion(void)
smartlist_t *routers = NULL;
digestmap_t *omit_as_sybil = NULL;
- private_key = get_identity_key();
+ private_key = get_server_identity_key();
if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
log_warn(LD_NET, "Couldn't resolve my hostname");
diff --git a/src/or/hibernate.c b/src/or/hibernate.c
index 9ec63756fa..04e06c8164 100644
--- a/src/or/hibernate.c
+++ b/src/or/hibernate.c
@@ -456,7 +456,7 @@ accounting_set_wakeup_time(void)
uint64_t time_to_exhaust_bw;
int time_to_consider;
- if (! identity_key_is_set()) {
+ if (! server_identity_key_is_set()) {
if (init_keys() < 0) {
log_err(LD_BUG, "Error initializing keys");
tor_assert(0);
@@ -464,7 +464,7 @@ accounting_set_wakeup_time(void)
}
format_iso_time(buf, interval_start_time);
- crypto_pk_get_digest(get_identity_key(), digest);
+ crypto_pk_get_digest(get_server_identity_key(), digest);
d_env = crypto_new_digest_env();
crypto_digest_add_bytes(d_env, buf, ISO_TIME_LEN);
diff --git a/src/or/main.c b/src/or/main.c
index 00fce80024..466801cb33 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -874,8 +874,8 @@ run_scheduled_events(time_t now)
if (last_rotated_x509_certificate+MAX_SSL_KEY_LIFETIME_INTERNAL < now) {
log_info(LD_GENERAL,"Rotating tls context.");
if (tor_tls_context_init(public_server_mode(options),
- get_identity_key(),
- is_server ? get_identity_key() : NULL,
+ get_client_identity_key(),
+ is_server ? get_server_identity_key() : NULL,
MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) {
log_warn(LD_BUG, "Error reinitializing TLS context");
/* XXX is it a bug here, that we just keep going? -RD */
@@ -1390,7 +1390,7 @@ do_main_loop(void)
/* load the private keys, if we're supposed to have them, and set up the
* TLS context. */
- if (! identity_key_is_set()) {
+ if (! client_identity_key_is_set()) {
if (init_keys() < 0) {
log_err(LD_BUG,"Error initializing keys; exiting");
return -1;
@@ -2020,7 +2020,7 @@ do_list_fingerprint(void)
log_err(LD_BUG,"Error initializing keys; can't display fingerprint");
return -1;
}
- if (!(k = get_identity_key())) {
+ if (!(k = get_server_identity_key())) {
log_err(LD_GENERAL,"Error: missing identity key.");
return -1;
}
diff --git a/src/or/or.h b/src/or/or.h
index f40511330a..a594d6f891 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -4205,9 +4205,12 @@ int rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request,
crypto_pk_env_t *get_onion_key(void);
time_t get_onion_key_set_at(void);
-void set_identity_key(crypto_pk_env_t *k);
-crypto_pk_env_t *get_identity_key(void);
-int identity_key_is_set(void);
+void set_client_identity_key(crypto_pk_env_t *k);
+void set_server_identity_key(crypto_pk_env_t *k);
+crypto_pk_env_t *get_client_identity_key(void);
+crypto_pk_env_t *get_server_identity_key(void);
+int client_identity_key_is_set(void);
+int server_identity_key_is_set(void);
authority_cert_t *get_my_v3_authority_cert(void);
crypto_pk_env_t *get_my_v3_authority_signing_key(void);
authority_cert_t *get_my_v3_legacy_cert(void);
diff --git a/src/or/router.c b/src/or/router.c
index dce2ad6018..c53bb8b4e9 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -31,11 +31,15 @@ static crypto_pk_env_t *onionkey=NULL;
/** Previous private onionskin decryption key: used to decode CREATE cells
* generated by clients that have an older version of our descriptor. */
static crypto_pk_env_t *lastonionkey=NULL;
-/** Private "identity key": used to sign directory info and TLS
+/** Private server "identity key": used to sign directory info and TLS
* certificates. Never changes. */
-static crypto_pk_env_t *identitykey=NULL;
-/** Digest of identitykey. */
-static char identitykey_digest[DIGEST_LEN];
+static crypto_pk_env_t *server_identitykey=NULL;
+/** Digest of server_identitykey. */
+static char server_identitykey_digest[DIGEST_LEN];
+/** Private client "identity key": used to sign bridges' and clients'
+ * outbound TLS certificates. Regenerated on startup and on IP address
+ * change. */
+static crypto_pk_env_t *client_identitykey=NULL;
/** Signing key used for v3 directory material; only set for authorities. */
static crypto_pk_env_t *authority_signing_key = NULL;
/** Key certificate to authenticate v3 directory material; only set for
@@ -106,32 +110,59 @@ get_onion_key_set_at(void)
return onionkey_set_at;
}
-/** Set the current identity key to k.
+/** Set the current server identity key to <b>k</b>.
*/
void
-set_identity_key(crypto_pk_env_t *k)
+set_server_identity_key(crypto_pk_env_t *k)
{
- if (identitykey)
- crypto_free_pk_env(identitykey);
- identitykey = k;
- crypto_pk_get_digest(identitykey, identitykey_digest);
+ if (server_identitykey)
+ crypto_free_pk_env(server_identitykey);
+ server_identitykey = k;
+ crypto_pk_get_digest(server_identitykey, server_identitykey_digest);
}
-/** Returns the current identity key; requires that the identity key has been
- * set.
+/** Returns the current server identity key; requires that the key has
+ * been set.
*/
crypto_pk_env_t *
-get_identity_key(void)
+get_server_identity_key(void)
{
- tor_assert(identitykey);
- return identitykey;
+ tor_assert(server_identitykey);
+ return server_identitykey;
}
-/** Return true iff the identity key has been set. */
+/** Return true iff the server identity key has been set. */
int
-identity_key_is_set(void)
+server_identity_key_is_set(void)
{
- return identitykey != NULL;
+ return server_identitykey != NULL;
+}
+
+/** Set the current client identity key to <b>k</b>.
+ */
+void
+set_client_identity_key(crypto_pk_env_t *k)
+{
+ if (client_identitykey)
+ crypto_free_pk_env(client_identitykey);
+ client_identitykey = k;
+}
+
+/** Returns the current client identity key; requires that the key has
+ * been set.
+ */
+crypto_pk_env_t *
+get_client_identity_key(void)
+{
+ tor_assert(client_identitykey);
+ return client_identitykey;
+}
+
+/** Return true iff the client identity key has been set. */
+int
+client_identity_key_is_set(void)
+{
+ return client_identitykey != NULL;
}
/** Return the key certificate for this v3 (voting) authority, or NULL
@@ -456,10 +487,10 @@ init_keys(void)
crypto_free_pk_env(prkey);
return -1;
}
- set_identity_key(prkey);
+ set_client_identity_key(prkey);
/* Create a TLS context. */
if (tor_tls_context_init(0,
- get_identity_key(),
+ get_client_identity_key(),
NULL,
MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) {
log_err(LD_GENERAL,"Error creating TLS context for Tor client.");
@@ -496,13 +527,28 @@ init_keys(void)
}
}
- /* 1. Read identity key. Make it if none is found. */
+ /* 1b. Read identity key. Make it if none is found. */
keydir = get_datadir_fname2("keys", "secret_id_key");
log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir);
prkey = init_key_from_file(keydir, 1, LOG_ERR);
tor_free(keydir);
if (!prkey) return -1;
- set_identity_key(prkey);
+ set_server_identity_key(prkey);
+
+ /* 1c. If we are configured as a bridge, generate a client key;
+ * otherwise, set the server identity key as our client identity
+ * key. */
+ if (public_server_mode(options)) {
+ set_client_identity_key(prkey); /* set above */
+ } else {
+ if (!(prkey = crypto_new_pk_env()))
+ return -1;
+ if (crypto_pk_generate_key(prkey)) {
+ crypto_free_pk_env(prkey);
+ return -1;
+ }
+ set_client_identity_key(prkey);
+ }
/* 2. Read onion key. Make it if none is found. */
keydir = get_datadir_fname2("keys", "secret_onion_key");
@@ -540,8 +586,8 @@ init_keys(void)
/* 3. Initialize link key and TLS context. */
if (tor_tls_context_init(public_server_mode(options),
- get_identity_key(),
- get_identity_key(),
+ get_client_identity_key(),
+ get_server_identity_key(),
MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) {
log_err(LD_GENERAL,"Error initializing TLS context");
return -1;
@@ -553,7 +599,8 @@ init_keys(void)
const char *m = NULL;
routerinfo_t *ri;
/* We need to add our own fingerprint so it gets recognized. */
- if (dirserv_add_own_fingerprint(options->Nickname, get_identity_key())) {
+ if (dirserv_add_own_fingerprint(options->Nickname,
+ get_server_identity_key())) {
log_err(LD_GENERAL,"Error adding own fingerprint to approved set");
return -1;
}
@@ -574,7 +621,8 @@ init_keys(void)
/* 5. Dump fingerprint to 'fingerprint' */
keydir = get_datadir_fname("fingerprint");
log_info(LD_GENERAL,"Dumping fingerprint to \"%s\"...",keydir);
- if (crypto_pk_get_fingerprint(get_identity_key(), fingerprint, 0)<0) {
+ if (crypto_pk_get_fingerprint(get_server_identity_key(),
+ fingerprint, 0) < 0) {
log_err(LD_GENERAL,"Error computing fingerprint");
tor_free(keydir);
return -1;
@@ -612,7 +660,7 @@ init_keys(void)
return -1;
}
/* 6b. [authdirserver only] add own key to approved directories. */
- crypto_pk_get_digest(get_identity_key(), digest);
+ crypto_pk_get_digest(get_server_identity_key(), digest);
type = ((options->V1AuthoritativeDir ? V1_AUTHORITY : NO_AUTHORITY) |
(options->V2AuthoritativeDir ? V2_AUTHORITY : NO_AUTHORITY) |
(options->V3AuthoritativeDir ? V3_AUTHORITY : NO_AUTHORITY) |
@@ -1130,11 +1178,12 @@ router_compare_to_my_exit_policy(edge_connection_t *conn)
}
/** Return true iff I'm a server and <b>digest</b> is equal to
- * my identity digest. */
+ * my server identity key digest. */
int
router_digest_is_me(const char *digest)
{
- return identitykey && tor_memeq(identitykey_digest, digest, DIGEST_LEN);
+ return (server_identitykey &&
+ tor_memeq(server_identitykey_digest, digest, DIGEST_LEN));
}
/** Return true iff I'm a server and <b>digest</b> is equal to
@@ -1271,7 +1320,7 @@ router_rebuild_descriptor(int force)
ri->cache_info.published_on = time(NULL);
ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from
* main thread */
- ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
+ ri->identity_pkey = crypto_pk_dup_key(get_server_identity_key());
if (crypto_pk_get_digest(ri->identity_pkey,
ri->cache_info.identity_digest)<0) {
routerinfo_free(ri);
@@ -1363,7 +1412,7 @@ router_rebuild_descriptor(int force)
DIGEST_LEN);
ei->cache_info.signed_descriptor_body = tor_malloc(8192);
if (extrainfo_dump_to_string(ei->cache_info.signed_descriptor_body, 8192,
- ei, get_identity_key()) < 0) {
+ ei, get_server_identity_key()) < 0) {
log_warn(LD_BUG, "Couldn't generate extra-info descriptor.");
routerinfo_free(ri);
extrainfo_free(ei);
@@ -1380,7 +1429,7 @@ router_rebuild_descriptor(int force)
DIGEST_LEN);
ri->cache_info.signed_descriptor_body = tor_malloc(8192);
if (router_dump_router_to_string(ri->cache_info.signed_descriptor_body, 8192,
- ri, get_identity_key())<0) {
+ ri, get_server_identity_key()) < 0) {
log_warn(LD_BUG, "Couldn't generate router descriptor.");
routerinfo_free(ri);
extrainfo_free(ei);
@@ -2029,8 +2078,10 @@ router_free_all(void)
crypto_free_pk_env(onionkey);
if (lastonionkey)
crypto_free_pk_env(lastonionkey);
- if (identitykey)
- crypto_free_pk_env(identitykey);
+ if (server_identitykey)
+ crypto_free_pk_env(server_identitykey);
+ if (client_identitykey)
+ crypto_free_pk_env(client_identitykey);
if (key_lock)
tor_mutex_free(key_lock);
if (desc_routerinfo)