Bug 1420836 - Part1 - Provide a utility function to compute the storage id. draft
authorJames Cheng <jacheng@mozilla.com>
Wed, 03 Jan 2018 15:23:15 +0800
changeset 720763 4d3ed4d2663109158d3abbab5bec1acfb918c4fe
parent 720191 21ddfb9e6cc008e47da89db50e22697dc7b38635
child 720764 dad35ee578bff28917e6c56a1dd700bca47db30a
child 720769 27d9efe3e8c32d3121da10452bbaaa7ac7391d24
push id95629
push userbmo:jacheng@mozilla.com
push dateTue, 16 Jan 2018 07:49:10 +0000
bugs1420836
milestone59.0a1
Bug 1420836 - Part1 - Provide a utility function to compute the storage id. The CDM on Mac and Windows will ask the host for storage id. We compute the storage id by hashing machine id, origin salt and browser id. MozReview-Commit-ID: 4fTCaOKgSIe
dom/media/gmp/CDMStorageIdProvider.cpp
dom/media/gmp/CDMStorageIdProvider.h
dom/media/gmp/moz.build
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/CDMStorageIdProvider.cpp
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "CDMStorageIdProvider.h"
+#include "GMPLog.h"
+#include "nsCOMPtr.h"
+#include "nsComponentManagerUtils.h"
+#include "nsICryptoHash.h"
+
+#ifdef SUPPORT_STORAGE_ID
+#include "rlz/lib/machine_id.h"
+#endif
+
+namespace mozilla {
+
+/*static*/ nsCString
+CDMStorageIdProvider::ComputeStorageId(const nsCString& aOriginSalt)
+{
+#ifndef SUPPORT_STORAGE_ID
+  return EmptyCString();
+#else
+  GMP_LOG("CDMStorageIdProvider::ComputeStorageId");
+
+  std::string machineId;
+  if (!rlz_lib::GetMachineId(&machineId)) {
+    GMP_LOG("CDMStorageIdProvider::ComputeStorageId: get machineId failed.");
+    return EmptyCString();
+  }
+
+  std::string originSalt(aOriginSalt.BeginReading(), aOriginSalt.Length());
+  std::string input = machineId + originSalt + CDMStorageIdProvider::kBrowserIdentifier;
+  nsAutoCString storageId;
+  nsresult rv;
+  nsCOMPtr<nsICryptoHash> hasher = do_CreateInstance("@mozilla.org/security/hash;1", &rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    GMP_LOG("CDMStorageIdProvider::ComputeStorageId: no crypto hash(0x%08" PRIx32 ")",
+            static_cast<uint32_t>(rv));
+    return EmptyCString();
+  }
+
+  rv = hasher->Init(nsICryptoHash::SHA256);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    GMP_LOG("CDMStorageIdProvider::ComputeStorageId: failed to initialize hash(0x%08" PRIx32 ")",
+            static_cast<uint32_t>(rv));
+    return EmptyCString();
+  }
+
+  rv = hasher->Update(reinterpret_cast<const uint8_t*>(input.c_str()), input.size());
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    GMP_LOG("CDMStorageIdProvider::ComputeStorageId: failed to update hash(0x%08" PRIx32 ")",
+            static_cast<uint32_t>(rv));
+    return EmptyCString();
+  }
+
+  rv = hasher->Finish(false, storageId);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    GMP_LOG("CDMStorageIdProvider::ComputeStorageId: failed to get the final hash result(0x%08" PRIx32 ")",
+            static_cast<uint32_t>(rv));
+    return EmptyCString();
+  }
+  return storageId;
+#endif
+}
+
+} // namespace mozilla
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/CDMStorageIdProvider.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef CDMStorageIdProvider_h_
+#define CDMStorageIdProvider_h_
+
+/**
+ * CDM will try to request a latest version(0) of storage id.
+ * If the storage id computation algorithm changed, we should increase the kCurrentVersion.
+*/
+
+#include <string>
+
+#include "nsString.h"
+
+namespace mozilla {
+
+class CDMStorageIdProvider
+{
+  static constexpr const char* kBrowserIdentifier =
+    "mozilla_firefox_gecko";
+
+public:
+  // Should increase the value when the storage id algorithm changed.
+  static constexpr int kCurrentVersion = 1;
+  static constexpr int kCDMRequestLatestVersion = 0;
+
+  // Return empty string when
+  // 1. Call on unsupported storageid platform.
+  // 2. Failed to compute the storage id.
+  // This function only provide the storage id for kCurrentVersion=1.
+  // If you want to change the algorithm or output of storageid,
+  // you should keep the version 1 storage id and consider to provide
+  // higher version storage id in another function.
+  static nsCString ComputeStorageId(const nsCString& aOriginSalt);
+
+};
+
+} // namespace mozilla
+
+#endif // CDMStorageIdProvider_h_
--- a/dom/media/gmp/moz.build
+++ b/dom/media/gmp/moz.build
@@ -61,16 +61,17 @@ EXPORTS += [
     'GMPVideoi420FrameImpl.h',
     'GMPVideoPlaneImpl.h',
     'widevine-adapter/content_decryption_module.h',
     'widevine-adapter/content_decryption_module_export.h',
     'widevine-adapter/content_decryption_module_ext.h',
 ]
 
 UNIFIED_SOURCES += [
+    'CDMStorageIdProvider.cpp',
     'ChromiumCDMAdapter.cpp',
     'ChromiumCDMCallbackProxy.cpp',
     'ChromiumCDMChild.cpp',
     'ChromiumCDMParent.cpp',
     'ChromiumCDMProxy.cpp',
     'DecryptJob.cpp',
     'GMPChild.cpp',
     'GMPContentChild.cpp',
@@ -115,16 +116,19 @@ IPDL_SOURCES += [
   'PGMPContent.ipdl',
   'PGMPService.ipdl',
   'PGMPStorage.ipdl',
   'PGMPTimer.ipdl',
   'PGMPVideoDecoder.ipdl',
   'PGMPVideoEncoder.ipdl',
 ]
 
+if CONFIG['OS_TARGET'] in ['WINNT', 'Darwin']:
+    DEFINES['SUPPORT_STORAGE_ID'] = 1;
+
 # comment this out to use Unsafe Shmem for more performance
 DEFINES['GMP_SAFE_SHMEM'] = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 if CONFIG['MOZ_SANDBOX']:
     # For sandbox includes and the include dependencies those have
     LOCAL_INCLUDES += [