diff options
Diffstat (limited to 'chromium/media/cdm/json_web_key_unittest.cc')
-rw-r--r-- | chromium/media/cdm/json_web_key_unittest.cc | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/chromium/media/cdm/json_web_key_unittest.cc b/chromium/media/cdm/json_web_key_unittest.cc new file mode 100644 index 00000000000..1018d173c76 --- /dev/null +++ b/chromium/media/cdm/json_web_key_unittest.cc @@ -0,0 +1,186 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/cdm/json_web_key.h" + +#include "base/logging.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media { + +class JSONWebKeyTest : public testing::Test { + public: + JSONWebKeyTest() {} + + protected: + void ExtractJWKKeysAndExpect(const std::string& jwk, + bool expected_result, + size_t expected_number_of_keys) { + DCHECK(!jwk.empty()); + KeyIdAndKeyPairs keys; + EXPECT_EQ(expected_result, ExtractKeysFromJWKSet(jwk, &keys)); + EXPECT_EQ(expected_number_of_keys, keys.size()); + } +}; + +TEST_F(JSONWebKeyTest, GenerateJWKSet) { + const uint8 data1[] = { 0x01, 0x02 }; + const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 }; + const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }; + + EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}", + GenerateJWKSet(data1, arraysize(data1), data1, arraysize(data1))); + EXPECT_EQ( + "{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}", + GenerateJWKSet(data2, arraysize(data2), data2, arraysize(data2))); + EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}", + GenerateJWKSet(data1, arraysize(data1), data2, arraysize(data2))); + EXPECT_EQ("{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}", + GenerateJWKSet(data2, arraysize(data2), data1, arraysize(data1))); + EXPECT_EQ( + "{\"keys\":[{\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":" + "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":\"oct\"}]}", + GenerateJWKSet(data3, arraysize(data3), data3, arraysize(data3))); +} + +TEST_F(JSONWebKeyTest, ExtractJWKKeys) { + // Try a simple JWK key (i.e. not in a set) + const std::string kJwkSimple = + "{" + " \"kty\": \"oct\"," + " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\"," + " \"k\": \"FBUWFxgZGhscHR4fICEiIw\"" + "}"; + ExtractJWKKeysAndExpect(kJwkSimple, false, 0); + + // Try a key list with multiple entries. + const std::string kJwksMultipleEntries = + "{" + " \"keys\": [" + " {" + " \"kty\": \"oct\"," + " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\"," + " \"k\": \"FBUWFxgZGhscHR4fICEiIw\"" + " }," + " {" + " \"kty\": \"oct\"," + " \"kid\": \"JCUmJygpKissLS4vMA\"," + " \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\"" + " }" + " ]" + "}"; + ExtractJWKKeysAndExpect(kJwksMultipleEntries, true, 2); + + // Try a key with no spaces and some \n plus additional fields. + const std::string kJwksNoSpaces = + "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\"," + "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg" + "\",\"foo\":\"bar\"}]}\n\n"; + ExtractJWKKeysAndExpect(kJwksNoSpaces, true, 1); + + // Try some non-ASCII characters. + ExtractJWKKeysAndExpect( + "This is not ASCII due to \xff\xfe\xfd in it.", false, 0); + + // Try some non-ASCII characters in an otherwise valid JWK. + const std::string kJwksInvalidCharacters = + "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\"," + "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"\xff\xfe\xfd" + "\",\"foo\":\"bar\"}]}\n\n"; + ExtractJWKKeysAndExpect(kJwksInvalidCharacters, false, 0); + + // Try a badly formatted key. Assume that the JSON parser is fully tested, + // so we won't try a lot of combinations. However, need a test to ensure + // that the code doesn't crash if invalid JSON received. + ExtractJWKKeysAndExpect("This is not a JSON key.", false, 0); + + // Try passing some valid JSON that is not a dictionary at the top level. + ExtractJWKKeysAndExpect("40", false, 0); + + // Try an empty dictionary. + ExtractJWKKeysAndExpect("{ }", false, 0); + + // Try an empty 'keys' dictionary. + ExtractJWKKeysAndExpect("{ \"keys\": [] }", true, 0); + + // Try with 'keys' not a dictionary. + ExtractJWKKeysAndExpect("{ \"keys\":\"1\" }", false, 0); + + // Try with 'keys' a list of integers. + ExtractJWKKeysAndExpect("{ \"keys\": [ 1, 2, 3 ] }", false, 0); + + // Try padding(=) at end of 'k' base64 string. + const std::string kJwksWithPaddedKey = + "{" + " \"keys\": [" + " {" + " \"kty\": \"oct\"," + " \"kid\": \"AAECAw\"," + " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\"" + " }" + " ]" + "}"; + ExtractJWKKeysAndExpect(kJwksWithPaddedKey, false, 0); + + // Try padding(=) at end of 'kid' base64 string. + const std::string kJwksWithPaddedKeyId = + "{" + " \"keys\": [" + " {" + " \"kty\": \"oct\"," + " \"kid\": \"AAECAw==\"," + " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\"" + " }" + " ]" + "}"; + ExtractJWKKeysAndExpect(kJwksWithPaddedKeyId, false, 0); + + // Try a key with invalid base64 encoding. + const std::string kJwksWithInvalidBase64 = + "{" + " \"keys\": [" + " {" + " \"kty\": \"oct\"," + " \"kid\": \"!@#$%^&*()\"," + " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\"" + " }" + " ]" + "}"; + ExtractJWKKeysAndExpect(kJwksWithInvalidBase64, false, 0); + + // Empty key id. + const std::string kJwksWithEmptyKeyId = + "{" + " \"keys\": [" + " {" + " \"kty\": \"oct\"," + " \"kid\": \"\"," + " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\"" + " }" + " ]" + "}"; + ExtractJWKKeysAndExpect(kJwksWithEmptyKeyId, false, 0); + + // Try a list with multiple keys with the same kid. + const std::string kJwksDuplicateKids = + "{" + " \"keys\": [" + " {" + " \"kty\": \"oct\"," + " \"kid\": \"JCUmJygpKissLS4vMA\"," + " \"k\": \"FBUWFxgZGhscHR4fICEiIw\"" + " }," + " {" + " \"kty\": \"oct\"," + " \"kid\": \"JCUmJygpKissLS4vMA\"," + " \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\"" + " }" + " ]" + "}"; + ExtractJWKKeysAndExpect(kJwksDuplicateKids, true, 2); +} + +} // namespace media + |