• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "media/cdm/json_web_key.h"
6 
7 #include "base/logging.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 
10 namespace media {
11 
12 class JSONWebKeyTest : public testing::Test {
13  public:
JSONWebKeyTest()14   JSONWebKeyTest() {}
15 
16  protected:
ExtractJWKKeysAndExpect(const std::string & jwk,bool expected_result,size_t expected_number_of_keys)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     EXPECT_EQ(expected_result, ExtractKeysFromJWKSet(jwk, &keys));
23     EXPECT_EQ(expected_number_of_keys, keys.size());
24   }
25 };
26 
TEST_F(JSONWebKeyTest,GenerateJWKSet)27 TEST_F(JSONWebKeyTest, GenerateJWKSet) {
28   const uint8 data1[] = { 0x01, 0x02 };
29   const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 };
30   const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
31                           0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 };
32 
33   EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
34             GenerateJWKSet(data1, arraysize(data1), data1, arraysize(data1)));
35   EXPECT_EQ(
36       "{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}",
37       GenerateJWKSet(data2, arraysize(data2), data2, arraysize(data2)));
38   EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}",
39             GenerateJWKSet(data1, arraysize(data1), data2, arraysize(data2)));
40   EXPECT_EQ("{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}",
41             GenerateJWKSet(data2, arraysize(data2), data1, arraysize(data1)));
42   EXPECT_EQ(
43       "{\"keys\":[{\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":"
44       "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":\"oct\"}]}",
45       GenerateJWKSet(data3, arraysize(data3), data3, arraysize(data3)));
46 }
47 
TEST_F(JSONWebKeyTest,ExtractJWKKeys)48 TEST_F(JSONWebKeyTest, ExtractJWKKeys) {
49   // Try a simple JWK key (i.e. not in a set)
50   const std::string kJwkSimple =
51       "{"
52       "  \"kty\": \"oct\","
53       "  \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
54       "  \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
55       "}";
56   ExtractJWKKeysAndExpect(kJwkSimple, false, 0);
57 
58   // Try a key list with multiple entries.
59   const std::string kJwksMultipleEntries =
60       "{"
61       "  \"keys\": ["
62       "    {"
63       "      \"kty\": \"oct\","
64       "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
65       "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
66       "    },"
67       "    {"
68       "      \"kty\": \"oct\","
69       "      \"kid\": \"JCUmJygpKissLS4vMA\","
70       "      \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\""
71       "    }"
72       "  ]"
73       "}";
74   ExtractJWKKeysAndExpect(kJwksMultipleEntries, true, 2);
75 
76   // Try a key with no spaces and some \n plus additional fields.
77   const std::string kJwksNoSpaces =
78       "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\","
79       "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg"
80       "\",\"foo\":\"bar\"}]}\n\n";
81   ExtractJWKKeysAndExpect(kJwksNoSpaces, true, 1);
82 
83   // Try some non-ASCII characters.
84   ExtractJWKKeysAndExpect(
85       "This is not ASCII due to \xff\xfe\xfd in it.", false, 0);
86 
87   // Try some non-ASCII characters in an otherwise valid JWK.
88   const std::string kJwksInvalidCharacters =
89       "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\","
90       "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"\xff\xfe\xfd"
91       "\",\"foo\":\"bar\"}]}\n\n";
92   ExtractJWKKeysAndExpect(kJwksInvalidCharacters, false, 0);
93 
94   // Try a badly formatted key. Assume that the JSON parser is fully tested,
95   // so we won't try a lot of combinations. However, need a test to ensure
96   // that the code doesn't crash if invalid JSON received.
97   ExtractJWKKeysAndExpect("This is not a JSON key.", false, 0);
98 
99   // Try passing some valid JSON that is not a dictionary at the top level.
100   ExtractJWKKeysAndExpect("40", false, 0);
101 
102   // Try an empty dictionary.
103   ExtractJWKKeysAndExpect("{ }", false, 0);
104 
105   // Try an empty 'keys' dictionary.
106   ExtractJWKKeysAndExpect("{ \"keys\": [] }", true, 0);
107 
108   // Try with 'keys' not a dictionary.
109   ExtractJWKKeysAndExpect("{ \"keys\":\"1\" }", false, 0);
110 
111   // Try with 'keys' a list of integers.
112   ExtractJWKKeysAndExpect("{ \"keys\": [ 1, 2, 3 ] }", false, 0);
113 
114   // Try padding(=) at end of 'k' base64 string.
115   const std::string kJwksWithPaddedKey =
116       "{"
117       "  \"keys\": ["
118       "    {"
119       "      \"kty\": \"oct\","
120       "      \"kid\": \"AAECAw\","
121       "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
122       "    }"
123       "  ]"
124       "}";
125   ExtractJWKKeysAndExpect(kJwksWithPaddedKey, false, 0);
126 
127   // Try padding(=) at end of 'kid' base64 string.
128   const std::string kJwksWithPaddedKeyId =
129       "{"
130       "  \"keys\": ["
131       "    {"
132       "      \"kty\": \"oct\","
133       "      \"kid\": \"AAECAw==\","
134       "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
135       "    }"
136       "  ]"
137       "}";
138   ExtractJWKKeysAndExpect(kJwksWithPaddedKeyId, false, 0);
139 
140   // Try a key with invalid base64 encoding.
141   const std::string kJwksWithInvalidBase64 =
142       "{"
143       "  \"keys\": ["
144       "    {"
145       "      \"kty\": \"oct\","
146       "      \"kid\": \"!@#$%^&*()\","
147       "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
148       "    }"
149       "  ]"
150       "}";
151   ExtractJWKKeysAndExpect(kJwksWithInvalidBase64, false, 0);
152 
153   // Empty key id.
154   const std::string kJwksWithEmptyKeyId =
155       "{"
156       "  \"keys\": ["
157       "    {"
158       "      \"kty\": \"oct\","
159       "      \"kid\": \"\","
160       "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
161       "    }"
162       "  ]"
163       "}";
164   ExtractJWKKeysAndExpect(kJwksWithEmptyKeyId, false, 0);
165 
166   // Try a list with multiple keys with the same kid.
167   const std::string kJwksDuplicateKids =
168       "{"
169       "  \"keys\": ["
170       "    {"
171       "      \"kty\": \"oct\","
172       "      \"kid\": \"JCUmJygpKissLS4vMA\","
173       "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
174       "    },"
175       "    {"
176       "      \"kty\": \"oct\","
177       "      \"kid\": \"JCUmJygpKissLS4vMA\","
178       "      \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\""
179       "    }"
180       "  ]"
181       "}";
182   ExtractJWKKeysAndExpect(kJwksDuplicateKids, true, 2);
183 }
184 
185 }  // namespace media
186 
187