commit 0fbd44f0305a01a14bc7439f5ad66b59d9278a2d
Author: Yawning Angel <yawning(a)schwanenlied.me>
Date: Tue Jun 7 19:01:41 2016 +0000
Bug 19206: Include a 128 bit random tag as part of the domain isolator nonce.
When creating a domain isolation nonce, 128 bits of entropy is drawn
from a cryptographic source and saved on a per-domain basis. The new
circuit behavior is changed to regenerate the nonce, instead of
incrementing a counter.
This allows the "right thing" to happen when the same tor instance is
used across multiple Tor Browser sessions, for example when using a
system wide tor, or a magic anonymity box.
---
src/components/domain-isolator.js | 36 ++++++++++++++++++++++++++----------
1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/src/components/domain-isolator.js b/src/components/domain-isolator.js
index 6cfd21e..769c47d 100644
--- a/src/components/domain-isolator.js
+++ b/src/components/domain-isolator.js
@@ -16,6 +16,9 @@ const Cc = Components.classes, Ci = Components.interfaces, Cu = Components.utils
let logger = Cc["@torproject.org/torbutton-logger;1"]
.getService(Components.interfaces.nsISupports).wrappedJSObject;
+// Import crypto object (FF 37+).
+Cu.importGlobalProperties(["crypto"]);
+
// ## mozilla namespace.
// Useful functionality for interacting with Mozilla services.
let mozilla = {};
@@ -69,7 +72,7 @@ tor.socksProxyCredentials = function (originalProxy, domain) {
// Check if we already have a nonce. If not, create
// one for this domain.
if (!tor.noncesForDomains.hasOwnProperty(domain)) {
- tor.noncesForDomains[domain] = 0;
+ tor.noncesForDomains[domain] = tor.nonce();
}
let proxy = originalProxy.QueryInterface(Ci.nsIProxyInfo);
return mozilla.protocolProxyService
@@ -77,21 +80,34 @@ tor.socksProxyCredentials = function (originalProxy, domain) {
proxy.host,
proxy.port,
domain, // username
- tor.noncesForDomains[domain].toString(), // password
+ tor.noncesForDomains[domain], // password
proxy.flags,
proxy.failoverTimeout,
proxy.failoverProxy);
};
-tor.newCircuitForDomain = function(domain) {
- // Check if we already have a nonce. If not, create
- // one for this domain.
- if (!tor.noncesForDomains.hasOwnProperty(domain)) {
- tor.noncesForDomains[domain] = 0;
- } else {
- tor.noncesForDomains[domain] += 1;
+tor.nonce = function() {
+ // Generate a new 128 bit random tag. Strictly speaking both using a
+ // cryptographic entropy source and using 128 bits of entropy for the
+ // tag are likely overkill, as correct behavior only depends on how
+ // unlikely it is for there to be a collision.
+ let tag = new Uint8Array(16);
+ crypto.getRandomValues(tag);
+
+ // Convert the tag to a hex string.
+ let tagStr = "";
+ for (var i = 0; i < tag.length; i++) {
+ tagStr += (tag[i] >>> 4).toString(16);
+ tagStr += (tag[i] & 0x0F).toString(16);
}
- logger.eclog(3, "New domain isolation count " +tor.noncesForDomains[domain] + " for " + domain);
+
+ return tagStr;
+}
+
+tor.newCircuitForDomain = function(domain) {
+ // Re-generate the nonce for the domain.
+ tor.noncesForDomains[domain] = tor.nonce();
+ logger.eclog(3, "New domain isolation for " + domain + ": " + tor.noncesForDomains[domain]);
}
// __tor.isolateCircuitsByDomain()__.