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"
13 class JSONWebKeyTest
: public testing::Test
{
18 void ExtractJWKKeysAndExpect(const std::string
& jwk
,
20 size_t expected_number_of_keys
) {
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
,
31 MediaKeys::SessionType expected_type
) {
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
,
45 MediaKeys::SessionType session_type
,
46 const std::string
& expected_result
) {
47 std::vector
<uint8
> result
;
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
,
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
));
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
);
75 KeyIdAndKeyPair
MakeKeyIdAndKeyPair(const uint8
* key
,
79 return std::make_pair(std::string(key_id
, key_id
+ key_id_length
),
80 std::string(key
, key
+ key_length
));
84 TEST_F(JSONWebKeyTest
, GenerateJWKSet
) {
85 const uint8 data1
[] = { 0x01, 0x02 };
86 const uint8 data2
[] = { 0x01, 0x02, 0x03, 0x04 };
87 const uint8 data3
[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
88 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
90 EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
91 GenerateJWKSet(data1
, arraysize(data1
), data1
, arraysize(data1
)));
93 "{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}",
94 GenerateJWKSet(data2
, arraysize(data2
), data2
, arraysize(data2
)));
95 EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}",
96 GenerateJWKSet(data1
, arraysize(data1
), data2
, arraysize(data2
)));
97 EXPECT_EQ("{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
98 GenerateJWKSet(data2
, arraysize(data2
), data1
, arraysize(data1
)));
100 "{\"keys\":[{\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":"
101 "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":\"oct\"}]}",
102 GenerateJWKSet(data3
, arraysize(data3
), data3
, arraysize(data3
)));
104 KeyIdAndKeyPairs keys
;
106 MakeKeyIdAndKeyPair(data1
, arraysize(data1
), data1
, arraysize(data1
)));
108 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
110 GenerateJWKSet(keys
, MediaKeys::TEMPORARY_SESSION
));
112 MakeKeyIdAndKeyPair(data2
, arraysize(data2
), data2
, arraysize(data2
)));
114 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"},{\"k\":"
115 "\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}],\"type\":\"persistent-"
117 GenerateJWKSet(keys
, MediaKeys::PERSISTENT_LICENSE_SESSION
));
119 MakeKeyIdAndKeyPair(data3
, arraysize(data3
), data3
, arraysize(data3
)));
121 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"},{\"k\":"
122 "\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"},{\"k\":"
123 "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":"
124 "\"oct\"}],\"type\":\"persistent-release-message\"}",
125 GenerateJWKSet(keys
, MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION
));
128 TEST_F(JSONWebKeyTest
, ExtractValidJWKKeys
) {
129 // Try an empty 'keys' dictionary.
130 ExtractJWKKeysAndExpect("{ \"keys\": [] }", true, 0);
132 // Try a key list with one entry.
133 const std::string kJwksOneEntry
=
138 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
139 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
143 ExtractJWKKeysAndExpect(kJwksOneEntry
, true, 1);
145 // Try a key list with multiple entries.
146 const std::string kJwksMultipleEntries
=
151 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
152 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
156 " \"kid\": \"JCUmJygpKissLS4vMA\","
157 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4_QA\""
161 ExtractJWKKeysAndExpect(kJwksMultipleEntries
, true, 2);
163 // Try a key with no spaces and some \n plus additional fields.
164 const std::string kJwksNoSpaces
=
165 "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\","
166 "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg"
167 "\",\"foo\":\"bar\"}]}\n\n";
168 ExtractJWKKeysAndExpect(kJwksNoSpaces
, true, 1);
170 // Try a list with multiple keys with the same kid.
171 const std::string kJwksDuplicateKids
=
176 " \"kid\": \"JCUmJygpKissLS4vMA\","
177 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
181 " \"kid\": \"JCUmJygpKissLS4vMA\","
182 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4_QA\""
186 ExtractJWKKeysAndExpect(kJwksDuplicateKids
, true, 2);
189 TEST_F(JSONWebKeyTest
, ExtractInvalidJWKKeys
) {
190 // Try a simple JWK key (i.e. not in a set)
191 const std::string kJwkSimple
=
194 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
195 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
197 ExtractJWKKeysAndExpect(kJwkSimple
, false, 0);
199 // Try some non-ASCII characters.
200 ExtractJWKKeysAndExpect(
201 "This is not ASCII due to \xff\xfe\xfd in it.", false, 0);
203 // Try some non-ASCII characters in an otherwise valid JWK.
204 const std::string kJwksInvalidCharacters
=
205 "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\","
206 "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"\xff\xfe\xfd"
207 "\",\"foo\":\"bar\"}]}\n\n";
208 ExtractJWKKeysAndExpect(kJwksInvalidCharacters
, false, 0);
210 // Try a badly formatted key. Assume that the JSON parser is fully tested,
211 // so we won't try a lot of combinations. However, need a test to ensure
212 // that the code doesn't crash if invalid JSON received.
213 ExtractJWKKeysAndExpect("This is not a JSON key.", false, 0);
215 // Try passing some valid JSON that is not a dictionary at the top level.
216 ExtractJWKKeysAndExpect("40", false, 0);
218 // Try an empty dictionary.
219 ExtractJWKKeysAndExpect("{ }", false, 0);
221 // Try with 'keys' not a dictionary.
222 ExtractJWKKeysAndExpect("{ \"keys\":\"1\" }", false, 0);
224 // Try with 'keys' a list of integers.
225 ExtractJWKKeysAndExpect("{ \"keys\": [ 1, 2, 3 ] }", false, 0);
227 // Try padding(=) at end of 'k' base64 string.
228 const std::string kJwksWithPaddedKey
=
233 " \"kid\": \"AAECAw\","
234 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
238 ExtractJWKKeysAndExpect(kJwksWithPaddedKey
, false, 0);
240 // Try padding(=) at end of 'kid' base64 string.
241 const std::string kJwksWithPaddedKeyId
=
246 " \"kid\": \"AAECAw==\","
247 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
251 ExtractJWKKeysAndExpect(kJwksWithPaddedKeyId
, false, 0);
253 // Try a key with invalid base64 encoding.
254 const std::string kJwksWithInvalidBase64
=
259 " \"kid\": \"!@#$%^&*()\","
260 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
264 ExtractJWKKeysAndExpect(kJwksWithInvalidBase64
, false, 0);
267 const std::string kJwksWithEmptyKeyId
=
273 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
277 ExtractJWKKeysAndExpect(kJwksWithEmptyKeyId
, false, 0);
280 TEST_F(JSONWebKeyTest
, KeyType
) {
282 const std::string kJwksWithValidKeyType
=
287 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
288 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
292 ExtractJWKKeysAndExpect(kJwksWithValidKeyType
, true, 1);
295 const std::string kJwksWithEmptyKeyType
=
300 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
301 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
305 ExtractJWKKeysAndExpect(kJwksWithEmptyKeyType
, false, 0);
307 // Key type is case sensitive.
308 const std::string kJwksWithUppercaseKeyType
=
313 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
314 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
318 ExtractJWKKeysAndExpect(kJwksWithUppercaseKeyType
, false, 0);
321 const std::string kJwksWithWrongKeyType
=
326 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
327 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
331 ExtractJWKKeysAndExpect(kJwksWithWrongKeyType
, false, 0);
334 TEST_F(JSONWebKeyTest
, Alg
) {
335 // 'alg' is ignored, so verify that anything is allowed.
337 const std::string kJwksWithValidAlg
=
342 " \"alg\": \"A128KW\","
343 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
344 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
348 ExtractJWKKeysAndExpect(kJwksWithValidAlg
, true, 1);
351 const std::string kJwksWithEmptyAlg
=
357 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
358 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
362 ExtractJWKKeysAndExpect(kJwksWithEmptyAlg
, true, 1);
364 // Alg is case sensitive.
365 const std::string kJwksWithLowercaseAlg
=
370 " \"alg\": \"a128kw\","
371 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
372 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
376 ExtractJWKKeysAndExpect(kJwksWithLowercaseAlg
, true, 1);
379 const std::string kJwksWithWrongAlg
=
384 " \"alg\": \"RS256\","
385 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
386 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
390 ExtractJWKKeysAndExpect(kJwksWithWrongAlg
, true, 1);
393 TEST_F(JSONWebKeyTest
, SessionType
) {
394 ExtractSessionTypeAndExpect(
395 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}", true,
396 MediaKeys::TEMPORARY_SESSION
);
397 ExtractSessionTypeAndExpect(
398 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
400 true, MediaKeys::TEMPORARY_SESSION
);
401 ExtractSessionTypeAndExpect(
402 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
403 "\"persistent-license\"}",
404 true, MediaKeys::PERSISTENT_LICENSE_SESSION
);
405 ExtractSessionTypeAndExpect(
406 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
407 "\"persistent-release-message\"}",
408 true, MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION
);
409 ExtractSessionTypeAndExpect(
410 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
412 false, MediaKeys::TEMPORARY_SESSION
);
413 ExtractSessionTypeAndExpect(
414 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":3}",
415 false, MediaKeys::TEMPORARY_SESSION
);
418 TEST_F(JSONWebKeyTest
, CreateLicense
) {
419 const uint8 data1
[] = { 0x01, 0x02 };
420 const uint8 data2
[] = { 0x01, 0x02, 0x03, 0x04 };
421 const uint8 data3
[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
422 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
424 CreateLicenseAndExpect(data1
,
426 MediaKeys::TEMPORARY_SESSION
,
427 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}");
428 CreateLicenseAndExpect(
429 data1
, arraysize(data1
), MediaKeys::PERSISTENT_LICENSE_SESSION
,
430 "{\"kids\":[\"AQI\"],\"type\":\"persistent-license\"}");
431 CreateLicenseAndExpect(
432 data1
, arraysize(data1
), MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION
,
433 "{\"kids\":[\"AQI\"],\"type\":\"persistent-release-message\"}");
434 CreateLicenseAndExpect(data2
,
436 MediaKeys::TEMPORARY_SESSION
,
437 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}");
438 CreateLicenseAndExpect(data3
, arraysize(data3
),
439 MediaKeys::PERSISTENT_LICENSE_SESSION
,
440 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":"
441 "\"persistent-license\"}");
444 TEST_F(JSONWebKeyTest
, ExtractLicense
) {
445 const uint8 data1
[] = { 0x01, 0x02 };
446 const uint8 data2
[] = { 0x01, 0x02, 0x03, 0x04 };
447 const uint8 data3
[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
448 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
450 ExtractKeyFromLicenseAndExpect(
451 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}",
455 ExtractKeyFromLicenseAndExpect(
456 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}",
460 ExtractKeyFromLicenseAndExpect(
461 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":\"persistent\"}",
466 // Try some incorrect JSON.
467 ExtractKeyFromLicenseAndExpect("", false, NULL
, 0);
468 ExtractKeyFromLicenseAndExpect("!@#$%^&*()", false, NULL
, 0);
470 // Valid JSON, but not a dictionary.
471 ExtractKeyFromLicenseAndExpect("6", false, NULL
, 0);
472 ExtractKeyFromLicenseAndExpect("[\"AQI\"]", false, NULL
, 0);
474 // Dictionary, but missing expected tag.
475 ExtractKeyFromLicenseAndExpect("{\"kid\":[\"AQI\"]}", false, NULL
, 0);
477 // Correct tag, but empty list.
478 ExtractKeyFromLicenseAndExpect("{\"kids\":[]}", false, NULL
, 0);
480 // Correct tag, but list doesn't contain a string.
481 ExtractKeyFromLicenseAndExpect("{\"kids\":[[\"AQI\"]]}", false, NULL
, 0);
483 // Correct tag, but invalid base64 encoding.
484 ExtractKeyFromLicenseAndExpect("{\"kids\":[\"!@#$%^&*()\"]}", false, NULL
, 0);
487 TEST_F(JSONWebKeyTest
, Base64UrlEncoding
) {
488 const uint8 data1
[] = { 0xfb, 0xfd, 0xfb, 0xfd, 0xfb, 0xfd, 0xfb };
490 // Verify that |data1| contains invalid base64url characters '+' and '/'
491 // and is padded with = when converted to base64.
492 std::string encoded_text
;
494 std::string(reinterpret_cast<const char*>(&data1
[0]), arraysize(data1
)),
496 EXPECT_EQ(encoded_text
, "+/37/fv9+w==");
497 EXPECT_NE(encoded_text
.find('+'), std::string::npos
);
498 EXPECT_NE(encoded_text
.find('/'), std::string::npos
);
499 EXPECT_NE(encoded_text
.find('='), std::string::npos
);
501 // base64url characters '-' and '_' not in base64 encoding.
502 EXPECT_EQ(encoded_text
.find('-'), std::string::npos
);
503 EXPECT_EQ(encoded_text
.find('_'), std::string::npos
);
505 CreateLicenseAndExpect(data1
, arraysize(data1
), MediaKeys::TEMPORARY_SESSION
,
506 "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}");
508 ExtractKeyFromLicenseAndExpect(
509 "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}", true, data1
,
513 TEST_F(JSONWebKeyTest
, MultipleKeys
) {
514 const uint8 data1
[] = { 0x01, 0x02 };
515 const uint8 data2
[] = { 0x01, 0x02, 0x03, 0x04 };
516 const uint8 data3
[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
517 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
519 std::vector
<uint8
> result
;
521 key_ids
.push_back(std::vector
<uint8
>(data1
, data1
+ arraysize(data1
)));
522 key_ids
.push_back(std::vector
<uint8
>(data2
, data2
+ arraysize(data2
)));
523 key_ids
.push_back(std::vector
<uint8
>(data3
, data3
+ arraysize(data3
)));
524 CreateLicenseRequest(key_ids
, MediaKeys::TEMPORARY_SESSION
, &result
);
525 std::string
s(result
.begin(), result
.end());
527 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":"
532 TEST_F(JSONWebKeyTest
, ExtractKeyIds
) {
533 const uint8 data1
[] = { 0x01, 0x02 };
534 const uint8 data2
[] = { 0x01, 0x02, 0x03, 0x04 };
535 const uint8 data3
[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
536 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
539 std::string error_message
;
541 EXPECT_TRUE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"AQI\"]}", &key_ids
,
543 EXPECT_EQ(1u, key_ids
.size());
544 EXPECT_EQ(0u, error_message
.length());
545 VerifyKeyId(key_ids
[0], data1
, arraysize(data1
));
547 EXPECT_TRUE(ExtractKeyIdsFromKeyIdsInitData(
548 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"]}", &key_ids
,
550 EXPECT_EQ(3u, key_ids
.size());
551 EXPECT_EQ(0u, error_message
.length());
552 VerifyKeyId(key_ids
[0], data1
, arraysize(data1
));
553 VerifyKeyId(key_ids
[1], data2
, arraysize(data2
));
554 VerifyKeyId(key_ids
[2], data3
, arraysize(data3
));
556 // Expect failure when non-ascii.
557 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData(
558 "This is not ASCII due to \xff\xfe\x0a in it.", &key_ids
,
560 EXPECT_EQ(3u, key_ids
.size()); // |key_ids| should be unchanged.
561 EXPECT_EQ(error_message
,
562 "Non ASCII: This is not ASCII due to \\u00FF\\u00FE\\n in it.");
564 // Expect failure when not JSON or not a dictionary.
565 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("This is invalid.", &key_ids
,
567 EXPECT_EQ(3u, key_ids
.size()); // |key_ids| should be unchanged.
568 EXPECT_EQ(error_message
, "Not valid JSON: This is invalid.");
569 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("6", &key_ids
, &error_message
));
570 EXPECT_EQ(3u, key_ids
.size()); // |key_ids| should be unchanged.
571 EXPECT_EQ(error_message
, "Not valid JSON: 6");
572 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData(
573 "This is a very long string that is longer than 64 characters and is "
575 &key_ids
, &error_message
));
576 EXPECT_EQ(3u, key_ids
.size()); // |key_ids| should be unchanged.
577 EXPECT_EQ(error_message
,
578 "Not valid JSON: This is a very long string that is longer than 64 "
581 // Expect failure when "kids" not specified.
582 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"keys\":[\"AQI\"]}", &key_ids
,
584 EXPECT_EQ(3u, key_ids
.size()); // |key_ids| should be unchanged.
585 EXPECT_EQ(error_message
, "Missing 'kids' parameter or not a list");
587 // Expect failure when invalid key_ids specified.
588 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[1]}", &key_ids
,
590 EXPECT_EQ(3u, key_ids
.size()); // |key_ids| should be unchanged.
591 EXPECT_EQ(error_message
, "'kids'[0] is not string.");
592 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\": {\"id\":\"AQI\" }}",
593 &key_ids
, &error_message
));
594 EXPECT_EQ(3u, key_ids
.size()); // |key_ids| should be unchanged.
595 EXPECT_EQ(error_message
, "Missing 'kids' parameter or not a list");
597 // Expect failure when non-base64 key_ids specified.
598 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"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'[0] is not valid base64url encoded. Value: AQI+");
603 EXPECT_FALSE(ExtractKeyIdsFromKeyIdsInitData("{\"kids\":[\"AQI\",\"AQI/\"]}",
604 &key_ids
, &error_message
));
605 EXPECT_EQ(3u, key_ids
.size()); // |key_ids| should be unchanged.
606 EXPECT_EQ(error_message
,
607 "'kids'[1] is not valid base64url encoded. Value: AQI/");
610 TEST_F(JSONWebKeyTest
, CreateInitData
) {
611 const uint8 data1
[] = { 0x01, 0x02 };
612 const uint8 data2
[] = { 0x01, 0x02, 0x03, 0x04 };
613 const uint8 data3
[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
614 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
617 std::string error_message
;
619 key_ids
.push_back(std::vector
<uint8
>(data1
, data1
+ arraysize(data1
)));
620 std::vector
<uint8
> init_data1
;
621 CreateKeyIdsInitData(key_ids
, &init_data1
);
622 std::string
result1(init_data1
.begin(), init_data1
.end());
623 EXPECT_EQ(result1
, "{\"kids\":[\"AQI\"]}");
625 key_ids
.push_back(std::vector
<uint8
>(data2
, data2
+ arraysize(data2
)));
626 std::vector
<uint8
> init_data2
;
627 CreateKeyIdsInitData(key_ids
, &init_data2
);
628 std::string
result2(init_data2
.begin(), init_data2
.end());
629 EXPECT_EQ(result2
, "{\"kids\":[\"AQI\",\"AQIDBA\"]}");
631 key_ids
.push_back(std::vector
<uint8
>(data3
, data3
+ arraysize(data3
)));
632 std::vector
<uint8
> init_data3
;
633 CreateKeyIdsInitData(key_ids
, &init_data3
);
634 std::string
result3(init_data3
.begin(), init_data3
.end());
636 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"]}");