From 878164011108c16574d6ce1d9530fe83a3109bad Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Fri, 1 Oct 2010 14:06:57 -0700 Subject: [PATCH] Refactor tor_tls_context_new: * Make tor_tls_context_new internal to tortls.c, and return the new tor_tls_context_t from it. * Add a public tor_tls_context_init wrapper function to replace it. Conflicts: src/or/main.c src/or/router.c --- src/common/tortls.c | 41 +++++++++++++++++++++++++++++++---------- src/common/tortls.h | 3 ++- src/or/main.c | 3 +-- src/or/router.c | 5 ++--- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/common/tortls.c b/src/common/tortls.c index 7735618ea2..d3435e7603 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -184,6 +184,8 @@ static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa, const char *cname_sign, unsigned int lifetime); static void tor_tls_unblock_renegotiation(tor_tls_t *tls); +static tor_tls_context_t *tor_tls_context_new(crypto_pk_env_t *identity, + unsigned int key_lifetime); /** Global tls context. We keep it here because nobody else needs to * touch it. */ @@ -591,13 +593,38 @@ tor_tls_context_incref(tor_tls_context_t *ctx) /** Create a new TLS context for use with Tor TLS handshakes. * identity should be set to the identity key used to sign the - * certificate, and nickname set to the nickname to use. + * certificate. * * You can call this function multiple times. Each time you call it, * it generates new certificates; all new connections will use * the new SSL context. */ int +tor_tls_context_init(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 = global_tls_context; + + if (new_ctx != NULL) { + global_tls_context = 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. + * identity 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) { crypto_pk_env_t *rsa = NULL; @@ -692,18 +719,12 @@ tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime) always_accept_verify_cb); /* let us realloc bufs that we're writing from */ 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: OpenSSL does - * reference counting with SSL and SSL_CTX objects. */ - tor_tls_context_decref(global_tls_context); - } - global_tls_context = result; + if (rsa) crypto_free_pk_env(rsa); tor_free(nickname); tor_free(nn2); - return 0; + return result; error: tls_log_errors(NULL, LOG_WARN, "creating TLS context"); @@ -719,7 +740,7 @@ tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime) X509_free(cert); if (idcert) X509_free(idcert); - return -1; + return NULL; } #ifdef V2_HANDSHAKE_SERVER diff --git a/src/common/tortls.h b/src/common/tortls.h index 9644b87f2c..3f80d998b7 100644 --- a/src/common/tortls.h +++ b/src/common/tortls.h @@ -50,7 +50,8 @@ typedef struct tor_tls_t tor_tls_t; const char *tor_tls_err_to_string(int err); 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(crypto_pk_env_t *identity, + unsigned int key_lifetime); 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_renegotiate_callback(tor_tls_t *tls, diff --git a/src/or/main.c b/src/or/main.c index 3c879dcd0e..fe1f42ece3 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -872,8 +872,7 @@ run_scheduled_events(time_t now) last_rotated_x509_certificate = now; if (last_rotated_x509_certificate+MAX_SSL_KEY_LIFETIME_INTERNAL < now) { log_info(LD_GENERAL,"Rotating tls context."); - if (tor_tls_context_new(get_identity_key(), - MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) { + if (tor_tls_context_init(get_identity_key(), 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 */ } diff --git a/src/or/router.c b/src/or/router.c index 45eeca09ff..9afa983bc3 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -458,8 +458,7 @@ init_keys(void) } set_identity_key(prkey); /* Create a TLS context; default the client nickname to "client". */ - if (tor_tls_context_new(get_identity_key(), - MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) { + if (tor_tls_context_init(get_identity_key(), MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) { log_err(LD_GENERAL,"Error creating TLS context for Tor client."); return -1; } @@ -537,7 +536,7 @@ init_keys(void) tor_free(keydir); /* 3. Initialize link key and TLS context. */ - if (tor_tls_context_new(get_identity_key(), + if (tor_tls_context_init(get_identity_key(), MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) { log_err(LD_GENERAL,"Error initializing TLS context"); return -1;