[MemSheriff] More sendto parameter issues.
[chromium-blink-merge.git] / media / cdm / json_web_key_unittest.cc
blob49ea32bd4568a47f9a216e5fe95515c74d3e5579
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("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
75 GenerateJWKSet(data1, arraysize(data1), data1, arraysize(data1)));
76 EXPECT_EQ(
77 "{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}",
78 GenerateJWKSet(data2, arraysize(data2), data2, arraysize(data2)));
79 EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}",
80 GenerateJWKSet(data1, arraysize(data1), data2, arraysize(data2)));
81 EXPECT_EQ("{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
82 GenerateJWKSet(data2, arraysize(data2), data1, arraysize(data1)));
83 EXPECT_EQ(
84 "{\"keys\":[{\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":"
85 "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":\"oct\"}]}",
86 GenerateJWKSet(data3, arraysize(data3), data3, arraysize(data3)));
89 TEST_F(JSONWebKeyTest, ExtractJWKKeys) {
90 // Try a simple JWK key (i.e. not in a set)
91 const std::string kJwkSimple =
92 "{"
93 " \"kty\": \"oct\","
94 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
95 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
96 "}";
97 ExtractJWKKeysAndExpect(kJwkSimple, false, 0);
99 // Try a key list with multiple entries.
100 const std::string kJwksMultipleEntries =
102 " \"keys\": ["
103 " {"
104 " \"kty\": \"oct\","
105 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
106 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
107 " },"
108 " {"
109 " \"kty\": \"oct\","
110 " \"kid\": \"JCUmJygpKissLS4vMA\","
111 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\""
112 " }"
113 " ]"
114 "}";
115 ExtractJWKKeysAndExpect(kJwksMultipleEntries, true, 2);
117 // Try a key with no spaces and some \n plus additional fields.
118 const std::string kJwksNoSpaces =
119 "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\","
120 "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg"
121 "\",\"foo\":\"bar\"}]}\n\n";
122 ExtractJWKKeysAndExpect(kJwksNoSpaces, true, 1);
124 // Try some non-ASCII characters.
125 ExtractJWKKeysAndExpect(
126 "This is not ASCII due to \xff\xfe\xfd in it.", false, 0);
128 // Try some non-ASCII characters in an otherwise valid JWK.
129 const std::string kJwksInvalidCharacters =
130 "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\","
131 "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"\xff\xfe\xfd"
132 "\",\"foo\":\"bar\"}]}\n\n";
133 ExtractJWKKeysAndExpect(kJwksInvalidCharacters, false, 0);
135 // Try a badly formatted key. Assume that the JSON parser is fully tested,
136 // so we won't try a lot of combinations. However, need a test to ensure
137 // that the code doesn't crash if invalid JSON received.
138 ExtractJWKKeysAndExpect("This is not a JSON key.", false, 0);
140 // Try passing some valid JSON that is not a dictionary at the top level.
141 ExtractJWKKeysAndExpect("40", false, 0);
143 // Try an empty dictionary.
144 ExtractJWKKeysAndExpect("{ }", false, 0);
146 // Try an empty 'keys' dictionary.
147 ExtractJWKKeysAndExpect("{ \"keys\": [] }", true, 0);
149 // Try with 'keys' not a dictionary.
150 ExtractJWKKeysAndExpect("{ \"keys\":\"1\" }", false, 0);
152 // Try with 'keys' a list of integers.
153 ExtractJWKKeysAndExpect("{ \"keys\": [ 1, 2, 3 ] }", false, 0);
155 // Try padding(=) at end of 'k' base64 string.
156 const std::string kJwksWithPaddedKey =
158 " \"keys\": ["
159 " {"
160 " \"kty\": \"oct\","
161 " \"kid\": \"AAECAw\","
162 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
163 " }"
164 " ]"
165 "}";
166 ExtractJWKKeysAndExpect(kJwksWithPaddedKey, false, 0);
168 // Try padding(=) at end of 'kid' base64 string.
169 const std::string kJwksWithPaddedKeyId =
171 " \"keys\": ["
172 " {"
173 " \"kty\": \"oct\","
174 " \"kid\": \"AAECAw==\","
175 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
176 " }"
177 " ]"
178 "}";
179 ExtractJWKKeysAndExpect(kJwksWithPaddedKeyId, false, 0);
181 // Try a key with invalid base64 encoding.
182 const std::string kJwksWithInvalidBase64 =
184 " \"keys\": ["
185 " {"
186 " \"kty\": \"oct\","
187 " \"kid\": \"!@#$%^&*()\","
188 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
189 " }"
190 " ]"
191 "}";
192 ExtractJWKKeysAndExpect(kJwksWithInvalidBase64, false, 0);
194 // Empty key id.
195 const std::string kJwksWithEmptyKeyId =
197 " \"keys\": ["
198 " {"
199 " \"kty\": \"oct\","
200 " \"kid\": \"\","
201 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
202 " }"
203 " ]"
204 "}";
205 ExtractJWKKeysAndExpect(kJwksWithEmptyKeyId, false, 0);
207 // Try a list with multiple keys with the same kid.
208 const std::string kJwksDuplicateKids =
210 " \"keys\": ["
211 " {"
212 " \"kty\": \"oct\","
213 " \"kid\": \"JCUmJygpKissLS4vMA\","
214 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
215 " },"
216 " {"
217 " \"kty\": \"oct\","
218 " \"kid\": \"JCUmJygpKissLS4vMA\","
219 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\""
220 " }"
221 " ]"
222 "}";
223 ExtractJWKKeysAndExpect(kJwksDuplicateKids, true, 2);
226 TEST_F(JSONWebKeyTest, SessionType) {
227 ExtractSessionTypeAndExpect(
228 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
229 true,
230 MediaKeys::TEMPORARY_SESSION);
231 ExtractSessionTypeAndExpect(
232 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
233 "\"temporary\"}",
234 true,
235 MediaKeys::TEMPORARY_SESSION);
236 ExtractSessionTypeAndExpect(
237 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
238 "\"persistent\"}",
239 true,
240 MediaKeys::PERSISTENT_SESSION);
241 ExtractSessionTypeAndExpect(
242 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
243 "\"unknown\"}",
244 false,
245 MediaKeys::TEMPORARY_SESSION);
246 ExtractSessionTypeAndExpect(
247 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":3}",
248 false,
249 MediaKeys::TEMPORARY_SESSION);
252 TEST_F(JSONWebKeyTest, CreateLicense) {
253 const uint8 data1[] = { 0x01, 0x02 };
254 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
255 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
256 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
258 CreateLicenseAndExpect(data1,
259 arraysize(data1),
260 MediaKeys::TEMPORARY_SESSION,
261 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}");
262 CreateLicenseAndExpect(data1,
263 arraysize(data1),
264 MediaKeys::PERSISTENT_SESSION,
265 "{\"kids\":[\"AQI\"],\"type\":\"persistent\"}");
266 CreateLicenseAndExpect(data2,
267 arraysize(data2),
268 MediaKeys::TEMPORARY_SESSION,
269 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}");
270 CreateLicenseAndExpect(
271 data3,
272 arraysize(data3),
273 MediaKeys::PERSISTENT_SESSION,
274 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":\"persistent\"}");
277 TEST_F(JSONWebKeyTest, ExtractLicense) {
278 const uint8 data1[] = { 0x01, 0x02 };
279 const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
280 const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
281 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
283 ExtractKeyFromLicenseAndExpect(
284 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}",
285 true,
286 data1,
287 arraysize(data1));
288 ExtractKeyFromLicenseAndExpect(
289 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}",
290 true,
291 data2,
292 arraysize(data2));
293 ExtractKeyFromLicenseAndExpect(
294 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":\"persistent\"}",
295 true,
296 data3,
297 arraysize(data3));
299 // Try some incorrect JSON.
300 ExtractKeyFromLicenseAndExpect("", false, NULL, 0);
301 ExtractKeyFromLicenseAndExpect("!@#$%^&*()", false, NULL, 0);
303 // Valid JSON, but not a dictionary.
304 ExtractKeyFromLicenseAndExpect("6", false, NULL, 0);
305 ExtractKeyFromLicenseAndExpect("[\"AQI\"]", false, NULL, 0);
307 // Dictionary, but missing expected tag.
308 ExtractKeyFromLicenseAndExpect("{\"kid\":[\"AQI\"]}", false, NULL, 0);
310 // Correct tag, but empty list.
311 ExtractKeyFromLicenseAndExpect("{\"kids\":[]}", false, NULL, 0);
313 // Correct tag, but list doesn't contain a string.
314 ExtractKeyFromLicenseAndExpect("{\"kids\":[[\"AQI\"]]}", false, NULL, 0);
316 // Correct tag, but invalid base64 encoding.
317 ExtractKeyFromLicenseAndExpect("{\"kids\":[\"!@#$%^&*()\"]}", false, NULL, 0);
320 } // namespace media