[tor-commits] [tor/master] Make ECDHE group configurable: 224 for public, 256 for bridges (default)
nickm at torproject.org
nickm at torproject.org
Wed Dec 26 03:13:09 UTC 2012
commit 25afecdbf999eb91ed9216be1f8b8cdf0f78135b
Author: Nick Mathewson <nickm at torproject.org>
Date: Tue Dec 25 20:04:54 2012 -0500
Make ECDHE group configurable: 224 for public, 256 for bridges (default)
---
changes/tls_ecdhe | 12 +++++++-----
doc/tor.1.txt | 6 ++++++
src/common/tortls.c | 30 ++++++++++++++++++++++++------
src/common/tortls.h | 7 ++++++-
src/or/config.c | 10 ++++++++++
src/or/or.h | 2 ++
src/or/router.c | 13 ++++++++++++-
7 files changed, 67 insertions(+), 13 deletions(-)
diff --git a/changes/tls_ecdhe b/changes/tls_ecdhe
index 58a8f90..48c6384 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 85b7f4c..7d1742c 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 47b8f28..ce6c7d6 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 8881827..df3ab87 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 1df10e1..b81edf7 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 3a8e50c..a65ca44 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 5786103..c7380cb 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,
More information about the tor-commits
mailing list