[Telemetry] Fix WPR files not being downloaded when required.
[chromium-blink-merge.git] / media / cdm / json_web_key_unittest.cc
blob57a57c290ca7bb5ee1157f62bf2f31ba0da92052
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/logging.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 namespace media {
12 class JSONWebKeyTest : public testing::Test {
13 public:
14 JSONWebKeyTest() {}
16 protected:
17 void ExtractJWKKeysAndExpect(const std::string& jwk,
18 bool expected_result,
19 size_t expected_number_of_keys) {
20 DCHECK(!jwk.empty());
21 KeyIdAndKeyPairs keys;
22 MediaKeys::SessionType session_type;
23 EXPECT_EQ(expected_result,
24 ExtractKeysFromJWKSet(jwk, &keys, &session_type));
25 EXPECT_EQ(expected_number_of_keys, keys.size());
28 void ExtractSessionTypeAndExpect(const std::string& jwk,
29 bool expected_result,
30 MediaKeys::SessionType expected_type) {
31 DCHECK(!jwk.empty());
32 KeyIdAndKeyPairs keys;
33 MediaKeys::SessionType session_type;
34 EXPECT_EQ(expected_result,
35 ExtractKeysFromJWKSet(jwk, &keys, &session_type));
36 if (expected_result) {
37 // Only check if successful.
38 EXPECT_EQ(expected_type, session_type);
42 void CreateLicenseAndExpect(const uint8* key_id,
43 int key_id_length,
44 MediaKeys::SessionType session_type,
45 const std::string& expected_result) {
46 std::vector<uint8> result;
47 CreateLicenseRequest(key_id, key_id_length, session_type, &result);
48 std::string s(result.begin(), result.end());
49 EXPECT_EQ(expected_result, s);
52 void ExtractKeyFromLicenseAndExpect(const std::string& license,
53 bool expected_result,
54 const uint8* expected_key,
55 int expected_key_length) {
56 std::vector<uint8> license_vector(license.begin(), license.end());
57 std::vector<uint8> key;
58 EXPECT_EQ(expected_result,
59 ExtractFirstKeyIdFromLicenseRequest(license_vector, &key));
60 if (expected_result) {
61 std::vector<uint8> key_result(expected_key,
62 expected_key + expected_key_length);
63 EXPECT_EQ(key_result, key);
68 TEST_F(JSONWebKeyTest, GenerateJWKSet) {
69 const uint8 data1[] = { 0x01, 0x02 };
70 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
71 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
72 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
74 EXPECT_EQ(
75 "{\"keys\":[{\"alg\":\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":"
76 "\"oct\"}]}",
77 GenerateJWKSet(data1, arraysize(data1), data1, arraysize(data1)));
78 EXPECT_EQ(
79 "{\"keys\":[{\"alg\":\"A128KW\",\"k\":\"AQIDBA\",\"kid\":\"AQIDBA\","
80 "\"kty\":\"oct\"}]}",
81 GenerateJWKSet(data2, arraysize(data2), data2, arraysize(data2)));
82 EXPECT_EQ(
83 "{\"keys\":[{\"alg\":\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQIDBA\",\"kty\":"
84 "\"oct\"}]}",
85 GenerateJWKSet(data1, arraysize(data1), data2, arraysize(data2)));
86 EXPECT_EQ(
87 "{\"keys\":[{\"alg\":\"A128KW\",\"k\":\"AQIDBA\",\"kid\":\"AQI\",\"kty\":"
88 "\"oct\"}]}",
89 GenerateJWKSet(data2, arraysize(data2), data1, arraysize(data1)));
90 EXPECT_EQ(
91 "{\"keys\":[{\"alg\":\"A128KW\",\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":"
92 "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":\"oct\"}]}",
93 GenerateJWKSet(data3, arraysize(data3), data3, arraysize(data3)));
96 TEST_F(JSONWebKeyTest, ExtractValidJWKKeys) {
97 // Try an empty 'keys' dictionary.
98 ExtractJWKKeysAndExpect("{ \"keys\": [] }", true, 0);
100 // Try a key list with one entry.
101 const std::string kJwksOneEntry =
103 " \"keys\": ["
104 " {"
105 " \"kty\": \"oct\","
106 " \"alg\": \"A128KW\","
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 " \"alg\": \"A128KW\","
121 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
122 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
123 " },"
124 " {"
125 " \"kty\": \"oct\","
126 " \"alg\": \"A128KW\","
127 " \"kid\": \"JCUmJygpKissLS4vMA\","
128 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\""
129 " }"
130 " ]"
131 "}";
132 ExtractJWKKeysAndExpect(kJwksMultipleEntries, true, 2);
134 // Try a key with no spaces and some \n plus additional fields.
135 const std::string kJwksNoSpaces =
136 "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\","
137 "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg"
138 "\",\"foo\":\"bar\"}]}\n\n";
139 ExtractJWKKeysAndExpect(kJwksNoSpaces, true, 1);
141 // Try a list with multiple keys with the same kid.
142 const std::string kJwksDuplicateKids =
144 " \"keys\": ["
145 " {"
146 " \"kty\": \"oct\","
147 " \"alg\": \"A128KW\","
148 " \"kid\": \"JCUmJygpKissLS4vMA\","
149 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
150 " },"
151 " {"
152 " \"kty\": \"oct\","
153 " \"alg\": \"A128KW\","
154 " \"kid\": \"JCUmJygpKissLS4vMA\","
155 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\""
156 " }"
157 " ]"
158 "}";
159 ExtractJWKKeysAndExpect(kJwksDuplicateKids, true, 2);
162 TEST_F(JSONWebKeyTest, ExtractInvalidJWKKeys) {
163 // Try a simple JWK key (i.e. not in a set)
164 const std::string kJwkSimple =
166 " \"kty\": \"oct\","
167 " \"alg\": \"A128KW\","
168 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
169 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
170 "}";
171 ExtractJWKKeysAndExpect(kJwkSimple, false, 0);
173 // Try some non-ASCII characters.
174 ExtractJWKKeysAndExpect(
175 "This is not ASCII due to \xff\xfe\xfd in it.", false, 0);
177 // Try some non-ASCII characters in an otherwise valid JWK.
178 const std::string kJwksInvalidCharacters =
179 "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\","
180 "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"\xff\xfe\xfd"
181 "\",\"foo\":\"bar\"}]}\n\n";
182 ExtractJWKKeysAndExpect(kJwksInvalidCharacters, false, 0);
184 // Try a badly formatted key. Assume that the JSON parser is fully tested,
185 // so we won't try a lot of combinations. However, need a test to ensure
186 // that the code doesn't crash if invalid JSON received.
187 ExtractJWKKeysAndExpect("This is not a JSON key.", false, 0);
189 // Try passing some valid JSON that is not a dictionary at the top level.
190 ExtractJWKKeysAndExpect("40", false, 0);
192 // Try an empty dictionary.
193 ExtractJWKKeysAndExpect("{ }", false, 0);
195 // Try with 'keys' not a dictionary.
196 ExtractJWKKeysAndExpect("{ \"keys\":\"1\" }", false, 0);
198 // Try with 'keys' a list of integers.
199 ExtractJWKKeysAndExpect("{ \"keys\": [ 1, 2, 3 ] }", false, 0);
201 // Try padding(=) at end of 'k' base64 string.
202 const std::string kJwksWithPaddedKey =
204 " \"keys\": ["
205 " {"
206 " \"kty\": \"oct\","
207 " \"alg\": \"A128KW\","
208 " \"kid\": \"AAECAw\","
209 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
210 " }"
211 " ]"
212 "}";
213 ExtractJWKKeysAndExpect(kJwksWithPaddedKey, false, 0);
215 // Try padding(=) at end of 'kid' base64 string.
216 const std::string kJwksWithPaddedKeyId =
218 " \"keys\": ["
219 " {"
220 " \"kty\": \"oct\","
221 " \"alg\": \"A128KW\","
222 " \"kid\": \"AAECAw==\","
223 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
224 " }"
225 " ]"
226 "}";
227 ExtractJWKKeysAndExpect(kJwksWithPaddedKeyId, false, 0);
229 // Try a key with invalid base64 encoding.
230 const std::string kJwksWithInvalidBase64 =
232 " \"keys\": ["
233 " {"
234 " \"kty\": \"oct\","
235 " \"alg\": \"A128KW\","
236 " \"kid\": \"!@#$%^&*()\","
237 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
238 " }"
239 " ]"
240 "}";
241 ExtractJWKKeysAndExpect(kJwksWithInvalidBase64, false, 0);
243 // Empty key id.
244 const std::string kJwksWithEmptyKeyId =
246 " \"keys\": ["
247 " {"
248 " \"kty\": \"oct\","
249 " \"alg\": \"A128KW\","
250 " \"kid\": \"\","
251 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
252 " }"
253 " ]"
254 "}";
255 ExtractJWKKeysAndExpect(kJwksWithEmptyKeyId, false, 0);
258 TEST_F(JSONWebKeyTest, KeyType) {
259 // Valid key type.
260 const std::string kJwksWithValidKeyType =
262 " \"keys\": ["
263 " {"
264 " \"kty\": \"oct\","
265 " \"alg\": \"A128KW\","
266 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
267 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
268 " }"
269 " ]"
270 "}";
271 ExtractJWKKeysAndExpect(kJwksWithValidKeyType, true, 1);
273 // Empty key type.
274 const std::string kJwksWithEmptyKeyType =
276 " \"keys\": ["
277 " {"
278 " \"kty\": \"\","
279 " \"alg\": \"A128KW\","
280 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
281 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
282 " }"
283 " ]"
284 "}";
285 ExtractJWKKeysAndExpect(kJwksWithEmptyKeyType, false, 0);
287 // Key type is case sensitive.
288 const std::string kJwksWithUppercaseKeyType =
290 " \"keys\": ["
291 " {"
292 " \"kty\": \"OCT\","
293 " \"alg\": \"A128KW\","
294 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
295 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
296 " }"
297 " ]"
298 "}";
299 ExtractJWKKeysAndExpect(kJwksWithUppercaseKeyType, false, 0);
301 // Wrong key type.
302 const std::string kJwksWithWrongKeyType =
304 " \"keys\": ["
305 " {"
306 " \"kty\": \"RSA\","
307 " \"alg\": \"A128KW\","
308 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
309 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
310 " }"
311 " ]"
312 "}";
313 ExtractJWKKeysAndExpect(kJwksWithWrongKeyType, false, 0);
316 TEST_F(JSONWebKeyTest, Alg) {
317 // Valid alg.
318 const std::string kJwksWithValidAlg =
320 " \"keys\": ["
321 " {"
322 " \"kty\": \"oct\","
323 " \"alg\": \"A128KW\","
324 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
325 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
326 " }"
327 " ]"
328 "}";
329 ExtractJWKKeysAndExpect(kJwksWithValidAlg, true, 1);
331 // Empty alg.
332 const std::string kJwksWithEmptyAlg =
334 " \"keys\": ["
335 " {"
336 " \"kty\": \"oct\","
337 " \"alg\": \"\","
338 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
339 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
340 " }"
341 " ]"
342 "}";
343 ExtractJWKKeysAndExpect(kJwksWithEmptyAlg, false, 0);
345 // Alg is case sensitive.
346 const std::string kJwksWithLowercaseAlg =
348 " \"keys\": ["
349 " {"
350 " \"kty\": \"oct\","
351 " \"alg\": \"a128kw\","
352 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
353 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
354 " }"
355 " ]"
356 "}";
357 ExtractJWKKeysAndExpect(kJwksWithLowercaseAlg, false, 0);
359 // Wrong alg.
360 const std::string kJwksWithWrongAlg =
362 " \"keys\": ["
363 " {"
364 " \"kty\": \"oct\","
365 " \"alg\": \"RS256\","
366 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
367 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
368 " }"
369 " ]"
370 "}";
371 ExtractJWKKeysAndExpect(kJwksWithWrongAlg, false, 0);
374 TEST_F(JSONWebKeyTest, SessionType) {
375 ExtractSessionTypeAndExpect(
376 "{\"keys\":[{\"alg\": "
377 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
378 true, MediaKeys::TEMPORARY_SESSION);
379 ExtractSessionTypeAndExpect(
380 "{\"keys\":[{\"alg\": "
381 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
382 "\"temporary\"}",
383 true, MediaKeys::TEMPORARY_SESSION);
384 ExtractSessionTypeAndExpect(
385 "{\"keys\":[{\"alg\": "
386 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
387 "\"persistent-license\"}",
388 true, MediaKeys::PERSISTENT_LICENSE_SESSION);
389 ExtractSessionTypeAndExpect(
390 "{\"keys\":[{\"alg\": "
391 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
392 "\"persistent-release-message\"}",
393 true, MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION);
394 ExtractSessionTypeAndExpect(
395 "{\"keys\":[{\"alg\": "
396 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
397 "\"unknown\"}",
398 false, MediaKeys::TEMPORARY_SESSION);
399 ExtractSessionTypeAndExpect(
400 "{\"keys\":[{\"alg\": "
401 "\"A128KW\",\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":3}",
402 false, MediaKeys::TEMPORARY_SESSION);
405 TEST_F(JSONWebKeyTest, CreateLicense) {
406 const uint8 data1[] = { 0x01, 0x02 };
407 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
408 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
409 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
411 CreateLicenseAndExpect(data1,
412 arraysize(data1),
413 MediaKeys::TEMPORARY_SESSION,
414 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}");
415 CreateLicenseAndExpect(
416 data1, arraysize(data1), MediaKeys::PERSISTENT_LICENSE_SESSION,
417 "{\"kids\":[\"AQI\"],\"type\":\"persistent-license\"}");
418 CreateLicenseAndExpect(
419 data1, arraysize(data1), MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION,
420 "{\"kids\":[\"AQI\"],\"type\":\"persistent-release-message\"}");
421 CreateLicenseAndExpect(data2,
422 arraysize(data2),
423 MediaKeys::TEMPORARY_SESSION,
424 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}");
425 CreateLicenseAndExpect(data3, arraysize(data3),
426 MediaKeys::PERSISTENT_LICENSE_SESSION,
427 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":"
428 "\"persistent-license\"}");
431 TEST_F(JSONWebKeyTest, ExtractLicense) {
432 const uint8 data1[] = { 0x01, 0x02 };
433 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
434 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
435 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
437 ExtractKeyFromLicenseAndExpect(
438 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}",
439 true,
440 data1,
441 arraysize(data1));
442 ExtractKeyFromLicenseAndExpect(
443 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}",
444 true,
445 data2,
446 arraysize(data2));
447 ExtractKeyFromLicenseAndExpect(
448 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":\"persistent\"}",
449 true,
450 data3,
451 arraysize(data3));
453 // Try some incorrect JSON.
454 ExtractKeyFromLicenseAndExpect("", false, NULL, 0);
455 ExtractKeyFromLicenseAndExpect("!@#$%^&*()", false, NULL, 0);
457 // Valid JSON, but not a dictionary.
458 ExtractKeyFromLicenseAndExpect("6", false, NULL, 0);
459 ExtractKeyFromLicenseAndExpect("[\"AQI\"]", false, NULL, 0);
461 // Dictionary, but missing expected tag.
462 ExtractKeyFromLicenseAndExpect("{\"kid\":[\"AQI\"]}", false, NULL, 0);
464 // Correct tag, but empty list.
465 ExtractKeyFromLicenseAndExpect("{\"kids\":[]}", false, NULL, 0);
467 // Correct tag, but list doesn't contain a string.
468 ExtractKeyFromLicenseAndExpect("{\"kids\":[[\"AQI\"]]}", false, NULL, 0);
470 // Correct tag, but invalid base64 encoding.
471 ExtractKeyFromLicenseAndExpect("{\"kids\":[\"!@#$%^&*()\"]}", false, NULL, 0);
474 } // namespace media