|
@@ -49,11 +49,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
|
|
@@ -123,31 +127,57 @@ 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)
|
|
|
{
|
|
|
- crypto_free_pk_env(identitykey);
|
|
|
- identitykey = k;
|
|
|
- crypto_pk_get_digest(identitykey, identitykey_digest);
|
|
|
+ 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)
|
|
|
+{
|
|
|
+ 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
|
|
@@ -470,10 +500,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) < 0) {
|
|
|
log_err(LD_GENERAL,"Error creating TLS context for Tor client.");
|
|
@@ -510,13 +540,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");
|
|
@@ -554,8 +599,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) < 0) {
|
|
|
log_err(LD_GENERAL,"Error initializing TLS context");
|
|
|
return -1;
|
|
@@ -567,7 +612,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;
|
|
|
}
|
|
@@ -588,7 +634,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;
|
|
@@ -626,7 +673,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) |
|
|
@@ -1178,11 +1225,12 @@ router_my_exit_policy_is_reject_star(void)
|
|
|
}
|
|
|
|
|
|
/** 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 && !memcmp(identitykey_digest, digest, DIGEST_LEN);
|
|
|
+ return (server_identitykey &&
|
|
|
+ !memcmp(server_identitykey_digest, digest, DIGEST_LEN));
|
|
|
}
|
|
|
|
|
|
/** Return true iff I'm a server and <b>digest</b> is equal to
|
|
@@ -1325,7 +1373,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);
|
|
@@ -1420,7 +1468,8 @@ router_rebuild_descriptor(int force)
|
|
|
ei_size = options->ExtraInfoStatistics ? MAX_EXTRAINFO_UPLOAD_SIZE : 8192;
|
|
|
ei->cache_info.signed_descriptor_body = tor_malloc(ei_size);
|
|
|
if (extrainfo_dump_to_string(ei->cache_info.signed_descriptor_body,
|
|
|
- ei_size, ei, get_identity_key()) < 0) {
|
|
|
+ ei_size, ei,
|
|
|
+ get_server_identity_key()) < 0) {
|
|
|
log_warn(LD_BUG, "Couldn't generate extra-info descriptor.");
|
|
|
routerinfo_free(ri);
|
|
|
extrainfo_free(ei);
|
|
@@ -1437,7 +1486,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);
|
|
@@ -2186,7 +2235,8 @@ router_free_all(void)
|
|
|
{
|
|
|
crypto_free_pk_env(onionkey);
|
|
|
crypto_free_pk_env(lastonionkey);
|
|
|
- crypto_free_pk_env(identitykey);
|
|
|
+ crypto_free_pk_env(server_identitykey);
|
|
|
+ crypto_free_pk_env(client_identitykey);
|
|
|
tor_mutex_free(key_lock);
|
|
|
routerinfo_free(desc_routerinfo);
|
|
|
extrainfo_free(desc_extrainfo);
|