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 }