mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Maintain separate server and client TLS contexts.
Fixes bug #988. Conflicts: src/or/main.c src/or/router.c
This commit is contained in:
parent
8781640111
commit
9976df9e56
@ -184,12 +184,16 @@ 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);
|
||||||
static void tor_tls_unblock_renegotiation(tor_tls_t *tls);
|
static void tor_tls_unblock_renegotiation(tor_tls_t *tls);
|
||||||
|
static int tor_tls_context_init_one(tor_tls_context_t **ppcontext,
|
||||||
|
crypto_pk_env_t *identity,
|
||||||
|
unsigned int key_lifetime);
|
||||||
static tor_tls_context_t *tor_tls_context_new(crypto_pk_env_t *identity,
|
static tor_tls_context_t *tor_tls_context_new(crypto_pk_env_t *identity,
|
||||||
unsigned int key_lifetime);
|
unsigned int key_lifetime);
|
||||||
|
|
||||||
/** Global tls context. We keep it here because nobody else needs to
|
/** Global TLS contexts. We keep them here because nobody else needs
|
||||||
* touch it. */
|
* to touch them. */
|
||||||
static tor_tls_context_t *global_tls_context = NULL;
|
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;
|
||||||
|
|
||||||
@ -402,9 +406,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.");
|
||||||
@ -591,6 +601,63 @@ tor_tls_context_incref(tor_tls_context_t *ctx)
|
|||||||
++ctx->refcnt;
|
++ctx->refcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Create new global client and server TLS contexts.
|
||||||
|
*
|
||||||
|
* 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 rv1 < rv2 ? rv1 : rv2;
|
||||||
|
}
|
||||||
|
|
||||||
/** Create a new TLS context for use with Tor TLS handshakes.
|
/** 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
|
* <b>identity</b> should be set to the identity key used to sign the
|
||||||
* certificate.
|
* certificate.
|
||||||
@ -599,15 +666,17 @@ tor_tls_context_incref(tor_tls_context_t *ctx)
|
|||||||
* 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(crypto_pk_env_t *identity, unsigned int key_lifetime)
|
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,
|
tor_tls_context_t *new_ctx = tor_tls_context_new(identity,
|
||||||
key_lifetime);
|
key_lifetime);
|
||||||
tor_tls_context_t *old_ctx = global_tls_context;
|
tor_tls_context_t *old_ctx = *ppcontext;
|
||||||
|
|
||||||
if (new_ctx != NULL) {
|
if (new_ctx != NULL) {
|
||||||
global_tls_context = new_ctx;
|
*ppcontext = new_ctx;
|
||||||
|
|
||||||
/* Free the old context if one existed. */
|
/* Free the old context if one existed. */
|
||||||
if (old_ctx != NULL) {
|
if (old_ctx != NULL) {
|
||||||
@ -920,10 +989,12 @@ 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, "generating TLS context");
|
tls_log_errors(NULL, LOG_WARN, "creating SSL object");
|
||||||
tor_free(result);
|
tor_free(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -962,8 +1033,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,9 @@ 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_init(crypto_pk_env_t *identity,
|
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);
|
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);
|
||||||
|
@ -816,6 +816,7 @@ run_scheduled_events(time_t now)
|
|||||||
static time_t time_to_dump_geoip_stats = 0;
|
static time_t time_to_dump_geoip_stats = 0;
|
||||||
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;
|
||||||
|
|
||||||
@ -837,7 +838,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();
|
||||||
@ -872,7 +873,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_INTERNAL < now) {
|
if (last_rotated_x509_certificate+MAX_SSL_KEY_LIFETIME_INTERNAL < now) {
|
||||||
log_info(LD_GENERAL,"Rotating tls context.");
|
log_info(LD_GENERAL,"Rotating tls context.");
|
||||||
if (tor_tls_context_init(get_identity_key(), MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) {
|
if (tor_tls_context_init(public_server_mode(options),
|
||||||
|
get_identity_key(),
|
||||||
|
is_server ? get_identity_key() : NULL,
|
||||||
|
MAX_SSL_KEY_LIFETIME_ADVERTISED) < 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 */
|
||||||
}
|
}
|
||||||
@ -1110,7 +1114,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 {
|
||||||
|
@ -457,8 +457,11 @@ init_keys(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
set_identity_key(prkey);
|
set_identity_key(prkey);
|
||||||
/* Create a TLS context; default the client nickname to "client". */
|
/* Create a TLS context. */
|
||||||
if (tor_tls_context_init(get_identity_key(), MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) {
|
if (tor_tls_context_init(0,
|
||||||
|
get_identity_key(),
|
||||||
|
NULL,
|
||||||
|
MAX_SSL_KEY_LIFETIME_ADVERTISED) < 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;
|
||||||
}
|
}
|
||||||
@ -536,7 +539,9 @@ 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_init(get_identity_key(),
|
if (tor_tls_context_init(public_server_mode(options),
|
||||||
|
get_identity_key(),
|
||||||
|
get_identity_key(),
|
||||||
MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) {
|
MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) {
|
||||||
log_err(LD_GENERAL,"Error initializing TLS context");
|
log_err(LD_GENERAL,"Error initializing TLS context");
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user