mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-14 07:03:44 +01:00
Merge remote branch 'origin/maint-0.2.2'
Conflicts: src/common/tortls.c
This commit is contained in:
commit
17fdde3d92
@ -200,9 +200,17 @@ static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
|
|||||||
const char *cname_sign,
|
const char *cname_sign,
|
||||||
unsigned int lifetime);
|
unsigned int lifetime);
|
||||||
|
|
||||||
/** Global tls context. We keep it here because nobody else needs to
|
static int tor_tls_context_init_one(tor_tls_context_t **ppcontext,
|
||||||
* touch it. */
|
crypto_pk_env_t *identity,
|
||||||
static tor_tls_context_t *global_tls_context = NULL;
|
unsigned int key_lifetime);
|
||||||
|
static tor_tls_context_t *tor_tls_context_new(crypto_pk_env_t *identity,
|
||||||
|
unsigned int key_lifetime);
|
||||||
|
|
||||||
|
/** Global TLS contexts. We keep them here because nobody else needs
|
||||||
|
* to touch them. */
|
||||||
|
static tor_tls_context_t *server_tls_context = NULL;
|
||||||
|
static tor_tls_context_t *client_tls_context = NULL;
|
||||||
|
|
||||||
/** True iff tor_tls_init() has been called. */
|
/** True iff tor_tls_init() has been called. */
|
||||||
static int tls_library_is_initialized = 0;
|
static int tls_library_is_initialized = 0;
|
||||||
|
|
||||||
@ -448,9 +456,15 @@ tor_tls_init(void)
|
|||||||
void
|
void
|
||||||
tor_tls_free_all(void)
|
tor_tls_free_all(void)
|
||||||
{
|
{
|
||||||
if (global_tls_context) {
|
if (server_tls_context) {
|
||||||
tor_tls_context_decref(global_tls_context);
|
tor_tls_context_t *ctx = server_tls_context;
|
||||||
global_tls_context = NULL;
|
server_tls_context = NULL;
|
||||||
|
tor_tls_context_decref(ctx);
|
||||||
|
}
|
||||||
|
if (client_tls_context) {
|
||||||
|
tor_tls_context_t *ctx = client_tls_context;
|
||||||
|
client_tls_context = NULL;
|
||||||
|
tor_tls_context_decref(ctx);
|
||||||
}
|
}
|
||||||
if (!HT_EMPTY(&tlsmap_root)) {
|
if (!HT_EMPTY(&tlsmap_root)) {
|
||||||
log_warn(LD_MM, "Still have entries in the tlsmap at shutdown.");
|
log_warn(LD_MM, "Still have entries in the tlsmap at shutdown.");
|
||||||
@ -637,15 +651,97 @@ tor_tls_context_incref(tor_tls_context_t *ctx)
|
|||||||
++ctx->refcnt;
|
++ctx->refcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a new TLS context for use with Tor TLS handshakes.
|
/** Create new global client and server TLS contexts.
|
||||||
* <b>identity</b> should be set to the identity key used to sign the
|
*
|
||||||
* certificate.
|
* If <b>server_identity</b> is NULL, this will not generate a server
|
||||||
|
* TLS context. If <b>is_public_server</b> is non-zero, this will use
|
||||||
|
* the same TLS context for incoming and outgoing connections, and
|
||||||
|
* ignore <b>client_identity</b>. */
|
||||||
|
int
|
||||||
|
tor_tls_context_init(int is_public_server,
|
||||||
|
crypto_pk_env_t *client_identity,
|
||||||
|
crypto_pk_env_t *server_identity,
|
||||||
|
unsigned int key_lifetime)
|
||||||
|
{
|
||||||
|
int rv1 = 0;
|
||||||
|
int rv2 = 0;
|
||||||
|
|
||||||
|
if (is_public_server) {
|
||||||
|
tor_tls_context_t *new_ctx;
|
||||||
|
tor_tls_context_t *old_ctx;
|
||||||
|
|
||||||
|
tor_assert(server_identity != NULL);
|
||||||
|
|
||||||
|
rv1 = tor_tls_context_init_one(&server_tls_context,
|
||||||
|
server_identity,
|
||||||
|
key_lifetime);
|
||||||
|
|
||||||
|
if (rv1 >= 0) {
|
||||||
|
new_ctx = server_tls_context;
|
||||||
|
tor_tls_context_incref(new_ctx);
|
||||||
|
old_ctx = client_tls_context;
|
||||||
|
client_tls_context = new_ctx;
|
||||||
|
|
||||||
|
if (old_ctx != NULL) {
|
||||||
|
tor_tls_context_decref(old_ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (server_identity != NULL) {
|
||||||
|
rv1 = tor_tls_context_init_one(&server_tls_context,
|
||||||
|
server_identity,
|
||||||
|
key_lifetime);
|
||||||
|
} else {
|
||||||
|
tor_tls_context_t *old_ctx = server_tls_context;
|
||||||
|
server_tls_context = NULL;
|
||||||
|
|
||||||
|
if (old_ctx != NULL) {
|
||||||
|
tor_tls_context_decref(old_ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rv2 = tor_tls_context_init_one(&client_tls_context,
|
||||||
|
client_identity,
|
||||||
|
key_lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MIN(rv1, rv2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a new global TLS context.
|
||||||
*
|
*
|
||||||
* You can call this function multiple times. Each time you call it,
|
* You can call this function multiple times. Each time you call it,
|
||||||
* it generates new certificates; all new connections will use
|
* it generates new certificates; all new connections will use
|
||||||
* the new SSL context.
|
* the new SSL context.
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
|
tor_tls_context_init_one(tor_tls_context_t **ppcontext,
|
||||||
|
crypto_pk_env_t *identity,
|
||||||
|
unsigned int key_lifetime)
|
||||||
|
{
|
||||||
|
tor_tls_context_t *new_ctx = tor_tls_context_new(identity,
|
||||||
|
key_lifetime);
|
||||||
|
tor_tls_context_t *old_ctx = *ppcontext;
|
||||||
|
|
||||||
|
if (new_ctx != NULL) {
|
||||||
|
*ppcontext = new_ctx;
|
||||||
|
|
||||||
|
/* Free the old context if one existed. */
|
||||||
|
if (old_ctx != NULL) {
|
||||||
|
/* This is safe even if there are open connections: we reference-
|
||||||
|
* count tor_tls_context_t objects. */
|
||||||
|
tor_tls_context_decref(old_ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((new_ctx != NULL) ? 0 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a new TLS context for use with Tor TLS handshakes.
|
||||||
|
* <b>identity</b> should be set to the identity key used to sign the
|
||||||
|
* certificate.
|
||||||
|
*/
|
||||||
|
static tor_tls_context_t *
|
||||||
tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime)
|
tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime)
|
||||||
{
|
{
|
||||||
crypto_pk_env_t *rsa = NULL;
|
crypto_pk_env_t *rsa = NULL;
|
||||||
@ -740,18 +836,12 @@ tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime)
|
|||||||
always_accept_verify_cb);
|
always_accept_verify_cb);
|
||||||
/* let us realloc bufs that we're writing from */
|
/* let us realloc bufs that we're writing from */
|
||||||
SSL_CTX_set_mode(result->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
SSL_CTX_set_mode(result->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||||
/* Free the old context if one exists. */
|
|
||||||
if (global_tls_context) {
|
|
||||||
/* This is safe even if there are open connections: we reference-
|
|
||||||
* count tor_tls_context_t objects. */
|
|
||||||
tor_tls_context_decref(global_tls_context);
|
|
||||||
}
|
|
||||||
global_tls_context = result;
|
|
||||||
if (rsa)
|
if (rsa)
|
||||||
crypto_free_pk_env(rsa);
|
crypto_free_pk_env(rsa);
|
||||||
tor_free(nickname);
|
tor_free(nickname);
|
||||||
tor_free(nn2);
|
tor_free(nn2);
|
||||||
return 0;
|
return result;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
tls_log_errors(NULL, LOG_WARN, LD_NET, "creating TLS context");
|
tls_log_errors(NULL, LOG_WARN, LD_NET, "creating TLS context");
|
||||||
@ -767,7 +857,7 @@ tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime)
|
|||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
if (idcert)
|
if (idcert)
|
||||||
X509_free(idcert);
|
X509_free(idcert);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef V2_HANDSHAKE_SERVER
|
#ifdef V2_HANDSHAKE_SERVER
|
||||||
@ -952,9 +1042,11 @@ tor_tls_new(int sock, int isServer)
|
|||||||
{
|
{
|
||||||
BIO *bio = NULL;
|
BIO *bio = NULL;
|
||||||
tor_tls_t *result = tor_malloc_zero(sizeof(tor_tls_t));
|
tor_tls_t *result = tor_malloc_zero(sizeof(tor_tls_t));
|
||||||
|
tor_tls_context_t *context = isServer ? server_tls_context :
|
||||||
|
client_tls_context;
|
||||||
|
|
||||||
tor_assert(global_tls_context); /* make sure somebody made it first */
|
tor_assert(context); /* make sure somebody made it first */
|
||||||
if (!(result->ssl = SSL_new(global_tls_context->ctx))) {
|
if (!(result->ssl = SSL_new(context->ctx))) {
|
||||||
tls_log_errors(NULL, LOG_WARN, LD_NET, "creating SSL object");
|
tls_log_errors(NULL, LOG_WARN, LD_NET, "creating SSL object");
|
||||||
tor_free(result);
|
tor_free(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -994,8 +1086,8 @@ tor_tls_new(int sock, int isServer)
|
|||||||
}
|
}
|
||||||
HT_INSERT(tlsmap, &tlsmap_root, result);
|
HT_INSERT(tlsmap, &tlsmap_root, result);
|
||||||
SSL_set_bio(result->ssl, bio, bio);
|
SSL_set_bio(result->ssl, bio, bio);
|
||||||
tor_tls_context_incref(global_tls_context);
|
tor_tls_context_incref(context);
|
||||||
result->context = global_tls_context;
|
result->context = context;
|
||||||
result->state = TOR_TLS_ST_HANDSHAKE;
|
result->state = TOR_TLS_ST_HANDSHAKE;
|
||||||
result->isServer = isServer;
|
result->isServer = isServer;
|
||||||
result->wantwrite_n = 0;
|
result->wantwrite_n = 0;
|
||||||
|
@ -50,7 +50,10 @@ typedef struct tor_tls_t tor_tls_t;
|
|||||||
const char *tor_tls_err_to_string(int err);
|
const char *tor_tls_err_to_string(int err);
|
||||||
|
|
||||||
void tor_tls_free_all(void);
|
void tor_tls_free_all(void);
|
||||||
int tor_tls_context_new(crypto_pk_env_t *rsa, unsigned int key_lifetime);
|
int tor_tls_context_init(int is_public_server,
|
||||||
|
crypto_pk_env_t *client_identity,
|
||||||
|
crypto_pk_env_t *server_identity,
|
||||||
|
unsigned int key_lifetime);
|
||||||
tor_tls_t *tor_tls_new(int sock, int is_server);
|
tor_tls_t *tor_tls_new(int sock, int is_server);
|
||||||
void tor_tls_set_logged_address(tor_tls_t *tls, const char *address);
|
void tor_tls_set_logged_address(tor_tls_t *tls, const char *address);
|
||||||
void tor_tls_set_renegotiate_callback(tor_tls_t *tls,
|
void tor_tls_set_renegotiate_callback(tor_tls_t *tls,
|
||||||
|
@ -1142,6 +1142,9 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
|
|||||||
started_here ? conn->_base.address :
|
started_here ? conn->_base.address :
|
||||||
safe_str_client(conn->_base.address);
|
safe_str_client(conn->_base.address);
|
||||||
const char *conn_type = started_here ? "outgoing" : "incoming";
|
const char *conn_type = started_here ? "outgoing" : "incoming";
|
||||||
|
crypto_pk_env_t *our_identity =
|
||||||
|
started_here ? get_tlsclient_identity_key() :
|
||||||
|
get_server_identity_key();
|
||||||
int has_cert = 0, has_identity=0;
|
int has_cert = 0, has_identity=0;
|
||||||
|
|
||||||
check_no_tls_errors();
|
check_no_tls_errors();
|
||||||
@ -1179,7 +1182,7 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
|
|||||||
if (identity_rcvd) {
|
if (identity_rcvd) {
|
||||||
has_identity = 1;
|
has_identity = 1;
|
||||||
crypto_pk_get_digest(identity_rcvd, digest_rcvd_out);
|
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;
|
conn->circ_id_type = CIRC_ID_TYPE_LOWER;
|
||||||
} else {
|
} else {
|
||||||
conn->circ_id_type = CIRC_ID_TYPE_HIGHER;
|
conn->circ_id_type = CIRC_ID_TYPE_HIGHER;
|
||||||
|
@ -1578,7 +1578,8 @@ dirserv_regenerate_directory(void)
|
|||||||
{
|
{
|
||||||
char *new_directory=NULL;
|
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.");
|
log_warn(LD_BUG, "Error creating directory.");
|
||||||
tor_free(new_directory);
|
tor_free(new_directory);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1608,7 +1609,7 @@ generate_runningrouters(void)
|
|||||||
char digest[DIGEST_LEN];
|
char digest[DIGEST_LEN];
|
||||||
char published[ISO_TIME_LEN+1];
|
char published[ISO_TIME_LEN+1];
|
||||||
size_t len;
|
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. */
|
char *identity_pkey; /* Identity key, DER64-encoded. */
|
||||||
size_t identity_pkey_len;
|
size_t identity_pkey_len;
|
||||||
|
|
||||||
@ -2734,7 +2735,7 @@ generate_v2_networkstatus_opinion(void)
|
|||||||
smartlist_t *routers = NULL;
|
smartlist_t *routers = NULL;
|
||||||
digestmap_t *omit_as_sybil = 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) {
|
if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
|
||||||
log_warn(LD_NET, "Couldn't resolve my hostname");
|
log_warn(LD_NET, "Couldn't resolve my hostname");
|
||||||
|
@ -522,7 +522,7 @@ accounting_set_wakeup_time(void)
|
|||||||
uint64_t time_to_exhaust_bw;
|
uint64_t time_to_exhaust_bw;
|
||||||
int time_to_consider;
|
int time_to_consider;
|
||||||
|
|
||||||
if (! identity_key_is_set()) {
|
if (! server_identity_key_is_set()) {
|
||||||
if (init_keys() < 0) {
|
if (init_keys() < 0) {
|
||||||
log_err(LD_BUG, "Error initializing keys");
|
log_err(LD_BUG, "Error initializing keys");
|
||||||
tor_assert(0);
|
tor_assert(0);
|
||||||
@ -530,7 +530,7 @@ accounting_set_wakeup_time(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
format_iso_time(buf, interval_start_time);
|
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();
|
d_env = crypto_new_digest_env();
|
||||||
crypto_digest_add_bytes(d_env, buf, ISO_TIME_LEN);
|
crypto_digest_add_bytes(d_env, buf, ISO_TIME_LEN);
|
||||||
|
@ -1037,6 +1037,7 @@ run_scheduled_events(time_t now)
|
|||||||
static int should_init_bridge_stats = 1;
|
static int should_init_bridge_stats = 1;
|
||||||
static time_t time_to_retry_dns_init = 0;
|
static time_t time_to_retry_dns_init = 0;
|
||||||
or_options_t *options = get_options();
|
or_options_t *options = get_options();
|
||||||
|
int is_server = server_mode(options);
|
||||||
int i;
|
int i;
|
||||||
int have_dir_info;
|
int have_dir_info;
|
||||||
|
|
||||||
@ -1068,7 +1069,7 @@ run_scheduled_events(time_t now)
|
|||||||
* shut down and restart all cpuworkers, and update the directory if
|
* shut down and restart all cpuworkers, and update the directory if
|
||||||
* necessary.
|
* necessary.
|
||||||
*/
|
*/
|
||||||
if (server_mode(options) &&
|
if (is_server &&
|
||||||
get_onion_key_set_at()+MIN_ONION_KEY_LIFETIME < now) {
|
get_onion_key_set_at()+MIN_ONION_KEY_LIFETIME < now) {
|
||||||
log_info(LD_GENERAL,"Rotating onion key.");
|
log_info(LD_GENERAL,"Rotating onion key.");
|
||||||
rotate_onion_key();
|
rotate_onion_key();
|
||||||
@ -1103,7 +1104,10 @@ run_scheduled_events(time_t now)
|
|||||||
last_rotated_x509_certificate = now;
|
last_rotated_x509_certificate = now;
|
||||||
if (last_rotated_x509_certificate+MAX_SSL_KEY_LIFETIME < now) {
|
if (last_rotated_x509_certificate+MAX_SSL_KEY_LIFETIME < now) {
|
||||||
log_info(LD_GENERAL,"Rotating tls context.");
|
log_info(LD_GENERAL,"Rotating tls context.");
|
||||||
if (tor_tls_context_new(get_identity_key(), MAX_SSL_KEY_LIFETIME) < 0) {
|
if (tor_tls_context_init(public_server_mode(options),
|
||||||
|
get_tlsclient_identity_key(),
|
||||||
|
is_server ? get_server_identity_key() : NULL,
|
||||||
|
MAX_SSL_KEY_LIFETIME) < 0) {
|
||||||
log_warn(LD_BUG, "Error reinitializing TLS context");
|
log_warn(LD_BUG, "Error reinitializing TLS context");
|
||||||
/* XXX is it a bug here, that we just keep going? -RD */
|
/* XXX is it a bug here, that we just keep going? -RD */
|
||||||
}
|
}
|
||||||
@ -1386,7 +1390,7 @@ run_scheduled_events(time_t now)
|
|||||||
|
|
||||||
/** 9. and if we're a server, check whether our DNS is telling stories to
|
/** 9. and if we're a server, check whether our DNS is telling stories to
|
||||||
* us. */
|
* us. */
|
||||||
if (server_mode(options) && time_to_check_for_correct_dns < now) {
|
if (is_server && time_to_check_for_correct_dns < now) {
|
||||||
if (!time_to_check_for_correct_dns) {
|
if (!time_to_check_for_correct_dns) {
|
||||||
time_to_check_for_correct_dns = now + 60 + crypto_rand_int(120);
|
time_to_check_for_correct_dns = now + 60 + crypto_rand_int(120);
|
||||||
} else {
|
} else {
|
||||||
@ -1660,7 +1664,7 @@ do_main_loop(void)
|
|||||||
|
|
||||||
/* load the private keys, if we're supposed to have them, and set up the
|
/* load the private keys, if we're supposed to have them, and set up the
|
||||||
* TLS context. */
|
* TLS context. */
|
||||||
if (! identity_key_is_set()) {
|
if (! client_identity_key_is_set()) {
|
||||||
if (init_keys() < 0) {
|
if (init_keys() < 0) {
|
||||||
log_err(LD_BUG,"Error initializing keys; exiting");
|
log_err(LD_BUG,"Error initializing keys; exiting");
|
||||||
return -1;
|
return -1;
|
||||||
@ -2299,7 +2303,7 @@ do_list_fingerprint(void)
|
|||||||
log_err(LD_BUG,"Error initializing keys; can't display fingerprint");
|
log_err(LD_BUG,"Error initializing keys; can't display fingerprint");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!(k = get_identity_key())) {
|
if (!(k = get_server_identity_key())) {
|
||||||
log_err(LD_GENERAL,"Error: missing identity key.");
|
log_err(LD_GENERAL,"Error: missing identity key.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
150
src/or/router.c
150
src/or/router.c
@ -51,11 +51,15 @@ static crypto_pk_env_t *onionkey=NULL;
|
|||||||
/** Previous private onionskin decryption key: used to decode CREATE cells
|
/** Previous private onionskin decryption key: used to decode CREATE cells
|
||||||
* generated by clients that have an older version of our descriptor. */
|
* generated by clients that have an older version of our descriptor. */
|
||||||
static crypto_pk_env_t *lastonionkey=NULL;
|
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. */
|
* certificates. Never changes. */
|
||||||
static crypto_pk_env_t *identitykey=NULL;
|
static crypto_pk_env_t *server_identitykey=NULL;
|
||||||
/** Digest of identitykey. */
|
/** Digest of server_identitykey. */
|
||||||
static char identitykey_digest[DIGEST_LEN];
|
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. */
|
/** Signing key used for v3 directory material; only set for authorities. */
|
||||||
static crypto_pk_env_t *authority_signing_key = NULL;
|
static crypto_pk_env_t *authority_signing_key = NULL;
|
||||||
/** Key certificate to authenticate v3 directory material; only set for
|
/** Key certificate to authenticate v3 directory material; only set for
|
||||||
@ -125,31 +129,78 @@ get_onion_key_set_at(void)
|
|||||||
return onionkey_set_at;
|
return onionkey_set_at;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set the current identity key to k.
|
/** Set the current server identity key to <b>k</b>.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
set_identity_key(crypto_pk_env_t *k)
|
set_server_identity_key(crypto_pk_env_t *k)
|
||||||
{
|
{
|
||||||
crypto_free_pk_env(identitykey);
|
crypto_free_pk_env(server_identitykey);
|
||||||
identitykey = k;
|
server_identitykey = k;
|
||||||
crypto_pk_get_digest(identitykey, identitykey_digest);
|
crypto_pk_get_digest(server_identitykey, server_identitykey_digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the current identity key; requires that the identity key has been
|
/** Make sure that we have set up our identity keys to match or not match as
|
||||||
* set.
|
* appropriate, and die with an assertion if we have not. */
|
||||||
|
static void
|
||||||
|
assert_identity_keys_ok(void)
|
||||||
|
{
|
||||||
|
tor_assert(client_identitykey);
|
||||||
|
if (public_server_mode(get_options())) {
|
||||||
|
/* assert that we have set the client and server keys to be equal */
|
||||||
|
tor_assert(server_identitykey);
|
||||||
|
tor_assert(0==crypto_pk_cmp_keys(client_identitykey, server_identitykey));
|
||||||
|
} else {
|
||||||
|
/* assert that we have set the client and server keys to be unequal */
|
||||||
|
if (server_identitykey)
|
||||||
|
tor_assert(0!=crypto_pk_cmp_keys(client_identitykey,
|
||||||
|
server_identitykey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the current server identity key; requires that the key has
|
||||||
|
* been set, and that we are running as a Tor server.
|
||||||
*/
|
*/
|
||||||
crypto_pk_env_t *
|
crypto_pk_env_t *
|
||||||
get_identity_key(void)
|
get_server_identity_key(void)
|
||||||
{
|
{
|
||||||
tor_assert(identitykey);
|
tor_assert(server_identitykey);
|
||||||
return identitykey;
|
tor_assert(server_mode(get_options()));
|
||||||
|
assert_identity_keys_ok();
|
||||||
|
return server_identitykey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return true iff the identity key has been set. */
|
/** Return true iff the server identity key has been set. */
|
||||||
int
|
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 for use on outgoing TLS
|
||||||
|
* connections; requires that the key has been set.
|
||||||
|
*/
|
||||||
|
crypto_pk_env_t *
|
||||||
|
get_tlsclient_identity_key(void)
|
||||||
|
{
|
||||||
|
tor_assert(client_identitykey);
|
||||||
|
assert_identity_keys_ok();
|
||||||
|
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
|
/** Return the key certificate for this v3 (voting) authority, or NULL
|
||||||
@ -472,9 +523,12 @@ init_keys(void)
|
|||||||
crypto_free_pk_env(prkey);
|
crypto_free_pk_env(prkey);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
set_identity_key(prkey);
|
set_client_identity_key(prkey);
|
||||||
/* Create a TLS context; default the client nickname to "client". */
|
/* Create a TLS context. */
|
||||||
if (tor_tls_context_new(get_identity_key(), MAX_SSL_KEY_LIFETIME) < 0) {
|
if (tor_tls_context_init(0,
|
||||||
|
get_tlsclient_identity_key(),
|
||||||
|
NULL,
|
||||||
|
MAX_SSL_KEY_LIFETIME) < 0) {
|
||||||
log_err(LD_GENERAL,"Error creating TLS context for Tor client.");
|
log_err(LD_GENERAL,"Error creating TLS context for Tor client.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -509,13 +563,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");
|
keydir = get_datadir_fname2("keys", "secret_id_key");
|
||||||
log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir);
|
log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir);
|
||||||
prkey = init_key_from_file(keydir, 1, LOG_ERR);
|
prkey = init_key_from_file(keydir, 1, LOG_ERR);
|
||||||
tor_free(keydir);
|
tor_free(keydir);
|
||||||
if (!prkey) return -1;
|
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. */
|
/* 2. Read onion key. Make it if none is found. */
|
||||||
keydir = get_datadir_fname2("keys", "secret_onion_key");
|
keydir = get_datadir_fname2("keys", "secret_onion_key");
|
||||||
@ -552,7 +621,10 @@ init_keys(void)
|
|||||||
tor_free(keydir);
|
tor_free(keydir);
|
||||||
|
|
||||||
/* 3. Initialize link key and TLS context. */
|
/* 3. Initialize link key and TLS context. */
|
||||||
if (tor_tls_context_new(get_identity_key(), MAX_SSL_KEY_LIFETIME) < 0) {
|
if (tor_tls_context_init(public_server_mode(options),
|
||||||
|
get_tlsclient_identity_key(),
|
||||||
|
get_server_identity_key(),
|
||||||
|
MAX_SSL_KEY_LIFETIME) < 0) {
|
||||||
log_err(LD_GENERAL,"Error initializing TLS context");
|
log_err(LD_GENERAL,"Error initializing TLS context");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -563,7 +635,8 @@ init_keys(void)
|
|||||||
const char *m = NULL;
|
const char *m = NULL;
|
||||||
routerinfo_t *ri;
|
routerinfo_t *ri;
|
||||||
/* We need to add our own fingerprint so it gets recognized. */
|
/* 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");
|
log_err(LD_GENERAL,"Error adding own fingerprint to approved set");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -584,7 +657,8 @@ init_keys(void)
|
|||||||
/* 5. Dump fingerprint to 'fingerprint' */
|
/* 5. Dump fingerprint to 'fingerprint' */
|
||||||
keydir = get_datadir_fname("fingerprint");
|
keydir = get_datadir_fname("fingerprint");
|
||||||
log_info(LD_GENERAL,"Dumping fingerprint to \"%s\"...",keydir);
|
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");
|
log_err(LD_GENERAL,"Error computing fingerprint");
|
||||||
tor_free(keydir);
|
tor_free(keydir);
|
||||||
return -1;
|
return -1;
|
||||||
@ -622,7 +696,7 @@ init_keys(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* 6b. [authdirserver only] add own key to approved directories. */
|
/* 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) |
|
type = ((options->V1AuthoritativeDir ? V1_AUTHORITY : NO_AUTHORITY) |
|
||||||
(options->V2AuthoritativeDir ? V2_AUTHORITY : NO_AUTHORITY) |
|
(options->V2AuthoritativeDir ? V2_AUTHORITY : NO_AUTHORITY) |
|
||||||
(options->V3AuthoritativeDir ? V3_AUTHORITY : NO_AUTHORITY) |
|
(options->V3AuthoritativeDir ? V3_AUTHORITY : NO_AUTHORITY) |
|
||||||
@ -981,6 +1055,15 @@ server_mode(or_options_t *options)
|
|||||||
return (options->ORPort != 0 || options->ORListenAddress);
|
return (options->ORPort != 0 || options->ORListenAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return true iff we are trying to be a non-bridge server.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
public_server_mode(or_options_t *options)
|
||||||
|
{
|
||||||
|
if (!server_mode(options)) return 0;
|
||||||
|
return (!options->BridgeRelay);
|
||||||
|
}
|
||||||
|
|
||||||
/** Return true iff the combination of options in <b>options</b> and parameters
|
/** Return true iff the combination of options in <b>options</b> and parameters
|
||||||
* in the consensus mean that we don't want to allow exits from circuits
|
* in the consensus mean that we don't want to allow exits from circuits
|
||||||
* we got from addresses not known to be servers. */
|
* we got from addresses not known to be servers. */
|
||||||
@ -1168,11 +1251,12 @@ router_my_exit_policy_is_reject_star(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Return true iff I'm a server and <b>digest</b> is equal to
|
/** Return true iff I'm a server and <b>digest</b> is equal to
|
||||||
* my identity digest. */
|
* my server identity key digest. */
|
||||||
int
|
int
|
||||||
router_digest_is_me(const char *digest)
|
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
|
/** Return true iff I'm a server and <b>digest</b> is equal to
|
||||||
@ -1311,7 +1395,7 @@ router_rebuild_descriptor(int force)
|
|||||||
ri->cache_info.published_on = time(NULL);
|
ri->cache_info.published_on = time(NULL);
|
||||||
ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from
|
ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from
|
||||||
* main thread */
|
* 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,
|
if (crypto_pk_get_digest(ri->identity_pkey,
|
||||||
ri->cache_info.identity_digest)<0) {
|
ri->cache_info.identity_digest)<0) {
|
||||||
routerinfo_free(ri);
|
routerinfo_free(ri);
|
||||||
@ -1406,7 +1490,8 @@ router_rebuild_descriptor(int force)
|
|||||||
ei_size = options->ExtraInfoStatistics ? MAX_EXTRAINFO_UPLOAD_SIZE : 8192;
|
ei_size = options->ExtraInfoStatistics ? MAX_EXTRAINFO_UPLOAD_SIZE : 8192;
|
||||||
ei->cache_info.signed_descriptor_body = tor_malloc(ei_size);
|
ei->cache_info.signed_descriptor_body = tor_malloc(ei_size);
|
||||||
if (extrainfo_dump_to_string(ei->cache_info.signed_descriptor_body,
|
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.");
|
log_warn(LD_BUG, "Couldn't generate extra-info descriptor.");
|
||||||
routerinfo_free(ri);
|
routerinfo_free(ri);
|
||||||
extrainfo_free(ei);
|
extrainfo_free(ei);
|
||||||
@ -1423,7 +1508,7 @@ router_rebuild_descriptor(int force)
|
|||||||
DIGEST_LEN);
|
DIGEST_LEN);
|
||||||
ri->cache_info.signed_descriptor_body = tor_malloc(8192);
|
ri->cache_info.signed_descriptor_body = tor_malloc(8192);
|
||||||
if (router_dump_router_to_string(ri->cache_info.signed_descriptor_body, 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.");
|
log_warn(LD_BUG, "Couldn't generate router descriptor.");
|
||||||
routerinfo_free(ri);
|
routerinfo_free(ri);
|
||||||
extrainfo_free(ei);
|
extrainfo_free(ei);
|
||||||
@ -2175,7 +2260,8 @@ router_free_all(void)
|
|||||||
{
|
{
|
||||||
crypto_free_pk_env(onionkey);
|
crypto_free_pk_env(onionkey);
|
||||||
crypto_free_pk_env(lastonionkey);
|
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);
|
tor_mutex_free(key_lock);
|
||||||
routerinfo_free(desc_routerinfo);
|
routerinfo_free(desc_routerinfo);
|
||||||
extrainfo_free(desc_extrainfo);
|
extrainfo_free(desc_extrainfo);
|
||||||
|
@ -14,9 +14,12 @@
|
|||||||
|
|
||||||
crypto_pk_env_t *get_onion_key(void);
|
crypto_pk_env_t *get_onion_key(void);
|
||||||
time_t get_onion_key_set_at(void);
|
time_t get_onion_key_set_at(void);
|
||||||
void set_identity_key(crypto_pk_env_t *k);
|
void set_server_identity_key(crypto_pk_env_t *k);
|
||||||
crypto_pk_env_t *get_identity_key(void);
|
crypto_pk_env_t *get_server_identity_key(void);
|
||||||
int identity_key_is_set(void);
|
int server_identity_key_is_set(void);
|
||||||
|
void set_client_identity_key(crypto_pk_env_t *k);
|
||||||
|
crypto_pk_env_t *get_tlsclient_identity_key(void);
|
||||||
|
int client_identity_key_is_set(void);
|
||||||
authority_cert_t *get_my_v3_authority_cert(void);
|
authority_cert_t *get_my_v3_authority_cert(void);
|
||||||
crypto_pk_env_t *get_my_v3_authority_signing_key(void);
|
crypto_pk_env_t *get_my_v3_authority_signing_key(void);
|
||||||
authority_cert_t *get_my_v3_legacy_cert(void);
|
authority_cert_t *get_my_v3_legacy_cert(void);
|
||||||
@ -48,6 +51,7 @@ int authdir_mode_tests_reachability(or_options_t *options);
|
|||||||
int authdir_mode_bridge(or_options_t *options);
|
int authdir_mode_bridge(or_options_t *options);
|
||||||
|
|
||||||
int server_mode(or_options_t *options);
|
int server_mode(or_options_t *options);
|
||||||
|
int public_server_mode(or_options_t *options);
|
||||||
int advertised_server_mode(void);
|
int advertised_server_mode(void);
|
||||||
int proxy_mode(or_options_t *options);
|
int proxy_mode(or_options_t *options);
|
||||||
void consider_publishable_server(int force);
|
void consider_publishable_server(int force);
|
||||||
|
Loading…
Reference in New Issue
Block a user