diff options
author | Nick Mathewson <nickm@torproject.org> | 2012-12-25 20:04:54 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2012-12-25 20:22:46 -0500 |
commit | 25afecdbf999eb91ed9216be1f8b8cdf0f78135b (patch) | |
tree | 73665d46e5858deac1c95c2473166c8c67e98dc7 | |
parent | c8b3bdb78215d4d7821d9bfa15bb8f7786403ce9 (diff) | |
download | tor-25afecdbf999eb91ed9216be1f8b8cdf0f78135b.tar tor-25afecdbf999eb91ed9216be1f8b8cdf0f78135b.tar.gz |
Make ECDHE group configurable: 224 for public, 256 for bridges (default)
-rw-r--r-- | changes/tls_ecdhe | 12 | ||||
-rw-r--r-- | doc/tor.1.txt | 6 | ||||
-rw-r--r-- | src/common/tortls.c | 30 | ||||
-rw-r--r-- | src/common/tortls.h | 7 | ||||
-rw-r--r-- | src/or/config.c | 10 | ||||
-rw-r--r-- | src/or/or.h | 2 | ||||
-rw-r--r-- | src/or/router.c | 13 |
7 files changed, 67 insertions, 13 deletions
diff --git a/changes/tls_ecdhe b/changes/tls_ecdhe index 58a8f9069..48c6384da 100644 --- a/changes/tls_ecdhe +++ b/changes/tls_ecdhe @@ -1,10 +1,12 @@ o Major features: - - Servers can now enable the ECDHE TLS ciphersuites when - available and appropriate. These ciphersuites, when used with - the P-256 elliptic curve, let us negotiate forward-secure TLS - secret keys more safely and more efficiently than with our - previous use of Diffie Hellman modulo a 1024-bit prime. + - Servers can now enable the ECDHE TLS ciphersuites when available + and appropriate. These ciphersuites let us negotiate forward- + secure TLS secret keys more safely and more efficiently than with + our previous use of Diffie Hellman modulo a 1024-bit prime. + By default, public servers prefer the (faster) P224 group, and + bridges prefer the (more common) P256 group; you can override this + with the TLSECGroup option. Enabling these ciphers was a little tricky, since for a long time, clients had been claiming to support them without diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 85b7f4c35..7d1742c0e 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -1527,6 +1527,12 @@ is non-zero): **GeoIPv6File** __filename__:: A filename containing IPv6 GeoIP data, for use with by-country statistics. +**TLSECGroup** **P224**|**P256**:: + What EC group should we try to use for incoming TLS connections? + P224 is faster, but makes us stand out more. Has no effect if + we're a client, or if our OpenSSL version lacks support for ECDHE. + (Default: P224 for public servers; P256 for bridges.) + **CellStatistics** **0**|**1**:: When this option is enabled, Tor writes statistics on the mean time that cells spend in circuit queues to disk every 24 hours. (Default: 0) diff --git a/src/common/tortls.c b/src/common/tortls.c index 47b8f2815..ce6c7d67c 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -236,9 +236,11 @@ static X509* tor_tls_create_certificate(crypto_pk_t *rsa, static int tor_tls_context_init_one(tor_tls_context_t **ppcontext, crypto_pk_t *identity, unsigned int key_lifetime, + unsigned int flags, int is_client); static tor_tls_context_t *tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime, + unsigned int flags, int is_client); static int check_cert_lifetime_internal(int severity, const X509 *cert, int past_tolerance, int future_tolerance); @@ -1098,17 +1100,20 @@ tor_tls_context_incref(tor_tls_context_t *ctx) /** 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 + * TLS context. If TOR_TLS_CTX_IS_PUBLIC_SERVER is set in <b>flags</b>, use * the same TLS context for incoming and outgoing connections, and - * ignore <b>client_identity</b>. */ + * ignore <b>client_identity</b>. If one of TOR_TLS_CTX_USE_ECDHE_P{224,256} + * is set in <b>flags</b>, use that ECDHE group if possible; otherwise use + * the default ECDHE group. */ int -tor_tls_context_init(int is_public_server, +tor_tls_context_init(unsigned flags, crypto_pk_t *client_identity, crypto_pk_t *server_identity, unsigned int key_lifetime) { int rv1 = 0; int rv2 = 0; + const int is_public_server = flags & TOR_TLS_CTX_IS_PUBLIC_SERVER; if (is_public_server) { tor_tls_context_t *new_ctx; @@ -1118,7 +1123,7 @@ tor_tls_context_init(int is_public_server, rv1 = tor_tls_context_init_one(&server_tls_context, server_identity, - key_lifetime, 0); + key_lifetime, flags, 0); if (rv1 >= 0) { new_ctx = server_tls_context; @@ -1135,6 +1140,7 @@ tor_tls_context_init(int is_public_server, rv1 = tor_tls_context_init_one(&server_tls_context, server_identity, key_lifetime, + flags, 0); } else { tor_tls_context_t *old_ctx = server_tls_context; @@ -1148,6 +1154,7 @@ tor_tls_context_init(int is_public_server, rv2 = tor_tls_context_init_one(&client_tls_context, client_identity, key_lifetime, + flags, 1); } @@ -1164,10 +1171,12 @@ static int tor_tls_context_init_one(tor_tls_context_t **ppcontext, crypto_pk_t *identity, unsigned int key_lifetime, + unsigned int flags, int is_client) { tor_tls_context_t *new_ctx = tor_tls_context_new(identity, key_lifetime, + flags, is_client); tor_tls_context_t *old_ctx = *ppcontext; @@ -1191,7 +1200,7 @@ tor_tls_context_init_one(tor_tls_context_t **ppcontext, */ static tor_tls_context_t * tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime, - int is_client) + unsigned flags, int is_client) { crypto_pk_t *rsa = NULL, *rsa_auth = NULL; EVP_PKEY *pkey = NULL; @@ -1362,9 +1371,18 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime, #if (!defined(OPENSSL_NO_EC) && \ OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,0)) if (! is_client) { + int nid; EC_KEY *ec_key; + if (flags & TOR_TLS_CTX_USE_ECDHE_P224) + nid = NID_secp224r1; + else if (flags & TOR_TLS_CTX_USE_ECDHE_P256) + nid = NID_X9_62_prime256v1; + else if (flags & TOR_TLS_CTX_IS_PUBLIC_SERVER) + nid = NID_X9_62_prime256v1; + else + nid = NID_secp224r1; /* Use P-256 for ECDHE. */ - ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + ec_key = EC_KEY_new_by_curve_name(nid); if (ec_key != NULL) /*XXXX Handle errors? */ SSL_CTX_set_tmp_ecdh(result->ctx, ec_key); EC_KEY_free(ec_key); diff --git a/src/common/tortls.h b/src/common/tortls.h index 8881827ce..df3ab87a1 100644 --- a/src/common/tortls.h +++ b/src/common/tortls.h @@ -54,7 +54,12 @@ const char *tor_tls_err_to_string(int err); void tor_tls_get_state_description(tor_tls_t *tls, char *buf, size_t sz); void tor_tls_free_all(void); -int tor_tls_context_init(int is_public_server, + +#define TOR_TLS_CTX_IS_PUBLIC_SERVER (1u<<0) +#define TOR_TLS_CTX_USE_ECDHE_P256 (1u<<1) +#define TOR_TLS_CTX_USE_ECDHE_P224 (1u<<2) + +int tor_tls_context_init(unsigned flags, crypto_pk_t *client_identity, crypto_pk_t *server_identity, unsigned int key_lifetime); diff --git a/src/or/config.c b/src/or/config.c index 1df10e110..b81edf749 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -372,6 +372,7 @@ static config_var_t option_vars_[] = { OBSOLETE("TestVia"), V(TokenBucketRefillInterval, MSEC_INTERVAL, "100 msec"), V(Tor2webMode, BOOL, "0"), + V(TLSECGroup, STRING, NULL), V(TrackHostExits, CSV, NULL), V(TrackHostExitsExpire, INTERVAL, "30 minutes"), OBSOLETE("TrafficShaping"), @@ -1193,6 +1194,9 @@ options_transition_requires_fresh_tls_context(const or_options_t *old_options, return 1; } + if (!opt_streq(old_options->TLSECGroup, new_options->TLSECGroup)) + return 1; + return 0; } @@ -2301,6 +2305,12 @@ options_validate(or_options_t *old_options, or_options_t *options, } } + if (options->TLSECGroup && (strcasecmp(options->TLSECGroup, "P256") && + strcasecmp(options->TLSECGroup, "P224"))) { + COMPLAIN("Unrecognized TLSECGroup: Falling back to the default."); + tor_free(options->TLSECGroup); + } + if (options->ExcludeNodes && options->StrictNodes) { COMPLAIN("You have asked to exclude certain relays from all positions " "in your circuits. Expect hidden services and other Tor " diff --git a/src/or/or.h b/src/or/or.h index 3a8e50c80..a65ca44ed 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3854,6 +3854,8 @@ typedef struct { int IPv6Exit; /**< Do we support exiting to IPv6 addresses? */ + char *TLSECGroup; /**< One of "P256", "P224", or nil for auto */ + } or_options_t; /** Persistent state for an onion router, as saved to disk. */ diff --git a/src/or/router.c b/src/or/router.c index 5786103b9..c7380cb44 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -491,7 +491,18 @@ v3_authority_check_key_expiry(void) int router_initialize_tls_context(void) { - return tor_tls_context_init(public_server_mode(get_options()), + unsigned int flags = 0; + const or_options_t *options = get_options(); + if (public_server_mode(options)) + flags |= TOR_TLS_CTX_IS_PUBLIC_SERVER; + if (options->TLSECGroup) { + if (!strcasecmp(options->TLSECGroup, "P256")) + flags |= TOR_TLS_CTX_USE_ECDHE_P256; + else if (!strcasecmp(options->TLSECGroup, "P224")) + flags |= TOR_TLS_CTX_USE_ECDHE_P224; + } + + return tor_tls_context_init(flags, get_tlsclient_identity_key(), server_mode(get_options()) ? get_server_identity_key() : NULL, |