1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/cdm/cenc_utils.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <limits>
11
12 #include "base/check.h"
13 #include "base/stl_util.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace media {
17
18 const uint8_t kKey1Data[] = {
19 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03,
20 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03
21 };
22 const uint8_t kKey2Data[] = {
23 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04,
24 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04,
25 };
26 const uint8_t kKey3Data[] = {
27 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x05,
28 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x05,
29 };
30 const uint8_t kKey4Data[] = {
31 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x06,
32 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x06,
33 };
34 const uint8_t kCommonSystemSystemId[] = {
35 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02,
36 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B
37 };
38
39 class CencUtilsTest : public testing::Test {
40 public:
CencUtilsTest()41 CencUtilsTest()
42 : key1_(kKey1Data, kKey1Data + base::size(kKey1Data)),
43 key2_(kKey2Data, kKey2Data + base::size(kKey2Data)),
44 key3_(kKey3Data, kKey3Data + base::size(kKey3Data)),
45 key4_(kKey4Data, kKey4Data + base::size(kKey4Data)),
46 common_system_system_id_(
47 kCommonSystemSystemId,
48 kCommonSystemSystemId + base::size(kCommonSystemSystemId)) {}
49
50 protected:
51 // Initialize the start of the 'pssh' box (up to key_count)
InitializePSSHBox(std::vector<uint8_t> * box,uint8_t size,uint8_t version)52 void InitializePSSHBox(std::vector<uint8_t>* box,
53 uint8_t size,
54 uint8_t version) {
55 DCHECK(box->size() == 0);
56
57 box->reserve(size);
58 // Add size.
59 DCHECK(size < std::numeric_limits<uint8_t>::max());
60 box->push_back(0);
61 box->push_back(0);
62 box->push_back(0);
63 box->push_back(size);
64 // Add 'pssh'.
65 box->push_back('p');
66 box->push_back('s');
67 box->push_back('s');
68 box->push_back('h');
69 // Add version.
70 box->push_back(version);
71 // Add flags.
72 box->push_back(0);
73 box->push_back(0);
74 box->push_back(0);
75 // Add Common Encryption SystemID.
76 box->insert(box->end(), common_system_system_id_.begin(),
77 common_system_system_id_.end());
78 }
79
MakePSSHBox(uint8_t version)80 std::vector<uint8_t> MakePSSHBox(uint8_t version) {
81 std::vector<uint8_t> box;
82 uint8_t size = (version == 0) ? 32 : 36;
83 InitializePSSHBox(&box, size, version);
84 if (version > 0) {
85 // Add key_count (= 0).
86 box.push_back(0);
87 box.push_back(0);
88 box.push_back(0);
89 box.push_back(0);
90 }
91 // Add data_size (= 0).
92 box.push_back(0);
93 box.push_back(0);
94 box.push_back(0);
95 box.push_back(0);
96 return box;
97 }
98
MakePSSHBox(uint8_t version,const std::vector<uint8_t> & key1)99 std::vector<uint8_t> MakePSSHBox(uint8_t version,
100 const std::vector<uint8_t>& key1) {
101 DCHECK(version > 0);
102 DCHECK(key1.size() == 16);
103
104 std::vector<uint8_t> box;
105 uint8_t size = 52;
106 InitializePSSHBox(&box, size, version);
107
108 // Add key_count (= 1).
109 box.push_back(0);
110 box.push_back(0);
111 box.push_back(0);
112 box.push_back(1);
113
114 // Add key1.
115 for (size_t i = 0; i < key1.size(); ++i)
116 box.push_back(key1[i]);
117
118 // Add data_size (= 0).
119 box.push_back(0);
120 box.push_back(0);
121 box.push_back(0);
122 box.push_back(0);
123 return box;
124 }
125
MakePSSHBox(uint8_t version,const std::vector<uint8_t> & key1,const std::vector<uint8_t> & key2)126 std::vector<uint8_t> MakePSSHBox(uint8_t version,
127 const std::vector<uint8_t>& key1,
128 const std::vector<uint8_t>& key2) {
129 DCHECK(version > 0);
130 DCHECK(key1.size() == 16);
131 DCHECK(key2.size() == 16);
132
133 std::vector<uint8_t> box;
134 uint8_t size = 68;
135 InitializePSSHBox(&box, size, version);
136
137 // Add key_count (= 2).
138 box.push_back(0);
139 box.push_back(0);
140 box.push_back(0);
141 box.push_back(2);
142
143 // Add key1.
144 for (size_t i = 0; i < key1.size(); ++i)
145 box.push_back(key1[i]);
146
147 // Add key2.
148 for (size_t i = 0; i < key2.size(); ++i)
149 box.push_back(key2[i]);
150
151 // Add data_size (= 0).
152 box.push_back(0);
153 box.push_back(0);
154 box.push_back(0);
155 box.push_back(0);
156 return box;
157 }
158
AppendData(std::vector<uint8_t> & pssh_box,const std::vector<uint8_t> & data)159 void AppendData(std::vector<uint8_t>& pssh_box,
160 const std::vector<uint8_t>& data) {
161 // This assumes that |pssh_box| has been created using the routines above,
162 // and simply appends the data to the end of it. It updates the box size
163 // and sets the data size.
164 DCHECK(data.size() < 100);
165 pssh_box[3] += static_cast<uint8_t>(data.size());
166 pssh_box.pop_back();
167 pssh_box.push_back(static_cast<uint8_t>(data.size()));
168 pssh_box.insert(pssh_box.end(), data.begin(), data.end());
169 }
170
Key1()171 const std::vector<uint8_t>& Key1() { return key1_; }
Key2()172 const std::vector<uint8_t>& Key2() { return key2_; }
Key3()173 const std::vector<uint8_t>& Key3() { return key3_; }
Key4()174 const std::vector<uint8_t>& Key4() { return key4_; }
CommonSystemSystemId()175 const std::vector<uint8_t>& CommonSystemSystemId() {
176 return common_system_system_id_;
177 }
178
179 private:
180 std::vector<uint8_t> key1_;
181 std::vector<uint8_t> key2_;
182 std::vector<uint8_t> key3_;
183 std::vector<uint8_t> key4_;
184 std::vector<uint8_t> common_system_system_id_;
185 };
186
TEST_F(CencUtilsTest,EmptyPSSH)187 TEST_F(CencUtilsTest, EmptyPSSH) {
188 KeyIdList key_ids;
189 EXPECT_TRUE(ValidatePsshInput(std::vector<uint8_t>()));
190 EXPECT_FALSE(GetKeyIdsForCommonSystemId(std::vector<uint8_t>(), &key_ids));
191 }
192
TEST_F(CencUtilsTest,PSSHVersion0)193 TEST_F(CencUtilsTest, PSSHVersion0) {
194 std::vector<uint8_t> box = MakePSSHBox(0);
195 KeyIdList key_ids;
196 EXPECT_TRUE(ValidatePsshInput(box));
197 EXPECT_FALSE(GetKeyIdsForCommonSystemId(box, &key_ids));
198 }
199
TEST_F(CencUtilsTest,PSSHVersion1WithNoKeys)200 TEST_F(CencUtilsTest, PSSHVersion1WithNoKeys) {
201 std::vector<uint8_t> box = MakePSSHBox(1);
202 KeyIdList key_ids;
203 EXPECT_TRUE(ValidatePsshInput(box));
204 EXPECT_FALSE(GetKeyIdsForCommonSystemId(box, &key_ids));
205 }
206
TEST_F(CencUtilsTest,PSSHVersion1WithOneKey)207 TEST_F(CencUtilsTest, PSSHVersion1WithOneKey) {
208 std::vector<uint8_t> box = MakePSSHBox(1, Key1());
209 KeyIdList key_ids;
210 EXPECT_TRUE(ValidatePsshInput(box));
211 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box, &key_ids));
212 EXPECT_EQ(1u, key_ids.size());
213 EXPECT_EQ(key_ids[0], Key1());
214 }
215
TEST_F(CencUtilsTest,PSSHVersion1WithTwoKeys)216 TEST_F(CencUtilsTest, PSSHVersion1WithTwoKeys) {
217 std::vector<uint8_t> box = MakePSSHBox(1, Key1(), Key2());
218 KeyIdList key_ids;
219 EXPECT_TRUE(ValidatePsshInput(box));
220 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box, &key_ids));
221 EXPECT_EQ(2u, key_ids.size());
222 EXPECT_EQ(key_ids[0], Key1());
223 EXPECT_EQ(key_ids[1], Key2());
224 }
225
TEST_F(CencUtilsTest,PSSHVersion0Plus1)226 TEST_F(CencUtilsTest, PSSHVersion0Plus1) {
227 std::vector<uint8_t> box0 = MakePSSHBox(0);
228 std::vector<uint8_t> box1 = MakePSSHBox(1, Key1());
229
230 // Concatentate box1 onto end of box0.
231 box0.insert(box0.end(), box1.begin(), box1.end());
232 EXPECT_TRUE(ValidatePsshInput(box0));
233
234 // No key IDs returned as only the first 'pssh' box is processed.
235 KeyIdList key_ids;
236 EXPECT_FALSE(GetKeyIdsForCommonSystemId(box0, &key_ids));
237 }
238
TEST_F(CencUtilsTest,PSSHVersion1Plus0)239 TEST_F(CencUtilsTest, PSSHVersion1Plus0) {
240 std::vector<uint8_t> box0 = MakePSSHBox(0);
241 std::vector<uint8_t> box1 = MakePSSHBox(1, Key1());
242
243 // Concatentate box0 onto end of box1.
244 box1.insert(box1.end(), box0.begin(), box0.end());
245
246 KeyIdList key_ids;
247 EXPECT_TRUE(ValidatePsshInput(box1));
248 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box1, &key_ids));
249 EXPECT_EQ(1u, key_ids.size());
250 EXPECT_EQ(key_ids[0], Key1());
251 }
252
TEST_F(CencUtilsTest,MultiplePSSHVersion1)253 TEST_F(CencUtilsTest, MultiplePSSHVersion1) {
254 std::vector<uint8_t> box = MakePSSHBox(1, Key1(), Key2());
255 std::vector<uint8_t> box1 = MakePSSHBox(1, Key3());
256 std::vector<uint8_t> box2 = MakePSSHBox(1, Key4());
257
258 // Concatentate box1 and box2 onto end of box.
259 box.insert(box.end(), box1.begin(), box1.end());
260 box.insert(box.end(), box2.begin(), box2.end());
261
262 KeyIdList key_ids;
263 EXPECT_TRUE(ValidatePsshInput(box));
264 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box, &key_ids));
265 EXPECT_EQ(2u, key_ids.size());
266 EXPECT_EQ(key_ids[0], Key1());
267 EXPECT_EQ(key_ids[1], Key2());
268 }
269
TEST_F(CencUtilsTest,PsshBoxSmallerThanSize)270 TEST_F(CencUtilsTest, PsshBoxSmallerThanSize) {
271 std::vector<uint8_t> box = MakePSSHBox(1, Key1(), Key2());
272 KeyIdList key_ids;
273
274 // Tries every buffer size less than the indicated 'pssh' box size.
275 for (size_t i = 1; i < box.size(); ++i) {
276 // Truncate the box to be less than the specified box size.
277 std::vector<uint8_t> truncated(&box[0], &box[0] + i);
278 EXPECT_FALSE(ValidatePsshInput(truncated)) << "Failed for length " << i;
279 EXPECT_FALSE(GetKeyIdsForCommonSystemId(truncated, &key_ids));
280 }
281 }
282
TEST_F(CencUtilsTest,PsshBoxLargerThanSize)283 TEST_F(CencUtilsTest, PsshBoxLargerThanSize) {
284 std::vector<uint8_t> box = MakePSSHBox(1, Key1(), Key2());
285 KeyIdList key_ids;
286
287 // Add 20 additional bytes to |box|.
288 size_t original_size = box.size();
289 for (size_t i = 0; i < 20; ++i)
290 box.push_back(static_cast<uint8_t>(i));
291
292 // Tries every size greater than |original_size|.
293 for (size_t i = original_size + 1; i < box.size(); ++i) {
294 // Modify size of box passed to be less than current size.
295 std::vector<uint8_t> truncated(&box[0], &box[0] + i);
296 EXPECT_FALSE(ValidatePsshInput(truncated)) << "Failed for length " << i;
297 EXPECT_FALSE(GetKeyIdsForCommonSystemId(truncated, &key_ids));
298 }
299 }
300
TEST_F(CencUtilsTest,UnrecognizedSystemID)301 TEST_F(CencUtilsTest, UnrecognizedSystemID) {
302 std::vector<uint8_t> box = MakePSSHBox(1, Key1(), Key2());
303
304 // Modify the System ID.
305 ++box[20];
306
307 KeyIdList key_ids;
308 EXPECT_FALSE(GetKeyIdsForCommonSystemId(box, &key_ids));
309 }
310
TEST_F(CencUtilsTest,InvalidFlags)311 TEST_F(CencUtilsTest, InvalidFlags) {
312 std::vector<uint8_t> box = MakePSSHBox(1, Key1(), Key2());
313
314 // Modify flags.
315 box[10] = 3;
316
317 KeyIdList key_ids;
318 EXPECT_FALSE(GetKeyIdsForCommonSystemId(box, &key_ids));
319 }
320
TEST_F(CencUtilsTest,LongSize)321 TEST_F(CencUtilsTest, LongSize) {
322 const uint8_t data[] = {
323 0x00, 0x00, 0x00, 0x01, // size = 1
324 0x70, 0x73, 0x73, 0x68, // 'pssh'
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, // longsize
326 0x01, // version
327 0x00, 0x00, 0x00, // flags
328 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // SystemID
329 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B,
330 0x00, 0x00, 0x00, 0x02, // key count
331 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03, // key1
332 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03,
333 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04, // key2
334 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04,
335 0x00, 0x00, 0x00, 0x00 // datasize
336 };
337
338 KeyIdList key_ids;
339 EXPECT_TRUE(
340 ValidatePsshInput(std::vector<uint8_t>(data, data + base::size(data))));
341 EXPECT_TRUE(GetKeyIdsForCommonSystemId(
342 std::vector<uint8_t>(data, data + base::size(data)), &key_ids));
343 EXPECT_EQ(2u, key_ids.size());
344 }
345
TEST_F(CencUtilsTest,SizeIsZero)346 TEST_F(CencUtilsTest, SizeIsZero) {
347 const uint8_t data[] = {
348 0x00, 0x00, 0x00, 0x00, // size = 0
349 0x70, 0x73, 0x73, 0x68, // 'pssh'
350 0x01, // version
351 0x00, 0x00, 0x00, // flags
352 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // SystemID
353 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B,
354 0x00, 0x00, 0x00, 0x02, // key count
355 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03, // key1
356 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03,
357 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04, // key2
358 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04,
359 0x00, 0x00, 0x00, 0x00 // datasize
360 };
361
362 KeyIdList key_ids;
363 EXPECT_TRUE(
364 ValidatePsshInput(std::vector<uint8_t>(data, data + base::size(data))));
365 EXPECT_TRUE(GetKeyIdsForCommonSystemId(
366 std::vector<uint8_t>(data, data + base::size(data)), &key_ids));
367 EXPECT_EQ(2u, key_ids.size());
368 }
369
TEST_F(CencUtilsTest,HugeSize)370 TEST_F(CencUtilsTest, HugeSize) {
371 const uint8_t data[] = {
372 0x00, 0x00, 0x00, 0x01, // size = 1
373 0x70, 0x73, 0x73, 0x68, // 'pssh'
374 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // longsize = big
375 0x01, // version
376 0x00, 0x00, 0x00, // flags
377 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // SystemID
378 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B,
379 0x00, 0x00, 0x00, 0x02, // key count
380 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03, // key1
381 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03,
382 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04, // key2
383 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04,
384 0x00, 0x00, 0x00, 0x00 // datasize
385 };
386
387 KeyIdList key_ids;
388 // These calls fail as the box size is huge (0xffffffffffffffff) and there
389 // is not enough bytes in |data|.
390 EXPECT_FALSE(
391 ValidatePsshInput(std::vector<uint8_t>(data, data + base::size(data))));
392 EXPECT_FALSE(GetKeyIdsForCommonSystemId(
393 std::vector<uint8_t>(data, data + base::size(data)), &key_ids));
394 }
395
TEST_F(CencUtilsTest,GetPsshData_Version0)396 TEST_F(CencUtilsTest, GetPsshData_Version0) {
397 const uint8_t data_bytes[] = {0x01, 0x02, 0x03, 0x04};
398 std::vector<uint8_t> pssh_data;
399
400 std::vector<uint8_t> box = MakePSSHBox(0);
401 EXPECT_TRUE(GetPsshData(box, CommonSystemSystemId(), &pssh_data));
402 EXPECT_EQ(0u, pssh_data.size());
403
404 std::vector<uint8_t> data(data_bytes, data_bytes + base::size(data_bytes));
405 AppendData(box, data);
406 EXPECT_TRUE(GetPsshData(box, CommonSystemSystemId(), &pssh_data));
407 EXPECT_EQ(data, pssh_data);
408 }
409
TEST_F(CencUtilsTest,GetPsshData_Version1NoKeys)410 TEST_F(CencUtilsTest, GetPsshData_Version1NoKeys) {
411 const uint8_t data_bytes[] = {0x05, 0x06, 0x07, 0x08};
412 std::vector<uint8_t> pssh_data;
413
414 std::vector<uint8_t> box = MakePSSHBox(1);
415 EXPECT_TRUE(GetPsshData(box, CommonSystemSystemId(), &pssh_data));
416 EXPECT_EQ(0u, pssh_data.size());
417
418 std::vector<uint8_t> data(data_bytes, data_bytes + base::size(data_bytes));
419 AppendData(box, data);
420 EXPECT_TRUE(GetPsshData(box, CommonSystemSystemId(), &pssh_data));
421 EXPECT_EQ(data, pssh_data);
422 }
423
TEST_F(CencUtilsTest,GetPsshData_Version1WithKeys)424 TEST_F(CencUtilsTest, GetPsshData_Version1WithKeys) {
425 const uint8_t data_bytes[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
426 std::vector<uint8_t> pssh_data;
427
428 std::vector<uint8_t> box = MakePSSHBox(1, Key1());
429 EXPECT_TRUE(GetPsshData(box, CommonSystemSystemId(), &pssh_data));
430 EXPECT_EQ(0u, pssh_data.size());
431
432 std::vector<uint8_t> data(data_bytes, data_bytes + base::size(data_bytes));
433 AppendData(box, data);
434 EXPECT_TRUE(GetPsshData(box, CommonSystemSystemId(), &pssh_data));
435 EXPECT_EQ(data, pssh_data);
436 }
437
TEST_F(CencUtilsTest,GetPsshData_Version2)438 TEST_F(CencUtilsTest, GetPsshData_Version2) {
439 std::vector<uint8_t> pssh_data;
440
441 std::vector<uint8_t> box = MakePSSHBox(1, Key1());
442 EXPECT_TRUE(GetPsshData(box, CommonSystemSystemId(), &pssh_data));
443
444 // Change the version manually, since we don't know what v2 will contain.
445 box[8] = 2;
446 EXPECT_FALSE(GetPsshData(box, CommonSystemSystemId(), &pssh_data));
447 }
448
TEST_F(CencUtilsTest,GetPsshData_Version2ThenVersion1)449 TEST_F(CencUtilsTest, GetPsshData_Version2ThenVersion1) {
450 std::vector<uint8_t> pssh_data;
451
452 std::vector<uint8_t> box_v1 = MakePSSHBox(1, Key1());
453 std::vector<uint8_t> box_v2 = MakePSSHBox(2, Key2(), Key3());
454
455 // Concatentate the boxes together (v2 first).
456 std::vector<uint8_t> boxes;
457 boxes.insert(boxes.end(), box_v2.begin(), box_v2.end());
458 boxes.insert(boxes.end(), box_v1.begin(), box_v1.end());
459 EXPECT_TRUE(GetPsshData(boxes, CommonSystemSystemId(), &pssh_data));
460
461 // GetKeyIdsForCommonSystemId() should return the single key from the v1
462 // 'pssh' box.
463 KeyIdList key_ids;
464 EXPECT_TRUE(GetKeyIdsForCommonSystemId(boxes, &key_ids));
465 EXPECT_EQ(1u, key_ids.size());
466 EXPECT_EQ(key_ids[0], Key1());
467 }
468
TEST_F(CencUtilsTest,GetPsshData_Version1ThenVersion2)469 TEST_F(CencUtilsTest, GetPsshData_Version1ThenVersion2) {
470 std::vector<uint8_t> pssh_data;
471
472 std::vector<uint8_t> box_v1 = MakePSSHBox(1, Key3());
473 std::vector<uint8_t> box_v2 = MakePSSHBox(2, Key4());
474
475 // Concatentate the boxes together (v1 first).
476 std::vector<uint8_t> boxes;
477 boxes.insert(boxes.end(), box_v1.begin(), box_v1.end());
478 boxes.insert(boxes.end(), box_v2.begin(), box_v2.end());
479 EXPECT_TRUE(GetPsshData(boxes, CommonSystemSystemId(), &pssh_data));
480
481 // GetKeyIdsForCommonSystemId() should return the single key from the v1
482 // 'pssh' box.
483 KeyIdList key_ids;
484 EXPECT_TRUE(GetKeyIdsForCommonSystemId(boxes, &key_ids));
485 EXPECT_EQ(1u, key_ids.size());
486 EXPECT_EQ(key_ids[0], Key3());
487 }
488
TEST_F(CencUtilsTest,GetPsshData_DifferentSystemID)489 TEST_F(CencUtilsTest, GetPsshData_DifferentSystemID) {
490 std::vector<uint8_t> unknown_system_id(kKey1Data,
491 kKey1Data + base::size(kKey1Data));
492 std::vector<uint8_t> pssh_data;
493
494 std::vector<uint8_t> box = MakePSSHBox(1, Key1());
495 EXPECT_TRUE(GetPsshData(box, CommonSystemSystemId(), &pssh_data));
496 EXPECT_FALSE(GetPsshData(box, unknown_system_id, &pssh_data));
497 }
498
TEST_F(CencUtilsTest,GetPsshData_MissingData)499 TEST_F(CencUtilsTest, GetPsshData_MissingData) {
500 const uint8_t data_bytes[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
501 std::vector<uint8_t> pssh_data;
502
503 std::vector<uint8_t> box = MakePSSHBox(1, Key1());
504 std::vector<uint8_t> data(data_bytes, data_bytes + base::size(data_bytes));
505 AppendData(box, data);
506 EXPECT_TRUE(GetPsshData(box, CommonSystemSystemId(), &pssh_data));
507
508 // Remove some data from the end, so now the size is incorrect.
509 box.pop_back();
510 box.pop_back();
511 EXPECT_FALSE(GetPsshData(box, CommonSystemSystemId(), &pssh_data));
512 }
513
TEST_F(CencUtilsTest,GetPsshData_MultiplePssh)514 TEST_F(CencUtilsTest, GetPsshData_MultiplePssh) {
515 const uint8_t data1_bytes[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
516 const uint8_t data2_bytes[] = {0xa1, 0xa2, 0xa3, 0xa4};
517 std::vector<uint8_t> pssh_data;
518
519 std::vector<uint8_t> box1 = MakePSSHBox(1, Key1());
520 std::vector<uint8_t> data1(data1_bytes,
521 data1_bytes + base::size(data1_bytes));
522 AppendData(box1, data1);
523
524 std::vector<uint8_t> box2 = MakePSSHBox(0);
525 std::vector<uint8_t> data2(data2_bytes,
526 data2_bytes + base::size(data2_bytes));
527 AppendData(box2, data2);
528
529 box1.insert(box1.end(), box2.begin(), box2.end());
530 EXPECT_TRUE(GetPsshData(box1, CommonSystemSystemId(), &pssh_data));
531 EXPECT_EQ(data1, pssh_data);
532 EXPECT_NE(data2, pssh_data);
533 }
534
TEST_F(CencUtilsTest,NonPsshData)535 TEST_F(CencUtilsTest, NonPsshData) {
536 // Create a non-'pssh' box.
537 const uint8_t data[] = {
538 0x00, 0x00, 0x00, 0x08, // size = 8
539 'p', 's', 's', 'g'
540 };
541 std::vector<uint8_t> non_pssh_box(data, data + base::size(data));
542 EXPECT_FALSE(ValidatePsshInput(non_pssh_box));
543
544 // Make a valid 'pssh' box.
545 std::vector<uint8_t> pssh_box = MakePSSHBox(1, Key1());
546 EXPECT_TRUE(ValidatePsshInput(pssh_box));
547
548 // Concatentate the boxes together (|pssh_box| first).
549 std::vector<uint8_t> boxes;
550 boxes.insert(boxes.end(), pssh_box.begin(), pssh_box.end());
551 boxes.insert(boxes.end(), non_pssh_box.begin(), non_pssh_box.end());
552 EXPECT_FALSE(ValidatePsshInput(boxes));
553
554 // Repeat with |non_pssh_box| first.
555 boxes.clear();
556 boxes.insert(boxes.end(), non_pssh_box.begin(), non_pssh_box.end());
557 boxes.insert(boxes.end(), pssh_box.begin(), pssh_box.end());
558 EXPECT_FALSE(ValidatePsshInput(boxes));
559 }
560
561 } // namespace media
562