Implement MoveFileLocal (with creating a snapshot).
[chromium-blink-merge.git] / media / cdm / json_web_key_unittest.cc
blob0cb251c639ec28e0df257dbff087b2f74be5fef4
1 // Copyright 2013 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.
5 #include "media/cdm/json_web_key.h"
7 #include "base/base64.h"
8 #include "base/logging.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 namespace media {
13 class JSONWebKeyTest : public testing::Test {
14 public:
15 JSONWebKeyTest() {}
17 protected:
18 void ExtractJWKKeysAndExpect(const std::string& jwk,
19 bool expected_result,
20 size_t expected_number_of_keys) {
21 DCHECK(!jwk.empty());
22 KeyIdAndKeyPairs keys;
23 MediaKeys::SessionType session_type;
24 EXPECT_EQ(expected_result,
25 ExtractKeysFromJWKSet(jwk, &keys, &session_type));
26 EXPECT_EQ(expected_number_of_keys, keys.size());
29 void ExtractSessionTypeAndExpect(const std::string& jwk,
30 bool expected_result,
31 MediaKeys::SessionType expected_type) {
32 DCHECK(!jwk.empty());
33 KeyIdAndKeyPairs keys;
34 MediaKeys::SessionType session_type;
35 EXPECT_EQ(expected_result,
36 ExtractKeysFromJWKSet(jwk, &keys, &session_type));
37 if (expected_result) {
38 // Only check if successful.
39 EXPECT_EQ(expected_type, session_type);
43 void CreateLicenseAndExpect(const uint8* key_id,
44 int key_id_length,
45 MediaKeys::SessionType session_type,
46 const std::string& expected_result) {
47 std::vector<uint8> result;
48 KeyIdList key_ids;
49 key_ids.push_back(std::vector<uint8>(key_id, key_id + key_id_length));
50 CreateLicenseRequest(key_ids, session_type, &result);
51 std::string s(result.begin(), result.end());
52 EXPECT_EQ(expected_result, s);
55 void ExtractKeyFromLicenseAndExpect(const std::string& license,
56 bool expected_result,
57 const uint8* expected_key,
58 int expected_key_length) {
59 std::vector<uint8> license_vector(license.begin(), license.end());
60 std::vector<uint8> key;
61 EXPECT_EQ(expected_result,
62 ExtractFirstKeyIdFromLicenseRequest(license_vector, &key));
63 if (expected_result)
64 VerifyKeyId(key, expected_key, expected_key_length);
67 void VerifyKeyId(std::vector<uint8> key,
68 const uint8* expected_key,
69 int expected_key_length) {
70 std::vector<uint8> key_result(expected_key,
71 expected_key + expected_key_length);
72 EXPECT_EQ(key_result, key);
76 TEST_F(JSONWebKeyTest, GenerateJWKSet) {
77 const uint8 data1[] = { 0x01, 0x02 };
78 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
79 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
80 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
82 EXPECT_EQ(
83 "{\"keys\":[{\"alg\":\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":"
84 "\"oct\"}]}",
85 GenerateJWKSet(data1, arraysize(data1), data1, arraysize(data1)));
86 EXPECT_EQ(
87 "{\"keys\":[{\"alg\":\"A128KW\",\"k\":\"AQIDBA\",\"kid\":\"AQIDBA\","
88 "\"kty\":\"oct\"}]}",
89 GenerateJWKSet(data2, arraysize(data2), data2, arraysize(data2)));
90 EXPECT_EQ(
91 "{\"keys\":[{\"alg\":\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQIDBA\",\"kty\":"
92 "\"oct\"}]}",
93 GenerateJWKSet(data1, arraysize(data1), data2, arraysize(data2)));
94 EXPECT_EQ(
95 "{\"keys\":[{\"alg\":\"A128KW\",\"k\":\"AQIDBA\",\"kid\":\"AQI\",\"kty\":"
96 "\"oct\"}]}",
97 GenerateJWKSet(data2, arraysize(data2), data1, arraysize(data1)));
98 EXPECT_EQ(
99 "{\"keys\":[{\"alg\":\"A128KW\",\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":"
100 "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":\"oct\"}]}",
101 GenerateJWKSet(data3, arraysize(data3), data3, arraysize(data3)));
104 TEST_F(JSONWebKeyTest, ExtractValidJWKKeys) {
105 // Try an empty 'keys' dictionary.
106 ExtractJWKKeysAndExpect("{ \"keys\": [] }", true, 0);
108 // Try a key list with one entry.
109 const std::string kJwksOneEntry =
111 " \"keys\": ["
112 " {"
113 " \"kty\": \"oct\","
114 " \"alg\": \"A128KW\","
115 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
116 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
117 " }"
118 " ]"
119 "}";
120 ExtractJWKKeysAndExpect(kJwksOneEntry, true, 1);
122 // Try a key list with multiple entries.
123 const std::string kJwksMultipleEntries =
125 " \"keys\": ["
126 " {"
127 " \"kty\": \"oct\","
128 " \"alg\": \"A128KW\","
129 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
130 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
131 " },"
132 " {"
133 " \"kty\": \"oct\","
134 " \"alg\": \"A128KW\","
135 " \"kid\": \"JCUmJygpKissLS4vMA\","
136 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4_QA\""
137 " }"
138 " ]"
139 "}";
140 ExtractJWKKeysAndExpect(kJwksMultipleEntries, true, 2);
142 // Try a key with no spaces and some \n plus additional fields.
143 const std::string kJwksNoSpaces =
144 "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\","
145 "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg"
146 "\",\"foo\":\"bar\"}]}\n\n";
147 ExtractJWKKeysAndExpect(kJwksNoSpaces, true, 1);
149 // Try a list with multiple keys with the same kid.
150 const std::string kJwksDuplicateKids =
152 " \"keys\": ["
153 " {"
154 " \"kty\": \"oct\","
155 " \"alg\": \"A128KW\","
156 " \"kid\": \"JCUmJygpKissLS4vMA\","
157 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
158 " },"
159 " {"
160 " \"kty\": \"oct\","
161 " \"alg\": \"A128KW\","
162 " \"kid\": \"JCUmJygpKissLS4vMA\","
163 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4_QA\""
164 " }"
165 " ]"
166 "}";
167 ExtractJWKKeysAndExpect(kJwksDuplicateKids, true, 2);
170 TEST_F(JSONWebKeyTest, ExtractInvalidJWKKeys) {
171 // Try a simple JWK key (i.e. not in a set)
172 const std::string kJwkSimple =
174 " \"kty\": \"oct\","
175 " \"alg\": \"A128KW\","
176 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
177 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
178 "}";
179 ExtractJWKKeysAndExpect(kJwkSimple, false, 0);
181 // Try some non-ASCII characters.
182 ExtractJWKKeysAndExpect(
183 "This is not ASCII due to \xff\xfe\xfd in it.", false, 0);
185 // Try some non-ASCII characters in an otherwise valid JWK.
186 const std::string kJwksInvalidCharacters =
187 "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\","
188 "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"\xff\xfe\xfd"
189 "\",\"foo\":\"bar\"}]}\n\n";
190 ExtractJWKKeysAndExpect(kJwksInvalidCharacters, false, 0);
192 // Try a badly formatted key. Assume that the JSON parser is fully tested,
193 // so we won't try a lot of combinations. However, need a test to ensure
194 // that the code doesn't crash if invalid JSON received.
195 ExtractJWKKeysAndExpect("This is not a JSON key.", false, 0);
197 // Try passing some valid JSON that is not a dictionary at the top level.
198 ExtractJWKKeysAndExpect("40", false, 0);
200 // Try an empty dictionary.
201 ExtractJWKKeysAndExpect("{ }", false, 0);
203 // Try with 'keys' not a dictionary.
204 ExtractJWKKeysAndExpect("{ \"keys\":\"1\" }", false, 0);
206 // Try with 'keys' a list of integers.
207 ExtractJWKKeysAndExpect("{ \"keys\": [ 1, 2, 3 ] }", false, 0);
209 // Try padding(=) at end of 'k' base64 string.
210 const std::string kJwksWithPaddedKey =
212 " \"keys\": ["
213 " {"
214 " \"kty\": \"oct\","
215 " \"alg\": \"A128KW\","
216 " \"kid\": \"AAECAw\","
217 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
218 " }"
219 " ]"
220 "}";
221 ExtractJWKKeysAndExpect(kJwksWithPaddedKey, false, 0);
223 // Try padding(=) at end of 'kid' base64 string.
224 const std::string kJwksWithPaddedKeyId =
226 " \"keys\": ["
227 " {"
228 " \"kty\": \"oct\","
229 " \"alg\": \"A128KW\","
230 " \"kid\": \"AAECAw==\","
231 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
232 " }"
233 " ]"
234 "}";
235 ExtractJWKKeysAndExpect(kJwksWithPaddedKeyId, false, 0);
237 // Try a key with invalid base64 encoding.
238 const std::string kJwksWithInvalidBase64 =
240 " \"keys\": ["
241 " {"
242 " \"kty\": \"oct\","
243 " \"alg\": \"A128KW\","
244 " \"kid\": \"!@#$%^&*()\","
245 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
246 " }"
247 " ]"
248 "}";
249 ExtractJWKKeysAndExpect(kJwksWithInvalidBase64, false, 0);
251 // Empty key id.
252 const std::string kJwksWithEmptyKeyId =
254 " \"keys\": ["
255 " {"
256 " \"kty\": \"oct\","
257 " \"alg\": \"A128KW\","
258 " \"kid\": \"\","
259 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
260 " }"
261 " ]"
262 "}";
263 ExtractJWKKeysAndExpect(kJwksWithEmptyKeyId, false, 0);
266 TEST_F(JSONWebKeyTest, KeyType) {
267 // Valid key type.
268 const std::string kJwksWithValidKeyType =
270 " \"keys\": ["
271 " {"
272 " \"kty\": \"oct\","
273 " \"alg\": \"A128KW\","
274 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
275 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
276 " }"
277 " ]"
278 "}";
279 ExtractJWKKeysAndExpect(kJwksWithValidKeyType, true, 1);
281 // Empty key type.
282 const std::string kJwksWithEmptyKeyType =
284 " \"keys\": ["
285 " {"
286 " \"kty\": \"\","
287 " \"alg\": \"A128KW\","
288 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
289 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
290 " }"
291 " ]"
292 "}";
293 ExtractJWKKeysAndExpect(kJwksWithEmptyKeyType, false, 0);
295 // Key type is case sensitive.
296 const std::string kJwksWithUppercaseKeyType =
298 " \"keys\": ["
299 " {"
300 " \"kty\": \"OCT\","
301 " \"alg\": \"A128KW\","
302 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
303 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
304 " }"
305 " ]"
306 "}";
307 ExtractJWKKeysAndExpect(kJwksWithUppercaseKeyType, false, 0);
309 // Wrong key type.
310 const std::string kJwksWithWrongKeyType =
312 " \"keys\": ["
313 " {"
314 " \"kty\": \"RSA\","
315 " \"alg\": \"A128KW\","
316 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
317 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
318 " }"
319 " ]"
320 "}";
321 ExtractJWKKeysAndExpect(kJwksWithWrongKeyType, false, 0);
324 TEST_F(JSONWebKeyTest, Alg) {
325 // Valid alg.
326 const std::string kJwksWithValidAlg =
328 " \"keys\": ["
329 " {"
330 " \"kty\": \"oct\","
331 " \"alg\": \"A128KW\","
332 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
333 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
334 " }"
335 " ]"
336 "}";
337 ExtractJWKKeysAndExpect(kJwksWithValidAlg, true, 1);
339 // Empty alg.
340 const std::string kJwksWithEmptyAlg =
342 " \"keys\": ["
343 " {"
344 " \"kty\": \"oct\","
345 " \"alg\": \"\","
346 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
347 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
348 " }"
349 " ]"
350 "}";
351 ExtractJWKKeysAndExpect(kJwksWithEmptyAlg, false, 0);
353 // Alg is case sensitive.
354 const std::string kJwksWithLowercaseAlg =
356 " \"keys\": ["
357 " {"
358 " \"kty\": \"oct\","
359 " \"alg\": \"a128kw\","
360 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
361 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
362 " }"
363 " ]"
364 "}";
365 ExtractJWKKeysAndExpect(kJwksWithLowercaseAlg, false, 0);
367 // Wrong alg.
368 const std::string kJwksWithWrongAlg =
370 " \"keys\": ["
371 " {"
372 " \"kty\": \"oct\","
373 " \"alg\": \"RS256\","
374 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
375 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
376 " }"
377 " ]"
378 "}";
379 ExtractJWKKeysAndExpect(kJwksWithWrongAlg, false, 0);
382 TEST_F(JSONWebKeyTest, SessionType) {
383 ExtractSessionTypeAndExpect(
384 "{\"keys\":[{\"alg\": "
385 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
386 true, MediaKeys::TEMPORARY_SESSION);
387 ExtractSessionTypeAndExpect(
388 "{\"keys\":[{\"alg\": "
389 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
390 "\"temporary\"}",
391 true, MediaKeys::TEMPORARY_SESSION);
392 ExtractSessionTypeAndExpect(
393 "{\"keys\":[{\"alg\": "
394 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
395 "\"persistent-license\"}",
396 true, MediaKeys::PERSISTENT_LICENSE_SESSION);
397 ExtractSessionTypeAndExpect(
398 "{\"keys\":[{\"alg\": "
399 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
400 "\"persistent-release-message\"}",
401 true, MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION);
402 ExtractSessionTypeAndExpect(
403 "{\"keys\":[{\"alg\": "
404 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
405 "\"unknown\"}",
406 false, MediaKeys::TEMPORARY_SESSION);
407 ExtractSessionTypeAndExpect(
408 "{\"keys\":[{\"alg\": "
409 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":3}",
410 false, MediaKeys::TEMPORARY_SESSION);
413 TEST_F(JSONWebKeyTest, CreateLicense) {
414 const uint8 data1[] = { 0x01, 0x02 };
415 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
416 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
417 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
419 CreateLicenseAndExpect(data1,
420 arraysize(data1),
421 MediaKeys::TEMPORARY_SESSION,
422 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}");
423 CreateLicenseAndExpect(
424 data1, arraysize(data1), MediaKeys::PERSISTENT_LICENSE_SESSION,
425 "{\"kids\":[\"AQI\"],\"type\":\"persistent-license\"}");
426 CreateLicenseAndExpect(
427 data1, arraysize(data1), MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION,
428 "{\"kids\":[\"AQI\"],\"type\":\"persistent-release-message\"}");
429 CreateLicenseAndExpect(data2,
430 arraysize(data2),
431 MediaKeys::TEMPORARY_SESSION,
432 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}");
433 CreateLicenseAndExpect(data3, arraysize(data3),
434 MediaKeys::PERSISTENT_LICENSE_SESSION,
435 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":"
436 "\"persistent-license\"}");
439 TEST_F(JSONWebKeyTest, ExtractLicense) {
440 const uint8 data1[] = { 0x01, 0x02 };
441 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
442 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
443 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
445 ExtractKeyFromLicenseAndExpect(
446 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}",
447 true,
448 data1,
449 arraysize(data1));
450 ExtractKeyFromLicenseAndExpect(
451 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}",
452 true,
453 data2,
454 arraysize(data2));
455 ExtractKeyFromLicenseAndExpect(
456 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":\"persistent\"}",
457 true,
458 data3,
459 arraysize(data3));
461 // Try some incorrect JSON.
462 ExtractKeyFromLicenseAndExpect("", false, NULL, 0);
463 ExtractKeyFromLicenseAndExpect("!@#$%^&*()", false, NULL, 0);
465 // Valid JSON, but not a dictionary.
466 ExtractKeyFromLicenseAndExpect("6", false, NULL, 0);
467 ExtractKeyFromLicenseAndExpect("[\"AQI\"]", false, NULL, 0);
469 // Dictionary, but missing expected tag.
470 ExtractKeyFromLicenseAndExpect("{\"kid\":[\"AQI\"]}", false, NULL, 0);
472 // Correct tag, but empty list.
473 ExtractKeyFromLicenseAndExpect("{\"kids\":[]}", false, NULL, 0);
475 // Correct tag, but list doesn't contain a string.
476 ExtractKeyFromLicenseAndExpect("{\"kids\":[[\"AQI\"]]}", false, NULL, 0);
478 // Correct tag, but invalid base64 encoding.
479 ExtractKeyFromLicenseAndExpect("{\"kids\":[\"!@#$%^&*()\"]}", false, NULL, 0);
482 TEST_F(JSONWebKeyTest, Base64UrlEncoding) {
483 const uint8 data1[] = { 0xfb, 0xfd, 0xfb, 0xfd, 0xfb, 0xfd, 0xfb };
485 // Verify that |data1| contains invalid base64url characters '+' and '/'
486 // and is padded with = when converted to base64.
487 std::string encoded_text;
488 base::Base64Encode(
489 std::string(reinterpret_cast<const char*>(&data1[0]), arraysize(data1)),
490 &encoded_text);
491 EXPECT_EQ(encoded_text, "+/37/fv9+w==");
492 EXPECT_NE(encoded_text.find('+'), std::string::npos);
493 EXPECT_NE(encoded_text.find('/'), std::string::npos);
494 EXPECT_NE(encoded_text.find('='), std::string::npos);
496 // base64url characters '-' and '_' not in base64 encoding.
497 EXPECT_EQ(encoded_text.find('-'), std::string::npos);
498 EXPECT_EQ(encoded_text.find('_'), std::string::npos);
500 CreateLicenseAndExpect(data1, arraysize(data1), MediaKeys::TEMPORARY_SESSION,
501 "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}");
503 ExtractKeyFromLicenseAndExpect(
504 "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}", true, data1,
505 arraysize(data1));
508 TEST_F(JSONWebKeyTest, MultipleKeys) {
509 const uint8 data1[] = { 0x01, 0x02 };
510 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
511 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
512 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
514 std::vector<uint8> result;
515 KeyIdList key_ids;
516 key_ids.push_back(std::vector<uint8>(data1, data1 + arraysize(data1)));
517 key_ids.push_back(std::vector<uint8>(data2, data2 + arraysize(data2)));
518 key_ids.push_back(std::vector<uint8>(data3, data3 + arraysize(data3)));
519 CreateLicenseRequest(key_ids, MediaKeys::TEMPORARY_SESSION, &result);
520 std::string s(result.begin(), result.end());
521 EXPECT_EQ(
522 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":"
523 "\"temporary\"}",
527 TEST_F(JSONWebKeyTest, ExtractKeyIds) {
528 const uint8 data1[] = { 0x01, 0x02 };
529 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
530 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
531 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
533 KeyIdList key_ids;
534 std::string error_message;
536 EXPECT_TRUE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"AQI\"]}", &key_ids,
537 &error_message));
538 EXPECT_EQ(1u, key_ids.size());
539 EXPECT_EQ(0u, error_message.length());
540 VerifyKeyId(key_ids[0], data1, arraysize(data1));
542 EXPECT_TRUE(ExtractKeyIdsFromKeyIdsInitData(
543 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"]}", &key_ids,
544 &error_message));
545 EXPECT_EQ(3u, key_ids.size());
546 EXPECT_EQ(0u, error_message.length());
547 VerifyKeyId(key_ids[0], data1, arraysize(data1));
548 VerifyKeyId(key_ids[1], data2, arraysize(data2));
549 VerifyKeyId(key_ids[2], data3, arraysize(data3));
551 // Expect failure when non-ascii.
552 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData(
553 "This is not ASCII due to \xff\xfe\x0a in it.", &key_ids,
554 &error_message));
555 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
556 EXPECT_EQ(error_message,
557 "Non ASCII: This is not ASCII due to \\u00FF\\u00FE\\n in it.");
559 // Expect failure when not JSON or not a dictionary.
560 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("This is invalid.", &key_ids,
561 &error_message));
562 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
563 EXPECT_EQ(error_message, "Not valid JSON: This is invalid.");
564 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("6", &key_ids, &error_message));
565 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
566 EXPECT_EQ(error_message, "Not valid JSON: 6");
567 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData(
568 "This is a very long string that is longer than 64 characters and is "
569 "invalid.",
570 &key_ids, &error_message));
571 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
572 EXPECT_EQ(error_message,
573 "Not valid JSON: This is a very long string that is longer than 64 "
574 "characters ...");
576 // Expect failure when "kids" not specified.
577 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"keys\":[\"AQI\"]}", &key_ids,
578 &error_message));
579 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
580 EXPECT_EQ(error_message, "Missing 'kids' parameter or not a list");
582 // Expect failure when invalid key_ids specified.
583 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[1]}", &key_ids,
584 &error_message));
585 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
586 EXPECT_EQ(error_message, "'kids'[0] is not string.");
587 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\": {\"id\":\"AQI\" }}",
588 &key_ids, &error_message));
589 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
590 EXPECT_EQ(error_message, "Missing 'kids' parameter or not a list");
592 // Expect failure when non-base64 key_ids specified.
593 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"AQI+\"]}",
594 &key_ids, &error_message));
595 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
596 EXPECT_EQ(error_message,
597 "'kids'[0] is not valid base64url encoded. Value: AQI+");
598 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"AQI\",\"AQI/\"]}",
599 &key_ids, &error_message));
600 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
601 EXPECT_EQ(error_message,
602 "'kids'[1] is not valid base64url encoded. Value: AQI/");
605 } // namespace media