Commit 25afecdb authored by Nick Mathewson's avatar Nick Mathewson 🎨
Browse files

Make ECDHE group configurable: 224 for public, 256 for bridges (default)

parent c8b3bdb7
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
......
......@@ -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)
......
......@@ -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);
......
......@@ -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);
......
......@@ -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 "
......
......@@ -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. */
......
......@@ -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,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment