Bug 1308076 - Ensure Primetime PSSH boxes pass the PSSH validator. r=jwwang draft
authorChris Pearce <cpearce@mozilla.com>
Mon, 10 Oct 2016 23:47:28 -0700
changeset 423467 53910f929c630fd2f44f9ae71fc6dcf1c859c6d8
parent 423466 6427f09f963e706c689baad6ca08abc52ce1f663
child 533459 c3c4ad1fdf5d575a2b96c2399c85e8e722267ff6
push id31912
push userbmo:cpearce@mozilla.com
push dateTue, 11 Oct 2016 08:02:34 +0000
reviewersjwwang
bugs1308076
milestone52.0a1
Bug 1308076 - Ensure Primetime PSSH boxes pass the PSSH validator. r=jwwang Primetime PSSH boxes don't use the common encryption system ID. So to ensure we don't break any existing Primetime players, we must allow PSSH boxes with the Primetime system ID to pass the PSSH validator. MozReview-Commit-ID: 3q58FKLQXgV
media/psshparser/PsshParser.cpp
media/psshparser/gtest/TestPsshParser.cpp
--- a/media/psshparser/PsshParser.cpp
+++ b/media/psshparser/PsshParser.cpp
@@ -102,16 +102,21 @@ private:
 
  // System ID identifying the cenc v2 pssh box format; specified at:
  // https://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/cenc-format.html
 const uint8_t kSystemID[] = {
   0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02,
   0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b
 };
 
+const uint8_t kPrimetimeID[] = {
+  0xf2, 0x39, 0xe7, 0x69, 0xef, 0xa3, 0x48, 0x50,
+  0x9c, 0x16, 0xa9, 0x03, 0xc6, 0x93, 0x2e, 0xfb
+};
+
 bool
 ParseCENCInitData(const uint8_t* aInitData,
                   uint32_t aInitDataSize,
                   std::vector<std::vector<uint8_t>>& aOutKeyIds)
 {
   aOutKeyIds.clear();
   std::vector<std::vector<uint8_t>> keyIds;
   ByteReader reader(aInitData, aInitDataSize);
@@ -152,16 +157,22 @@ ParseCENCInitData(const uint8_t* aInitDa
     reader.Read(3); // skip flags.
 
     // SystemID
     const uint8_t* sid = reader.Read(sizeof(kSystemID));
     if (!sid) {
       // Insufficient bytes to read SystemID.
       return false;
     }
+    if (!memcmp(kPrimetimeID, sid, sizeof(kSystemID))) {
+      // Allow legacy Primetime key system PSSH boxes, which
+      // don't conform to common encryption format.
+      return true;
+    }
+
     if (memcmp(kSystemID, sid, sizeof(kSystemID))) {
       // Ignore pssh boxes with wrong system ID.
       reader.Seek(std::max<size_t>(reader.Offset(), end));
       continue;
     }
 
     if (!reader.CanRead32()) {
       return false;
--- a/media/psshparser/gtest/TestPsshParser.cpp
+++ b/media/psshparser/gtest/TestPsshParser.cpp
@@ -108,16 +108,25 @@ const uint8_t g2xGoogleWPTCencInitData[]
   0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02,  // Common SystemID
   0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B,
   0x00, 0x00, 0x00, 0x01,                          // key count
   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,  // key
   0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
   0x00, 0x00, 0x00, 0x00                           // datasize
 };
 
+const uint8_t gPrimetimePSSH[] = {
+  0x00, 0x00, 0x00, 0x00,                          // size = 0
+  0x70, 0x73, 0x73, 0x68,                          // 'pssh'
+  0x01,                                            // version = 1
+  0x00, 0x00, 0x00,                                // flags
+  0xf2, 0x39, 0xe7, 0x69, 0xef, 0xa3, 0x48, 0x50,  // Primetime system Id
+  0x9c, 0x16, 0xa9, 0x03, 0xc6, 0x93, 0x2e, 0xfb
+};
+
 TEST(PsshParser, ParseCencInitData) {
   std::vector<std::vector<uint8_t>> keyIds;
   bool rv;
 
   rv = ParseCENCInitData(gGoogleWPTCencInitData, MOZ_ARRAY_LENGTH(gGoogleWPTCencInitData), keyIds);
   EXPECT_TRUE(rv);
   EXPECT_EQ(1u, keyIds.size());
   EXPECT_EQ(16u, keyIds[0].size());
@@ -148,9 +157,13 @@ TEST(PsshParser, ParseCencInitData) {
 
   rv = ParseCENCInitData(g2xGoogleWPTCencInitData, MOZ_ARRAY_LENGTH(g2xGoogleWPTCencInitData), keyIds);
   EXPECT_TRUE(rv);
   EXPECT_EQ(2u, keyIds.size());
   EXPECT_EQ(16u, keyIds[0].size());
   EXPECT_EQ(16u, keyIds[1].size());
   EXPECT_EQ(0, memcmp(&keyIds[0].front(), &g2xGoogleWPTCencInitData[32], 16));
   EXPECT_EQ(0, memcmp(&keyIds[1].front(), &g2xGoogleWPTCencInitData[84], 16));
+
+  rv = ParseCENCInitData(gPrimetimePSSH, MOZ_ARRAY_LENGTH(gPrimetimePSSH), keyIds);
+  EXPECT_TRUE(rv);
+  EXPECT_EQ(0u, keyIds.size());
 }