Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / media / cdm / json_web_key_unittest.cc
blob82b3bb0827d402d9845267a4004728a527d4d13a
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("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
83 GenerateJWKSet(data1, arraysize(data1), data1, arraysize(data1)));
84 EXPECT_EQ(
85 "{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}",
86 GenerateJWKSet(data2, arraysize(data2), data2, arraysize(data2)));
87 EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}",
88 GenerateJWKSet(data1, arraysize(data1), data2, arraysize(data2)));
89 EXPECT_EQ("{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
90 GenerateJWKSet(data2, arraysize(data2), data1, arraysize(data1)));
91 EXPECT_EQ(
92 "{\"keys\":[{\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":"
93 "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":\"oct\"}]}",
94 GenerateJWKSet(data3, arraysize(data3), data3, arraysize(data3)));
97 TEST_F(JSONWebKeyTest, ExtractValidJWKKeys) {
98 // Try an empty 'keys' dictionary.
99 ExtractJWKKeysAndExpect("{ \"keys\": [] }", true, 0);
101 // Try a key list with one entry.
102 const std::string kJwksOneEntry =
104 " \"keys\": ["
105 " {"
106 " \"kty\": \"oct\","
107 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
108 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
109 " }"
110 " ]"
111 "}";
112 ExtractJWKKeysAndExpect(kJwksOneEntry, true, 1);
114 // Try a key list with multiple entries.
115 const std::string kJwksMultipleEntries =
117 " \"keys\": ["
118 " {"
119 " \"kty\": \"oct\","
120 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
121 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
122 " },"
123 " {"
124 " \"kty\": \"oct\","
125 " \"kid\": \"JCUmJygpKissLS4vMA\","
126 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4_QA\""
127 " }"
128 " ]"
129 "}";
130 ExtractJWKKeysAndExpect(kJwksMultipleEntries, true, 2);
132 // Try a key with no spaces and some \n plus additional fields.
133 const std::string kJwksNoSpaces =
134 "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\","
135 "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg"
136 "\",\"foo\":\"bar\"}]}\n\n";
137 ExtractJWKKeysAndExpect(kJwksNoSpaces, true, 1);
139 // Try a list with multiple keys with the same kid.
140 const std::string kJwksDuplicateKids =
142 " \"keys\": ["
143 " {"
144 " \"kty\": \"oct\","
145 " \"kid\": \"JCUmJygpKissLS4vMA\","
146 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
147 " },"
148 " {"
149 " \"kty\": \"oct\","
150 " \"kid\": \"JCUmJygpKissLS4vMA\","
151 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4_QA\""
152 " }"
153 " ]"
154 "}";
155 ExtractJWKKeysAndExpect(kJwksDuplicateKids, true, 2);
158 TEST_F(JSONWebKeyTest, ExtractInvalidJWKKeys) {
159 // Try a simple JWK key (i.e. not in a set)
160 const std::string kJwkSimple =
162 " \"kty\": \"oct\","
163 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
164 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
165 "}";
166 ExtractJWKKeysAndExpect(kJwkSimple, false, 0);
168 // Try some non-ASCII characters.
169 ExtractJWKKeysAndExpect(
170 "This is not ASCII due to \xff\xfe\xfd in it.", false, 0);
172 // Try some non-ASCII characters in an otherwise valid JWK.
173 const std::string kJwksInvalidCharacters =
174 "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\","
175 "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"\xff\xfe\xfd"
176 "\",\"foo\":\"bar\"}]}\n\n";
177 ExtractJWKKeysAndExpect(kJwksInvalidCharacters, false, 0);
179 // Try a badly formatted key. Assume that the JSON parser is fully tested,
180 // so we won't try a lot of combinations. However, need a test to ensure
181 // that the code doesn't crash if invalid JSON received.
182 ExtractJWKKeysAndExpect("This is not a JSON key.", false, 0);
184 // Try passing some valid JSON that is not a dictionary at the top level.
185 ExtractJWKKeysAndExpect("40", false, 0);
187 // Try an empty dictionary.
188 ExtractJWKKeysAndExpect("{ }", false, 0);
190 // Try with 'keys' not a dictionary.
191 ExtractJWKKeysAndExpect("{ \"keys\":\"1\" }", false, 0);
193 // Try with 'keys' a list of integers.
194 ExtractJWKKeysAndExpect("{ \"keys\": [ 1, 2, 3 ] }", false, 0);
196 // Try padding(=) at end of 'k' base64 string.
197 const std::string kJwksWithPaddedKey =
199 " \"keys\": ["
200 " {"
201 " \"kty\": \"oct\","
202 " \"kid\": \"AAECAw\","
203 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
204 " }"
205 " ]"
206 "}";
207 ExtractJWKKeysAndExpect(kJwksWithPaddedKey, false, 0);
209 // Try padding(=) at end of 'kid' base64 string.
210 const std::string kJwksWithPaddedKeyId =
212 " \"keys\": ["
213 " {"
214 " \"kty\": \"oct\","
215 " \"kid\": \"AAECAw==\","
216 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
217 " }"
218 " ]"
219 "}";
220 ExtractJWKKeysAndExpect(kJwksWithPaddedKeyId, false, 0);
222 // Try a key with invalid base64 encoding.
223 const std::string kJwksWithInvalidBase64 =
225 " \"keys\": ["
226 " {"
227 " \"kty\": \"oct\","
228 " \"kid\": \"!@#$%^&*()\","
229 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
230 " }"
231 " ]"
232 "}";
233 ExtractJWKKeysAndExpect(kJwksWithInvalidBase64, false, 0);
235 // Empty key id.
236 const std::string kJwksWithEmptyKeyId =
238 " \"keys\": ["
239 " {"
240 " \"kty\": \"oct\","
241 " \"kid\": \"\","
242 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
243 " }"
244 " ]"
245 "}";
246 ExtractJWKKeysAndExpect(kJwksWithEmptyKeyId, false, 0);
249 TEST_F(JSONWebKeyTest, KeyType) {
250 // Valid key type.
251 const std::string kJwksWithValidKeyType =
253 " \"keys\": ["
254 " {"
255 " \"kty\": \"oct\","
256 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
257 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
258 " }"
259 " ]"
260 "}";
261 ExtractJWKKeysAndExpect(kJwksWithValidKeyType, true, 1);
263 // Empty key type.
264 const std::string kJwksWithEmptyKeyType =
266 " \"keys\": ["
267 " {"
268 " \"kty\": \"\","
269 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
270 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
271 " }"
272 " ]"
273 "}";
274 ExtractJWKKeysAndExpect(kJwksWithEmptyKeyType, false, 0);
276 // Key type is case sensitive.
277 const std::string kJwksWithUppercaseKeyType =
279 " \"keys\": ["
280 " {"
281 " \"kty\": \"OCT\","
282 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
283 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
284 " }"
285 " ]"
286 "}";
287 ExtractJWKKeysAndExpect(kJwksWithUppercaseKeyType, false, 0);
289 // Wrong key type.
290 const std::string kJwksWithWrongKeyType =
292 " \"keys\": ["
293 " {"
294 " \"kty\": \"RSA\","
295 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
296 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
297 " }"
298 " ]"
299 "}";
300 ExtractJWKKeysAndExpect(kJwksWithWrongKeyType, false, 0);
303 TEST_F(JSONWebKeyTest, Alg) {
304 // 'alg' is ignored, so verify that anything is allowed.
305 // Valid alg.
306 const std::string kJwksWithValidAlg =
308 " \"keys\": ["
309 " {"
310 " \"kty\": \"oct\","
311 " \"alg\": \"A128KW\","
312 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
313 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
314 " }"
315 " ]"
316 "}";
317 ExtractJWKKeysAndExpect(kJwksWithValidAlg, true, 1);
319 // Empty alg.
320 const std::string kJwksWithEmptyAlg =
322 " \"keys\": ["
323 " {"
324 " \"kty\": \"oct\","
325 " \"alg\": \"\","
326 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
327 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
328 " }"
329 " ]"
330 "}";
331 ExtractJWKKeysAndExpect(kJwksWithEmptyAlg, true, 1);
333 // Alg is case sensitive.
334 const std::string kJwksWithLowercaseAlg =
336 " \"keys\": ["
337 " {"
338 " \"kty\": \"oct\","
339 " \"alg\": \"a128kw\","
340 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
341 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
342 " }"
343 " ]"
344 "}";
345 ExtractJWKKeysAndExpect(kJwksWithLowercaseAlg, true, 1);
347 // Wrong alg.
348 const std::string kJwksWithWrongAlg =
350 " \"keys\": ["
351 " {"
352 " \"kty\": \"oct\","
353 " \"alg\": \"RS256\","
354 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
355 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
356 " }"
357 " ]"
358 "}";
359 ExtractJWKKeysAndExpect(kJwksWithWrongAlg, true, 1);
362 TEST_F(JSONWebKeyTest, SessionType) {
363 ExtractSessionTypeAndExpect(
364 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}", true,
365 MediaKeys::TEMPORARY_SESSION);
366 ExtractSessionTypeAndExpect(
367 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
368 "\"temporary\"}",
369 true, MediaKeys::TEMPORARY_SESSION);
370 ExtractSessionTypeAndExpect(
371 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
372 "\"persistent-license\"}",
373 true, MediaKeys::PERSISTENT_LICENSE_SESSION);
374 ExtractSessionTypeAndExpect(
375 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
376 "\"persistent-release-message\"}",
377 true, MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION);
378 ExtractSessionTypeAndExpect(
379 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
380 "\"unknown\"}",
381 false, MediaKeys::TEMPORARY_SESSION);
382 ExtractSessionTypeAndExpect(
383 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":3}",
384 false, MediaKeys::TEMPORARY_SESSION);
387 TEST_F(JSONWebKeyTest, CreateLicense) {
388 const uint8 data1[] = { 0x01, 0x02 };
389 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
390 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
391 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
393 CreateLicenseAndExpect(data1,
394 arraysize(data1),
395 MediaKeys::TEMPORARY_SESSION,
396 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}");
397 CreateLicenseAndExpect(
398 data1, arraysize(data1), MediaKeys::PERSISTENT_LICENSE_SESSION,
399 "{\"kids\":[\"AQI\"],\"type\":\"persistent-license\"}");
400 CreateLicenseAndExpect(
401 data1, arraysize(data1), MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION,
402 "{\"kids\":[\"AQI\"],\"type\":\"persistent-release-message\"}");
403 CreateLicenseAndExpect(data2,
404 arraysize(data2),
405 MediaKeys::TEMPORARY_SESSION,
406 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}");
407 CreateLicenseAndExpect(data3, arraysize(data3),
408 MediaKeys::PERSISTENT_LICENSE_SESSION,
409 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":"
410 "\"persistent-license\"}");
413 TEST_F(JSONWebKeyTest, ExtractLicense) {
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 ExtractKeyFromLicenseAndExpect(
420 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}",
421 true,
422 data1,
423 arraysize(data1));
424 ExtractKeyFromLicenseAndExpect(
425 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}",
426 true,
427 data2,
428 arraysize(data2));
429 ExtractKeyFromLicenseAndExpect(
430 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":\"persistent\"}",
431 true,
432 data3,
433 arraysize(data3));
435 // Try some incorrect JSON.
436 ExtractKeyFromLicenseAndExpect("", false, NULL, 0);
437 ExtractKeyFromLicenseAndExpect("!@#$%^&*()", false, NULL, 0);
439 // Valid JSON, but not a dictionary.
440 ExtractKeyFromLicenseAndExpect("6", false, NULL, 0);
441 ExtractKeyFromLicenseAndExpect("[\"AQI\"]", false, NULL, 0);
443 // Dictionary, but missing expected tag.
444 ExtractKeyFromLicenseAndExpect("{\"kid\":[\"AQI\"]}", false, NULL, 0);
446 // Correct tag, but empty list.
447 ExtractKeyFromLicenseAndExpect("{\"kids\":[]}", false, NULL, 0);
449 // Correct tag, but list doesn't contain a string.
450 ExtractKeyFromLicenseAndExpect("{\"kids\":[[\"AQI\"]]}", false, NULL, 0);
452 // Correct tag, but invalid base64 encoding.
453 ExtractKeyFromLicenseAndExpect("{\"kids\":[\"!@#$%^&*()\"]}", false, NULL, 0);
456 TEST_F(JSONWebKeyTest, Base64UrlEncoding) {
457 const uint8 data1[] = { 0xfb, 0xfd, 0xfb, 0xfd, 0xfb, 0xfd, 0xfb };
459 // Verify that |data1| contains invalid base64url characters '+' and '/'
460 // and is padded with = when converted to base64.
461 std::string encoded_text;
462 base::Base64Encode(
463 std::string(reinterpret_cast<const char*>(&data1[0]), arraysize(data1)),
464 &encoded_text);
465 EXPECT_EQ(encoded_text, "+/37/fv9+w==");
466 EXPECT_NE(encoded_text.find('+'), std::string::npos);
467 EXPECT_NE(encoded_text.find('/'), std::string::npos);
468 EXPECT_NE(encoded_text.find('='), std::string::npos);
470 // base64url characters '-' and '_' not in base64 encoding.
471 EXPECT_EQ(encoded_text.find('-'), std::string::npos);
472 EXPECT_EQ(encoded_text.find('_'), std::string::npos);
474 CreateLicenseAndExpect(data1, arraysize(data1), MediaKeys::TEMPORARY_SESSION,
475 "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}");
477 ExtractKeyFromLicenseAndExpect(
478 "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}", true, data1,
479 arraysize(data1));
482 TEST_F(JSONWebKeyTest, MultipleKeys) {
483 const uint8 data1[] = { 0x01, 0x02 };
484 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
485 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
486 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
488 std::vector<uint8> result;
489 KeyIdList key_ids;
490 key_ids.push_back(std::vector<uint8>(data1, data1 + arraysize(data1)));
491 key_ids.push_back(std::vector<uint8>(data2, data2 + arraysize(data2)));
492 key_ids.push_back(std::vector<uint8>(data3, data3 + arraysize(data3)));
493 CreateLicenseRequest(key_ids, MediaKeys::TEMPORARY_SESSION, &result);
494 std::string s(result.begin(), result.end());
495 EXPECT_EQ(
496 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":"
497 "\"temporary\"}",
501 TEST_F(JSONWebKeyTest, ExtractKeyIds) {
502 const uint8 data1[] = { 0x01, 0x02 };
503 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
504 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
505 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
507 KeyIdList key_ids;
508 std::string error_message;
510 EXPECT_TRUE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"AQI\"]}", &key_ids,
511 &error_message));
512 EXPECT_EQ(1u, key_ids.size());
513 EXPECT_EQ(0u, error_message.length());
514 VerifyKeyId(key_ids[0], data1, arraysize(data1));
516 EXPECT_TRUE(ExtractKeyIdsFromKeyIdsInitData(
517 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"]}", &key_ids,
518 &error_message));
519 EXPECT_EQ(3u, key_ids.size());
520 EXPECT_EQ(0u, error_message.length());
521 VerifyKeyId(key_ids[0], data1, arraysize(data1));
522 VerifyKeyId(key_ids[1], data2, arraysize(data2));
523 VerifyKeyId(key_ids[2], data3, arraysize(data3));
525 // Expect failure when non-ascii.
526 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData(
527 "This is not ASCII due to \xff\xfe\x0a in it.", &key_ids,
528 &error_message));
529 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
530 EXPECT_EQ(error_message,
531 "Non ASCII: This is not ASCII due to \\u00FF\\u00FE\\n in it.");
533 // Expect failure when not JSON or not a dictionary.
534 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("This is invalid.", &key_ids,
535 &error_message));
536 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
537 EXPECT_EQ(error_message, "Not valid JSON: This is invalid.");
538 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("6", &key_ids, &error_message));
539 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
540 EXPECT_EQ(error_message, "Not valid JSON: 6");
541 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData(
542 "This is a very long string that is longer than 64 characters and is "
543 "invalid.",
544 &key_ids, &error_message));
545 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
546 EXPECT_EQ(error_message,
547 "Not valid JSON: This is a very long string that is longer than 64 "
548 "characters ...");
550 // Expect failure when "kids" not specified.
551 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"keys\":[\"AQI\"]}", &key_ids,
552 &error_message));
553 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
554 EXPECT_EQ(error_message, "Missing 'kids' parameter or not a list");
556 // Expect failure when invalid key_ids specified.
557 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[1]}", &key_ids,
558 &error_message));
559 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
560 EXPECT_EQ(error_message, "'kids'[0] is not string.");
561 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\": {\"id\":\"AQI\" }}",
562 &key_ids, &error_message));
563 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
564 EXPECT_EQ(error_message, "Missing 'kids' parameter or not a list");
566 // Expect failure when non-base64 key_ids specified.
567 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"AQI+\"]}",
568 &key_ids, &error_message));
569 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
570 EXPECT_EQ(error_message,
571 "'kids'[0] is not valid base64url encoded. Value: AQI+");
572 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"AQI\",\"AQI/\"]}",
573 &key_ids, &error_message));
574 EXPECT_EQ(3u, key_ids.size()); // |key_ids| should be unchanged.
575 EXPECT_EQ(error_message,
576 "'kids'[1] is not valid base64url encoded. Value: AQI/");
579 TEST_F(JSONWebKeyTest, CreateInitData) {
580 const uint8 data1[] = { 0x01, 0x02 };
581 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
582 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
583 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
585 KeyIdList key_ids;
586 std::string error_message;
588 key_ids.push_back(std::vector<uint8>(data1, data1 + arraysize(data1)));
589 std::vector<uint8> init_data1;
590 CreateKeyIdsInitData(key_ids, &init_data1);
591 std::string result1(init_data1.begin(), init_data1.end());
592 EXPECT_EQ(result1, "{\"kids\":[\"AQI\"]}");
594 key_ids.push_back(std::vector<uint8>(data2, data2 + arraysize(data2)));
595 std::vector<uint8> init_data2;
596 CreateKeyIdsInitData(key_ids, &init_data2);
597 std::string result2(init_data2.begin(), init_data2.end());
598 EXPECT_EQ(result2, "{\"kids\":[\"AQI\",\"AQIDBA\"]}");
600 key_ids.push_back(std::vector<uint8>(data3, data3 + arraysize(data3)));
601 std::vector<uint8> init_data3;
602 CreateKeyIdsInitData(key_ids, &init_data3);
603 std::string result3(init_data3.begin(), init_data3.end());
604 EXPECT_EQ(result3,
605 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"]}");
608 } // namespace media