tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestPsshParser.cpp (7553B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "gtest/gtest.h"
      8 #include <stdint.h>
      9 #include <vector>
     10 
     11 #include "psshparser/PsshParser.h"
     12 
     13 using namespace std;
     14 
     15 // This is the CENC initData from Google's web-platform tests.
     16 // https://github.com/w3c/web-platform-tests/blob/master/encrypted-media/Google/encrypted-media-utils.js#L50
     17 const uint8_t gGoogleWPTCencInitData[] = {
     18    // clang-format off
     19  0x00, 0x00, 0x00, 0x00,                          // size = 0
     20  0x70, 0x73, 0x73, 0x68,                          // 'pssh'
     21  0x01,                                            // version = 1
     22  0x00, 0x00, 0x00,                                // flags
     23  0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02,  // Common SystemID
     24  0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B,
     25  0x00, 0x00, 0x00, 0x01,                          // key count
     26  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,  // key
     27  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
     28  0x00, 0x00, 0x00, 0x00                           // datasize
     29    // clang-format on
     30 };
     31 
     32 // Example CENC initData from the EME spec format registry:
     33 // https://w3c.github.io/encrypted-media/format-registry/initdata/cenc.html
     34 const uint8_t gW3SpecExampleCencInitData[] = {
     35    // clang-format off
     36  0x00, 0x00, 0x00, 0x44, 0x70, 0x73, 0x73, 0x68, // BMFF box header (68 bytes, 'pssh')
     37  0x01, 0x00, 0x00, 0x00,                         // Full box header (version = 1, flags = 0)
     38  0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, // SystemID
     39  0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b,
     40  0x00, 0x00, 0x00, 0x02,                         // KID_count (2)
     41  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // First KID ("0123456789012345")
     42  0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
     43  0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // Second KID ("ABCDEFGHIJKLMNOP")
     44  0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
     45  0x00, 0x00, 0x00, 0x00                         // Size of Data (0)
     46    // clang-format on
     47 };
     48 
     49 // Invalid box size, would overflow if used.
     50 const uint8_t gOverflowBoxSize[] = {
     51    0xff, 0xff, 0xff, 0xff,  // size = UINT32_MAX
     52 };
     53 
     54 // Valid box size, but key count too large.
     55 const uint8_t gTooLargeKeyCountInitData[] = {
     56    // clang-format off
     57  0x00, 0x00, 0x00, 0x34,                          // size = too big a number
     58  0x70, 0x73, 0x73, 0x68,                          // 'pssh'
     59  0x01,                                            // version = 1
     60  0xff, 0xff, 0xff,                                // flags
     61  0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02,  // Common SystemID
     62  0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B,
     63  0xff, 0xff, 0xff, 0xff,                          // key count = UINT32_MAX
     64  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // key
     65  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     66  0xff, 0xff, 0xff, 0xff                           // datasize
     67    // clang-format on
     68 };
     69 
     70 // Non common SystemID PSSH.
     71 // No keys Ids can be extracted, but don't consider the box invalid.
     72 const uint8_t gNonCencInitData[] = {
     73    // clang-format off
     74  0x00, 0x00, 0x00, 0x5c,                          // size = 92
     75  0x70, 0x73, 0x73, 0x68,                          // 'pssh'
     76  0x01,                                            // version = 1
     77  0x00, 0x00, 0x00,                                // flags
     78  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // Invalid SystemID
     79  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     80  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // Some data to pad out the box.
     81  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     82  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     83  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     84  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     85  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     86  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     87  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     88    // clang-format on
     89 };
     90 
     91 const uint8_t gNonPSSHBoxZeroSize[] = {
     92    // clang-format off
     93  0x00, 0x00, 0x00, 0x00,                          // size = 0
     94  0xff, 0xff, 0xff, 0xff,                          // something other than 'pssh'
     95    // clang-format on
     96 };
     97 
     98 // Two lots of the google init data. To ensure we handle
     99 // multiple boxes with size 0.
    100 const uint8_t g2xGoogleWPTCencInitData[] = {
    101    // clang-format off
    102  0x00, 0x00, 0x00, 0x00,                          // size = 0
    103  0x70, 0x73, 0x73, 0x68,                          // 'pssh'
    104  0x01,                                            // version = 1
    105  0x00, 0x00, 0x00,                                // flags
    106  0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02,  // Common SystemID
    107  0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B,
    108  0x00, 0x00, 0x00, 0x01,                          // key count
    109  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,  // key
    110  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    111  0x00, 0x00, 0x00, 0x00,                          // datasize
    112 
    113  0x00, 0x00, 0x00, 0x00,                          // size = 0
    114  0x70, 0x73, 0x73, 0x68,                          // 'pssh'
    115  0x01,                                            // version = 1
    116  0x00, 0x00, 0x00,                                // flags
    117  0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02,  // Common SystemID
    118  0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B,
    119  0x00, 0x00, 0x00, 0x01,                          // key count
    120  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,  // key
    121  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    122  0x00, 0x00, 0x00, 0x00                           // datasize
    123    // clang-format on
    124 };
    125 
    126 TEST(PsshParser, ParseCencInitData)
    127 {
    128  std::vector<std::vector<uint8_t>> keyIds;
    129  bool rv;
    130 
    131  rv = ParseCENCInitData(gGoogleWPTCencInitData,
    132                         std::size(gGoogleWPTCencInitData), keyIds);
    133  EXPECT_TRUE(rv);
    134  EXPECT_EQ(1u, keyIds.size());
    135  EXPECT_EQ(16u, keyIds[0].size());
    136  EXPECT_EQ(0, memcmp(&keyIds[0].front(), &gGoogleWPTCencInitData[32], 16));
    137 
    138  rv = ParseCENCInitData(gW3SpecExampleCencInitData,
    139                         std::size(gW3SpecExampleCencInitData), keyIds);
    140  EXPECT_TRUE(rv);
    141  EXPECT_EQ(2u, keyIds.size());
    142  EXPECT_EQ(16u, keyIds[0].size());
    143  EXPECT_EQ(0, memcmp(&keyIds[0].front(), &gW3SpecExampleCencInitData[32], 16));
    144  EXPECT_EQ(0, memcmp(&keyIds[1].front(), &gW3SpecExampleCencInitData[48], 16));
    145 
    146  rv = ParseCENCInitData(gOverflowBoxSize, std::size(gOverflowBoxSize), keyIds);
    147  EXPECT_FALSE(rv);
    148  EXPECT_EQ(0u, keyIds.size());
    149 
    150  rv = ParseCENCInitData(gTooLargeKeyCountInitData,
    151                         std::size(gTooLargeKeyCountInitData), keyIds);
    152  EXPECT_FALSE(rv);
    153  EXPECT_EQ(0u, keyIds.size());
    154 
    155  rv = ParseCENCInitData(gNonCencInitData, std::size(gNonCencInitData), keyIds);
    156  EXPECT_TRUE(rv);
    157  EXPECT_EQ(0u, keyIds.size());
    158 
    159  rv = ParseCENCInitData(gNonPSSHBoxZeroSize, std::size(gNonPSSHBoxZeroSize),
    160                         keyIds);
    161  EXPECT_FALSE(rv);
    162  EXPECT_EQ(0u, keyIds.size());
    163 
    164  rv = ParseCENCInitData(g2xGoogleWPTCencInitData,
    165                         std::size(g2xGoogleWPTCencInitData), keyIds);
    166  EXPECT_TRUE(rv);
    167  EXPECT_EQ(2u, keyIds.size());
    168  EXPECT_EQ(16u, keyIds[0].size());
    169  EXPECT_EQ(16u, keyIds[1].size());
    170  EXPECT_EQ(0, memcmp(&keyIds[0].front(), &g2xGoogleWPTCencInitData[32], 16));
    171  EXPECT_EQ(0, memcmp(&keyIds[1].front(), &g2xGoogleWPTCencInitData[84], 16));
    172 }