mirror of
https://github.com/torproject/torspec.git
synced 2024-12-13 21:48:45 +00:00
251 lines
8.2 KiB
Plaintext
251 lines
8.2 KiB
Plaintext
Filename: 222-remove-client-timestamps.txt
|
|
Title: Stop sending client timestamps
|
|
Authors: Nick Mathewson
|
|
Created: 22 August 2013
|
|
Status: Closed
|
|
Implemented-In: 0.2.4.18
|
|
|
|
0. Summary
|
|
|
|
There are a few places in Tor where clients and servers send
|
|
timestamps. I list them and discuss how to eliminate them.
|
|
|
|
1. Introduction
|
|
|
|
Despite this late date, many hosts aren't running NTP and
|
|
don't have very well synchronized clocks. Even more hosts
|
|
aren't running a secure NTP; it's probably easy to
|
|
desynchronize target hosts.
|
|
|
|
Given all of this, it's probably a fingerprinting opportunity
|
|
whenever clients send their view of the current time.
|
|
Let's try to avoid that.
|
|
|
|
I'm also going to list the places where servers send their
|
|
view of the current time, and propose that we eliminate some
|
|
of those.
|
|
|
|
Scope: This proposal is about eliminating passive timestamp
|
|
exposure, not about tricky active detection mechanisms where
|
|
you do something like offering a client a large number of
|
|
about-to-expire/just-expired certificates to see which ones
|
|
they accept.
|
|
|
|
2. The Tor link protocol
|
|
|
|
2.1. NETINFO (client and server)
|
|
|
|
NETINFO cells specify that both parties include a 4-byte
|
|
timestamp.
|
|
|
|
Instead, let's say that clients should set this timestamp to
|
|
0. Nothing currently looks at a client's setting for this
|
|
field, so this change should be safe.
|
|
|
|
2.2. AUTHENTICATE (server)
|
|
|
|
The AUTHENTICATE cell is not ordinarily sent by clients. It
|
|
contains an 8-byte timestamp and a 16-byte random value.
|
|
Instead, let's just send 24 bytes or random value.
|
|
|
|
(An earlier version of this proposal suggested that we replace
|
|
them both with a 24-byte (truncated) HMAC of the current time,
|
|
using a random key, in an attempt to retain the allegedly
|
|
desirable property of avoiding nonce duplication in the event of
|
|
a bad RNG. But really, a Tor process with a bad RNG is not going
|
|
to get security in any case, so let's KISS.)
|
|
|
|
2.3. TLS
|
|
|
|
2.3.1. ClientRandom in the TLS handshake
|
|
|
|
See TLS proposal in appendix A.
|
|
|
|
This presents a TLS fingerprinting/censorship opportunity. I
|
|
propose that we investigate whether "random " or "zero" is
|
|
more common on the wire, choose that, and lobby for changes to
|
|
TLS implementations.
|
|
|
|
2.3.2. Certificate validity intervals
|
|
|
|
Servers use the current time in setting certificate validity
|
|
for their initial certificates. They randomize this value
|
|
somewhat. I propose that we don't change this, since it's a
|
|
server-only issue, and already somewhat mitigated.
|
|
|
|
3. Directory protocol
|
|
|
|
3.1. Published
|
|
|
|
This field in descriptors is generated by servers only; I
|
|
propose no change.
|
|
|
|
3.2. The Date header
|
|
|
|
This HTTP header is sent by directory servers only; I propose
|
|
no change.
|
|
|
|
4. The hidden service protocol
|
|
|
|
4.1. Descriptor publication time
|
|
|
|
Hidden service descriptors include a publication time. I
|
|
propose that we round this time down to the nearest N minutes,
|
|
where N=60.
|
|
|
|
4.2. INTRODUCE2 cell timestamp
|
|
|
|
INTRODUCE2 cells once limited the duration of their replay
|
|
caches by including a timestamp in the INTRODUCE2 cells. Since
|
|
0.2.3.9-alpha, this timestamp is ignored, and key lifetime is
|
|
used instead.
|
|
|
|
When we determine that no hidden services are running on
|
|
0.2.2.x (and really, no hidden services should be running on
|
|
0.2.2.x!), we can simply send 0 instead. (See ticket #7803).
|
|
|
|
We can control this behavior with a consensus parameter
|
|
(Support022HiddenServices) and a tristate (0/1/auto) torrc option of
|
|
the same name.
|
|
|
|
When the timestamp is not completely disabled, it should be
|
|
rounded to the closest 10 minutes.
|
|
|
|
I claim this would be suitable for backport to 0.2.4.
|
|
|
|
5. The application layer
|
|
|
|
The application layer is mostly out of scope for this proposal,
|
|
except:
|
|
|
|
TorBrowser already (I hear) drops the timestamp from the
|
|
ClientRandom field in TLS. We should encourage other TLS
|
|
applications to do so. (See Appendix A.)
|
|
|
|
|
|
|
|
=================================================================
|
|
APPENDIX A: "Let's replace gmt_unix_time in TLS"
|
|
|
|
PROBLEM:
|
|
|
|
The gmt_unix_time field in the Random field in the TLS handshake
|
|
provides a way for an observer to fingerprint clients.
|
|
|
|
Despite the late date, much of the world is still not
|
|
synchronized to the second via an ntp-like service. This means
|
|
that different clients have different views of the current time,
|
|
which provides a fingerprint that helps to track and distinguish
|
|
them. This fingerprint is useful for tracking clients as they
|
|
move around. It can also distinguish clients using a single VPN,
|
|
NAT, or privacy network. (Tor's modified firefox avoids this by
|
|
not sending the time.)
|
|
|
|
Worse, some implementations don't send the current time, but the
|
|
process time, or the computer's uptime, both of which are far
|
|
more distinguishing than the current time() value.
|
|
|
|
The information fingerprint here is strong enough to uniquely
|
|
identify some TLS users (the ones whose clocks are hours off).
|
|
Even for the ones whose clocks are mostly right (within a second
|
|
or two), the field leaks a bit of information, and it only takes
|
|
so many bits to make a user unique.
|
|
|
|
|
|
WHY gmt_unix_time IN THE FIRST PLACE?
|
|
|
|
According to third-hand reports -- (and correct me if I'm wrong!)
|
|
it was introduced in SSL 3.0 to prevent complete failure in cases
|
|
where the PRNG was completely broken, by making a part of the
|
|
Random field that would definitely vary between TLS handshakes.
|
|
|
|
I doubt that this goal is really achieved: on modern desktop
|
|
environments, it's not really so strange to start two TLS
|
|
connections within the same second.
|
|
|
|
WHY ELSE IS gmt_unix_time USED?
|
|
|
|
The consensus among implementors seems to be that it's unwise to
|
|
depend on any particular value or interpretation for the field.
|
|
The TLS 1.2 standard, RFC 5246, says that "Clocks are not
|
|
required to be set correctly by the basic TLS protocol;
|
|
higher-level or application protocols may define additional
|
|
requirements."
|
|
|
|
Some implementations set the entire field randomly; this appears
|
|
not to have broken TLS on the internet.
|
|
|
|
At least one tool (tlsdate) uses the server-side value of the
|
|
field as an authenticated view of the current time.
|
|
|
|
|
|
|
|
PROPOSAL 1:
|
|
|
|
Declare that implementations MAY replace gmt_unix_time either
|
|
with four more random bytes, or four bytes of zeroes.
|
|
|
|
Make your implementation just do that.
|
|
|
|
(Rationale: some implementations (like TorBrowser) are already
|
|
doing this in practice. It's sensible and simple. You're
|
|
unlikely to mess it up, or cause trouble.)
|
|
|
|
|
|
|
|
PROPOSAL 2:
|
|
|
|
Okay, if you really want to preserve the security allegedly
|
|
provided by gmt_unix_time, allow the following approach instead:
|
|
|
|
Set the Random field, not to 32 bytes from your PRNG, but to the
|
|
HMAC-SHA256 of any high resolution timer that you have, using 32
|
|
bytes from your PRNG as a key. In other words, replace this:
|
|
|
|
Random.gmt_unix_time = time();
|
|
Random.random_bytes = get_random_bytes(28)
|
|
|
|
with this:
|
|
|
|
now = hires_time(); // clock_gettime(), or concatenate time()
|
|
// with a CPU timer, or process
|
|
// uptime, or whatever.
|
|
key = get_random_bytes(32);
|
|
Random = hmac_sha256(key, now);
|
|
|
|
This approach is better than the status quo on the following
|
|
counts:
|
|
|
|
* It doesn't leak your view of the current time, assuming that
|
|
your PRNG isn't busted.
|
|
|
|
* It actually fixes the problem that gmt_unix_time purported to
|
|
fix, by using a high-resolution time that's much less likely to
|
|
be used twice. Even if the PRNG is broken, the value is still
|
|
nonrepeating.
|
|
|
|
It is not worse than the status quo:
|
|
|
|
* It is unpredictable from an attacker's POV, assuming that the
|
|
PRNG works. (Because an HMAC, even of known data, with an
|
|
unknown random key is supposed to look random).
|
|
|
|
|
|
CONSIDERATIONS:
|
|
|
|
I'd personally suggest proposal 1 (just set the field at random) for
|
|
most users. Yes, it makes things a little worse if your PRNG can
|
|
generate repeat values... but nearly everything in cryptography
|
|
fails if your PRNG is broken.
|
|
|
|
|
|
You might want to apply this fix on clients only. With a few
|
|
exceptions (like hidden services) the server's view of the current
|
|
time is not sensitive.
|
|
|
|
|
|
Implementors might want to make this feature optional and
|
|
on-by-default, just in case some higher-level application protocol
|
|
really does depend on it.
|
|
==================================================================
|