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