Bug 1060179 - Use RLZ to hash device specific id into origin salt to give EME GMPs a per-origin and non transferrable node id. r=hsivonen,jesup
☠☠ backed out by 1466856e5208 ☠ ☠
authorChris Pearce <cpearce@mozilla.com>
Thu, 09 Oct 2014 17:01:03 +1300
changeset 209525 ca27bcfe3e5bacdc5161b5f5dda77944be627bd1
parent 209524 ff97841a1f5468353a48846b4354df89aa0d2672
child 209526 981994dec186511c9bdb4daceea90f6ba6312665
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewershsivonen, jesup
bugs1060179
milestone35.0a1
Bug 1060179 - Use RLZ to hash device specific id into origin salt to give EME GMPs a per-origin and non transferrable node id. r=hsivonen,jesup
content/media/gmp/GMPChild.cpp
--- a/content/media/gmp/GMPChild.cpp
+++ b/content/media/gmp/GMPChild.cpp
@@ -20,16 +20,31 @@
 using mozilla::dom::CrashReporterChild;
 
 #ifdef XP_WIN
 #include <stdlib.h> // for _exit()
 #else
 #include <unistd.h> // for _exit()
 #endif
 
+#if defined(XP_WIN)
+// In order to provide EME plugins with a "device binding" capability,
+// in the parent we generate and store some random bytes as salt for every
+// (origin, urlBarOrigin) pair that uses EME. We store these bytes so
+// that every time we revisit the same origin we get the same salt.
+// We send this salt to the child on startup. The child collects some
+// device specific data and munges that with the salt to create the
+// "node id" that we expose to EME plugins. It then overwrites the device
+// specific data, and activates the sandbox.
+#define HASH_NODE_ID_WITH_DEVICE_ID 1
+#include "rlz/lib/machine_id.h"
+#include "rlz/lib/string_utils.h"
+#include "mozilla/SHA1.h"
+#endif
+
 #if defined(MOZ_SANDBOX) && defined(XP_WIN)
 #define TARGET_SANDBOX_EXPORTS
 #include "mozilla/sandboxTarget.h"
 #elif defined (MOZ_GMP_SANDBOX)
 #if defined(XP_LINUX) || defined(XP_MACOSX)
 #include "mozilla/Sandbox.h"
 #endif
 #endif
@@ -234,18 +249,46 @@ GMPChild::Init(const std::string& aPlugi
 
   mPluginPath = aPluginPath;
   return true;
 }
 
 bool
 GMPChild::RecvSetNodeId(const nsCString& aNodeId)
 {
-  // TODO: hash mNodeId with machine specific data.
+#ifdef HASH_NODE_ID_WITH_DEVICE_ID
+  if (!aNodeId.IsEmpty() && !aNodeId.EqualsLiteral("null")) {
+    string16 deviceId;
+    int volumeId;
+    if (!rlz_lib::GetRawMachineId(&deviceId, &volumeId)) {
+      return false;
+    }
+
+    // TODO: Switch to SHA256.
+    mozilla::SHA1Sum hash;
+    hash.update(deviceId.c_str(), deviceId.size() * sizeof(string16::value_type));
+    hash.update(aNodeId.get(), aNodeId.Length());
+    hash.update(&volumeId, sizeof(int));
+    uint8_t digest[mozilla::SHA1Sum::kHashSize];
+    hash.finish(digest);
+    if (!rlz_lib::BytesToString(digest, mozilla::SHA1Sum::kHashSize, &mNodeId)) {
+      return false;
+    }
+
+    // Overwrite device id as it could potentially identify the user, so
+    // there's no chance a GMP can read it and use it for identity tracking.
+    volumeId = 0;
+    memset(&deviceId.front(), '*', sizeof(string16::size_type) * deviceId.size());
+    deviceId = L"";
+  } else {
+    mNodeId = "null";
+  }
+#else
   mNodeId = std::string(aNodeId.BeginReading(), aNodeId.EndReading());
+#endif
   return true;
 }
 
 bool
 GMPChild::RecvStartPlugin()
 {
 #if defined(MOZ_SANDBOX) && defined(XP_WIN)
   mozilla::SandboxTarget::Instance()->StartSandbox();