json_web_key_unittest.cc revision f2477e01787aa58f445919b809d89e252beef54f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/cdm/json_web_key.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class JSONWebKeyTest : public testing::Test { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 14ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch JSONWebKeyTest() {} 158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 16ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch protected: 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ExtractJWKKeysAndExpect(const std::string& jwk, 18ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool expected_result, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_number_of_keys) { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!jwk.empty()); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KeyIdAndKeyPairs keys; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_result, ExtractKeysFromJWKSet(jwk, &keys)); 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_number_of_keys, keys.size()); 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(JSONWebKeyTest, GenerateJWKSet) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8 data1[] = { 0x01, 0x02 }; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8 data2[] = { 0x01, 0x02, 0x03, 0x04 }; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8 data3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}", 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateJWKSet(data1, arraysize(data1), data1, arraysize(data1))); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ( 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}", 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateJWKSet(data2, arraysize(data2), data2, arraysize(data2))); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}]}", 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateJWKSet(data1, arraysize(data1), data2, arraysize(data2))); 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ("{\"keys\":[{\"k\":\"AQIDBA\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}", 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateJWKSet(data2, arraysize(data2), data1, arraysize(data1))); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ( 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{\"keys\":[{\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":\"oct\"}]}", 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateJWKSet(data3, arraysize(data3), data3, arraysize(data3))); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(JSONWebKeyTest, ExtractJWKKeys) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try a simple JWK key (i.e. not in a set) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kJwkSimple = 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{" 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"kty\": \"oct\"," 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\"," 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"k\": \"FBUWFxgZGhscHR4fICEiIw\"" 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}"; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractJWKKeysAndExpect(kJwkSimple, false, 0); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try a key list with multiple entries. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kJwksMultipleEntries = 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{" 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"keys\": [" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " {" 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kty\": \"oct\"," 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\"," 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"k\": \"FBUWFxgZGhscHR4fICEiIw\"" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }," 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " {" 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kty\": \"oct\"," 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kid\": \"JCUmJygpKissLS4vMA\"," 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\"" 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }" 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ]" 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}"; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractJWKKeysAndExpect(kJwksMultipleEntries, true, 2); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try a key with no spaces and some \n plus additional fields. 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string kJwksNoSpaces = 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\"," 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg" 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\",\"foo\":\"bar\"}]}\n\n"; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractJWKKeysAndExpect(kJwksNoSpaces, true, 1); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try some non-ASCII characters. 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtractJWKKeysAndExpect( 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "This is not ASCII due to \xff\xfe\xfd in it.", false, 0); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try some non-ASCII characters in an otherwise valid JWK. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kJwksInvalidCharacters = 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\"," 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"\xff\xfe\xfd" 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "\",\"foo\":\"bar\"}]}\n\n"; 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExtractJWKKeysAndExpect(kJwksInvalidCharacters, false, 0); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try a badly formatted key. Assume that the JSON parser is fully tested, 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // so we won't try a lot of combinations. However, need a test to ensure 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that the code doesn't crash if invalid JSON received. 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ExtractJWKKeysAndExpect("This is not a JSON key.", false, 0); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Try passing some valid JSON that is not a dictionary at the top level. 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ExtractJWKKeysAndExpect("40", false, 0); 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Try an empty dictionary. 103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ExtractJWKKeysAndExpect("{ }", false, 0); 104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Try an empty 'keys' dictionary. 106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ExtractJWKKeysAndExpect("{ \"keys\": [] }", true, 0); 107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Try with 'keys' not a dictionary. 109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ExtractJWKKeysAndExpect("{ \"keys\":\"1\" }", false, 0); 110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try with 'keys' a list of integers. 1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ExtractJWKKeysAndExpect("{ \"keys\": [ 1, 2, 3 ] }", false, 0); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try padding(=) at end of 'k' base64 string. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kJwksWithPaddedKey = 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{" 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"keys\": [" 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " {" 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kty\": \"oct\"," 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kid\": \"AAECAw\"," 1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\"" 1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) " }" 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ]" 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}"; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractJWKKeysAndExpect(kJwksWithPaddedKey, false, 0); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try padding(=) at end of 'kid' base64 string. 1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::string kJwksWithPaddedKeyId = 1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "{" 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"keys\": [" 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " {" 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kty\": \"oct\"," 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kid\": \"AAECAw==\"," 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\"" 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }" 1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) " ]" 1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "}"; 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ExtractJWKKeysAndExpect(kJwksWithPaddedKeyId, false, 0); 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Try a key with invalid base64 encoding. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kJwksWithInvalidBase64 = 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{" 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"keys\": [" 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " {" 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kty\": \"oct\"," 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kid\": \"!@#$%^&*()\"," 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\"" 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }" 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ]" 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}"; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractJWKKeysAndExpect(kJwksWithInvalidBase64, false, 0); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Empty key id. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kJwksWithEmptyKeyId = 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{" 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"keys\": [" 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " {" 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kty\": \"oct\"," 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kid\": \"\"," 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\"" 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }" 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ]" 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}"; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractJWKKeysAndExpect(kJwksWithEmptyKeyId, false, 0); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try a list with multiple keys with the same kid. 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string kJwksDuplicateKids = 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{" 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"keys\": [" 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " {" 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kty\": \"oct\"," 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"kid\": \"JCUmJygpKissLS4vMA\"," 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"k\": \"FBUWFxgZGhscHR4fICEiIw\"" 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }," 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " {" 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " \"kty\": \"oct\"," 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " \"kid\": \"JCUmJygpKissLS4vMA\"," 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\"" 179ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch " }" 180ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch " ]" 181ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "}"; 182ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ExtractJWKKeysAndExpect(kJwksDuplicateKids, true, 2); 183ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 184ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 185ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace media 186ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 187ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch