Browse Source

Merge branch 'maint-0.2.4'

Roger Dingledine 12 years ago
parent
commit
331e4dcb46
6 changed files with 46 additions and 11 deletions
  1. 4 0
      changes/ticket8443
  2. 7 2
      doc/tor.1.txt
  3. 11 5
      src/common/tortls.c
  4. 1 0
      src/or/config.c
  5. 4 2
      src/or/or.h
  6. 19 2
      src/or/router.c

+ 4 - 0
changes/ticket8443

@@ -0,0 +1,4 @@
+  o Minor features:
+    - Randomize the lifetime of our SSL link certificate, so censors can't
+      use the static value for filtering Tor flows. Resolves ticket 8443;
+      related to ticket 4014 which was included in 0.2.2.33.

+ 7 - 2
doc/tor.1.txt

@@ -1500,8 +1500,13 @@ is non-zero):
 **ShutdownWaitLength** __NUM__::
     When we get a SIGINT and we're a server, we begin shutting down:
     we close listeners and start refusing new circuits. After **NUM**
-    seconds, we exit. If we get a second SIGINT, we exit immedi-
-    ately. (Default: 30 seconds)
+    seconds, we exit. If we get a second SIGINT, we exit immediately.
+    (Default: 30 seconds)
+
+**SSLKeyLifetime** __N__ **minutes**|**hours**|**days**|**weeks**::
+    When creating a link certificate for our outermost SSL handshake,
+    set its lifetime to this amount of time. If set to 0, Tor will choose
+    some reasonable random defaults. (Default: 0)
 
 **HeartbeatPeriod**  __N__ **minutes**|**hours**|**days**|**weeks**::
     Log a heartbeat message every **HeartbeatPeriod** seconds. This is

+ 11 - 5
src/common/tortls.c

@@ -234,7 +234,7 @@ static X509* tor_tls_create_certificate(crypto_pk_t *rsa,
                                         crypto_pk_t *rsa_sign,
                                         const char *cname,
                                         const char *cname_sign,
-                                        unsigned int lifetime);
+                                        unsigned int cert_lifetime);
 
 static int tor_tls_context_init_one(tor_tls_context_t **ppcontext,
                                     crypto_pk_t *identity,
@@ -608,9 +608,10 @@ tor_x509_name_new(const char *cname)
 /** Generate and sign an X509 certificate with the public key <b>rsa</b>,
  * signed by the private key <b>rsa_sign</b>.  The commonName of the
  * certificate will be <b>cname</b>; the commonName of the issuer will be
- * <b>cname_sign</b>. The cert will be valid for <b>cert_lifetime</b> seconds
- * starting from now.  Return a certificate on success, NULL on
- * failure.
+ * <b>cname_sign</b>. The cert will be valid for <b>cert_lifetime</b>
+ * seconds, starting from some time in the past.
+ *
+ * Return a certificate on success, NULL on failure.
  */
 static X509 *
 tor_tls_create_certificate(crypto_pk_t *rsa,
@@ -632,7 +633,12 @@ tor_tls_create_certificate(crypto_pk_t *rsa,
 
   tor_tls_init();
 
-  start_time = time(NULL);
+  /* Make sure we're part-way through the certificate lifetime, rather
+   * than having it start right now. Don't choose quite uniformly, since
+   * then we might pick a time where we're about to expire. Lastly, be
+   * sure to start on a day boundary. */
+  start_time = time(NULL) - crypto_rand_int(cert_lifetime) + 2*24*3600;
+  start_time -= start_time % (24*3600);
 
   tor_assert(rsa);
   tor_assert(cname);

+ 1 - 0
src/or/config.c

@@ -380,6 +380,7 @@ static config_var_t option_vars_[] = {
   V(SocksPolicy,                 LINELIST, NULL),
   VPORT(SocksPort,                   LINELIST, NULL),
   V(SocksTimeout,                INTERVAL, "2 minutes"),
+  V(SSLKeyLifetime,              INTERVAL, "0"),
   OBSOLETE("StatusFetchPeriod"),
   V(StrictNodes,                 BOOL,     "0"),
   OBSOLETE("SysLog"),

+ 4 - 2
src/or/or.h

@@ -177,8 +177,6 @@
 #define MIN_ONION_KEY_LIFETIME (7*24*60*60)
 /** How often do we rotate TLS contexts? */
 #define MAX_SSL_KEY_LIFETIME_INTERNAL (2*60*60)
-/** What expiry time shall we place on our SSL certs? */
-#define MAX_SSL_KEY_LIFETIME_ADVERTISED (365*24*60*60)
 
 /** How old do we allow a router to get before removing it
  * from the router list? In seconds. */
@@ -4010,6 +4008,10 @@ typedef struct {
    */
   int DisableV2DirectoryInfo_;
 
+  /** What expiry time shall we place on our SSL certs? "0" means we
+   * should guess a suitable value. */
+  int SSLKeyLifetime;
+
 } or_options_t;
 
 /** Persistent state for an onion router, as saved to disk. */

+ 19 - 2
src/or/router.c

@@ -650,6 +650,7 @@ router_initialize_tls_context(void)
 {
   unsigned int flags = 0;
   const or_options_t *options = get_options();
+  int lifetime = options->SSLKeyLifetime;
   if (public_server_mode(options))
     flags |= TOR_TLS_CTX_IS_PUBLIC_SERVER;
   if (options->TLSECGroup) {
@@ -658,12 +659,28 @@ router_initialize_tls_context(void)
     else if (!strcasecmp(options->TLSECGroup, "P224"))
       flags |= TOR_TLS_CTX_USE_ECDHE_P224;
   }
+  if (!lifetime) { /* we should guess a good ssl cert lifetime */
 
+    /* choose between 5 and 365 days, and round to the day */
+    lifetime = 5*24*3600 + crypto_rand_int(361*24*3600);
+    lifetime -= lifetime % (24*3600);
+
+    if (crypto_rand_int(2)) {
+      /* Half the time we expire at midnight, and half the time we expire
+       * one second before midnight. (Some CAs wobble their expiry times a
+       * bit in practice, perhaps to reduce collision attacks; see ticket
+       * 8443 for details about observed certs in the wild.) */
+      lifetime--;
+    }
+  }
+
+  /* It's ok to pass lifetime in as an unsigned int, since
+   * config_parse_interval() checked it. */
   return tor_tls_context_init(flags,
                               get_tlsclient_identity_key(),
-                              server_mode(get_options()) ?
+                              server_mode(options) ?
                               get_server_identity_key() : NULL,
-                              MAX_SSL_KEY_LIFETIME_ADVERTISED);
+                              (unsigned int)lifetime);
 }
 
 /** Initialize all OR private keys, and the TLS context, as necessary.