Explorar el Código

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

Nick Mathewson hace 12 años
padre
commit
25afecdbf9
Se han modificado 7 ficheros con 67 adiciones y 13 borrados
  1. 7 5
      changes/tls_ecdhe
  2. 6 0
      doc/tor.1.txt
  3. 24 6
      src/common/tortls.c
  4. 6 1
      src/common/tortls.h
  5. 10 0
      src/or/config.c
  6. 2 0
      src/or/or.h
  7. 12 1
      src/or/router.c

+ 7 - 5
changes/tls_ecdhe

@@ -1,10 +1,12 @@
   o Major features:
   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
       Enabling these ciphers was a little tricky, since for a long
       time, clients had been claiming to support them without
       time, clients had been claiming to support them without

+ 6 - 0
doc/tor.1.txt

@@ -1527,6 +1527,12 @@ is non-zero):
 **GeoIPv6File** __filename__::
 **GeoIPv6File** __filename__::
     A filename containing IPv6 GeoIP data, for use with by-country statistics.
     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**::
 **CellStatistics** **0**|**1**::
     When this option is enabled, Tor writes statistics on the mean time that
     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)
     cells spend in circuit queues to disk every 24 hours. (Default: 0)

+ 24 - 6
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,
 static int tor_tls_context_init_one(tor_tls_context_t **ppcontext,
                                     crypto_pk_t *identity,
                                     crypto_pk_t *identity,
                                     unsigned int key_lifetime,
                                     unsigned int key_lifetime,
+                                    unsigned int flags,
                                     int is_client);
                                     int is_client);
 static tor_tls_context_t *tor_tls_context_new(crypto_pk_t *identity,
 static tor_tls_context_t *tor_tls_context_new(crypto_pk_t *identity,
                                               unsigned int key_lifetime,
                                               unsigned int key_lifetime,
+                                              unsigned int flags,
                                               int is_client);
                                               int is_client);
 static int check_cert_lifetime_internal(int severity, const X509 *cert,
 static int check_cert_lifetime_internal(int severity, const X509 *cert,
                                    int past_tolerance, int future_tolerance);
                                    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.
 /** Create new global client and server TLS contexts.
  *
  *
  * If <b>server_identity</b> is NULL, this will not generate a server
  * 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
  * 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
 int
-tor_tls_context_init(int is_public_server,
+tor_tls_context_init(unsigned flags,
                      crypto_pk_t *client_identity,
                      crypto_pk_t *client_identity,
                      crypto_pk_t *server_identity,
                      crypto_pk_t *server_identity,
                      unsigned int key_lifetime)
                      unsigned int key_lifetime)
 {
 {
   int rv1 = 0;
   int rv1 = 0;
   int rv2 = 0;
   int rv2 = 0;
+  const int is_public_server = flags & TOR_TLS_CTX_IS_PUBLIC_SERVER;
 
 
   if (is_public_server) {
   if (is_public_server) {
     tor_tls_context_t *new_ctx;
     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,
     rv1 = tor_tls_context_init_one(&server_tls_context,
                                    server_identity,
                                    server_identity,
-                                   key_lifetime, 0);
+                                   key_lifetime, flags, 0);
 
 
     if (rv1 >= 0) {
     if (rv1 >= 0) {
       new_ctx = server_tls_context;
       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,
       rv1 = tor_tls_context_init_one(&server_tls_context,
                                      server_identity,
                                      server_identity,
                                      key_lifetime,
                                      key_lifetime,
+                                     flags,
                                      0);
                                      0);
     } else {
     } else {
       tor_tls_context_t *old_ctx = server_tls_context;
       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,
     rv2 = tor_tls_context_init_one(&client_tls_context,
                                    client_identity,
                                    client_identity,
                                    key_lifetime,
                                    key_lifetime,
+                                   flags,
                                    1);
                                    1);
   }
   }
 
 
@@ -1164,10 +1171,12 @@ static int
 tor_tls_context_init_one(tor_tls_context_t **ppcontext,
 tor_tls_context_init_one(tor_tls_context_t **ppcontext,
                          crypto_pk_t *identity,
                          crypto_pk_t *identity,
                          unsigned int key_lifetime,
                          unsigned int key_lifetime,
+                         unsigned int flags,
                          int is_client)
                          int is_client)
 {
 {
   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,
+                                                   flags,
                                                    is_client);
                                                    is_client);
   tor_tls_context_t *old_ctx = *ppcontext;
   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 *
 static tor_tls_context_t *
 tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime,
 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;
   crypto_pk_t *rsa = NULL, *rsa_auth = NULL;
   EVP_PKEY *pkey = 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) &&                         \
 #if (!defined(OPENSSL_NO_EC) &&                         \
      OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,0))
      OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,0))
   if (! is_client) {
   if (! is_client) {
+    int nid;
     EC_KEY *ec_key;
     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. */
     /* 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? */
     if (ec_key != NULL) /*XXXX Handle errors? */
       SSL_CTX_set_tmp_ecdh(result->ctx, ec_key);
       SSL_CTX_set_tmp_ecdh(result->ctx, ec_key);
     EC_KEY_free(ec_key);
     EC_KEY_free(ec_key);

+ 6 - 1
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_get_state_description(tor_tls_t *tls, char *buf, size_t sz);
 
 
 void tor_tls_free_all(void);
 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 *client_identity,
                          crypto_pk_t *server_identity,
                          crypto_pk_t *server_identity,
                          unsigned int key_lifetime);
                          unsigned int key_lifetime);

+ 10 - 0
src/or/config.c

@@ -372,6 +372,7 @@ static config_var_t option_vars_[] = {
   OBSOLETE("TestVia"),
   OBSOLETE("TestVia"),
   V(TokenBucketRefillInterval,   MSEC_INTERVAL, "100 msec"),
   V(TokenBucketRefillInterval,   MSEC_INTERVAL, "100 msec"),
   V(Tor2webMode,                 BOOL,     "0"),
   V(Tor2webMode,                 BOOL,     "0"),
+  V(TLSECGroup,                  STRING,   NULL),
   V(TrackHostExits,              CSV,      NULL),
   V(TrackHostExits,              CSV,      NULL),
   V(TrackHostExitsExpire,        INTERVAL, "30 minutes"),
   V(TrackHostExitsExpire,        INTERVAL, "30 minutes"),
   OBSOLETE("TrafficShaping"),
   OBSOLETE("TrafficShaping"),
@@ -1193,6 +1194,9 @@ options_transition_requires_fresh_tls_context(const or_options_t *old_options,
     return 1;
     return 1;
   }
   }
 
 
+  if (!opt_streq(old_options->TLSECGroup, new_options->TLSECGroup))
+    return 1;
+
   return 0;
   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) {
   if (options->ExcludeNodes && options->StrictNodes) {
     COMPLAIN("You have asked to exclude certain relays from all positions "
     COMPLAIN("You have asked to exclude certain relays from all positions "
              "in your circuits. Expect hidden services and other Tor "
              "in your circuits. Expect hidden services and other Tor "

+ 2 - 0
src/or/or.h

@@ -3854,6 +3854,8 @@ typedef struct {
 
 
   int IPv6Exit; /**< Do we support exiting to IPv6 addresses? */
   int IPv6Exit; /**< Do we support exiting to IPv6 addresses? */
 
 
+  char *TLSECGroup; /**< One of "P256", "P224", or nil for auto */
+
 } or_options_t;
 } or_options_t;
 
 
 /** Persistent state for an onion router, as saved to disk. */
 /** Persistent state for an onion router, as saved to disk. */

+ 12 - 1
src/or/router.c

@@ -491,7 +491,18 @@ v3_authority_check_key_expiry(void)
 int
 int
 router_initialize_tls_context(void)
 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(),
                               get_tlsclient_identity_key(),
                               server_mode(get_options()) ?
                               server_mode(get_options()) ?
                               get_server_identity_key() : NULL,
                               get_server_identity_key() : NULL,