17bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong/* 21917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * Copyright (C) 2018 The Android Open Source Project 37bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * 47bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * Licensed under the Apache License, Version 2.0 (the "License"); 57bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * you may not use this file except in compliance with the License. 67bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * You may obtain a copy of the License at 77bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * 87bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * http://www.apache.org/licenses/LICENSE-2.0 97bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * 107bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * Unless required by applicable law or agreed to in writing, software 117bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * distributed under the License is distributed on an "AS IS" BASIS, 127bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * See the License for the specific language governing permissions and 147bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * limitations under the License. 157bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong */ 161917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#define LOG_TAG "hidl_JsonWebKey" 177bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 187bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong#include <utils/Log.h> 197bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 207bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong#include "JsonWebKey.h" 217bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 221917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#include "Base64.h" 231917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 247bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wongnamespace { 251917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerconst std::string kKeysTag("keys"); 261917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerconst std::string kKeyTypeTag("kty"); 271917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerconst std::string kSymmetricKeyValue("oct"); 281917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerconst std::string kKeyTag("k"); 291917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerconst std::string kKeyIdTag("kid"); 301917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerconst std::string kBase64Padding("="); 317bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong} 327bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 331917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace android { 341917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace hardware { 351917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace drm { 361917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace V1_1 { 371917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace clearkey { 387bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 397bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin WongJsonWebKey::JsonWebKey() { 407bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong} 417bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 427bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin WongJsonWebKey::~JsonWebKey() { 437bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong} 447bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 457bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong/* 467bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * Parses a JSON Web Key Set string, initializes a KeyMap with key id:key 477bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * pairs from the JSON Web Key Set. Both key ids and keys are base64url 487bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * encoded. The KeyMap contains base64url decoded key id:key pairs. 497bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * 507bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * @return Returns false for errors, true for success. 517bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong */ 521917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerbool JsonWebKey::extractKeysFromJsonWebKeySet(const std::string& jsonWebKeySet, 537bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong KeyMap* keys) { 547bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 557bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong keys->clear(); 561917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 577bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (!parseJsonWebKeySet(jsonWebKeySet, &mJsonObjects)) { 587bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 597bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 607bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 617bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong // mJsonObjects[0] contains the entire JSON Web Key Set, including 627bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong // all the base64 encoded keys. Each key is also stored separately as 637bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong // a JSON object in mJsonObjects[1..n] where n is the total 647bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong // number of keys in the set. 657bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (!isJsonWebKeySet(mJsonObjects[0])) { 667bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 677bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 687bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 691917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker std::string encodedKey, encodedKeyId; 701917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker std::vector<uint8_t> decodedKey, decodedKeyId; 717bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 727bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong // mJsonObjects[1] contains the first JSON Web Key in the set 737bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong for (size_t i = 1; i < mJsonObjects.size(); ++i) { 747bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong encodedKeyId.clear(); 757bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong encodedKey.clear(); 767bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 777bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (!parseJsonObject(mJsonObjects[i], &mTokens)) 787bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 797bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 807bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (findKey(mJsonObjects[i], &encodedKeyId, &encodedKey)) { 811917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (encodedKeyId.empty() || encodedKey.empty()) { 827bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong ALOGE("Must have both key id and key in the JsonWebKey set."); 837bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong continue; 847bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 857bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 867bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (!decodeBase64String(encodedKeyId, &decodedKeyId)) { 871917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker ALOGE("Failed to decode key id(%s)", encodedKeyId.c_str()); 887bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong continue; 897bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 907bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 917bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (!decodeBase64String(encodedKey, &decodedKey)) { 921917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker ALOGE("Failed to decode key(%s)", encodedKey.c_str()); 937bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong continue; 947bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 957bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 961917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker keys->insert(std::pair<std::vector<uint8_t>, 971917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker std::vector<uint8_t> >(decodedKeyId, decodedKey)); 987bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 997bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1007bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return true; 1017bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong} 1027bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1031917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerbool JsonWebKey::decodeBase64String(const std::string& encodedText, 1041917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker std::vector<uint8_t>* decodedText) { 1057bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1067bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong decodedText->clear(); 1077bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1087bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong // encodedText should not contain padding characters as per EME spec. 1091917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (encodedText.find(kBase64Padding) != std::string::npos) { 1107bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 1117bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1127bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1131917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker // Since decodeBase64() requires padding characters, 1147bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong // add them so length of encodedText is exactly a multiple of 4. 1157bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong int remainder = encodedText.length() % 4; 1161917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker std::string paddedText(encodedText); 1177bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (remainder > 0) { 1187bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong for (int i = 0; i < 4 - remainder; ++i) { 1197bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong paddedText.append(kBase64Padding); 1207bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1217bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1227bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1231917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker sp<Buffer> buffer = decodeBase64(paddedText); 1241917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (buffer == nullptr) { 1257bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong ALOGE("Malformed base64 encoded content found."); 1267bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 1277bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1287bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1291917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker decodedText->insert(decodedText->end(), buffer->base(), buffer->base() + buffer->size()); 1307bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return true; 1317bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong} 1327bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1331917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerbool JsonWebKey::findKey(const std::string& jsonObject, std::string* keyId, 1341917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker std::string* encodedKey) { 1357bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1361917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker std::string key, value; 1377bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1387bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong // Only allow symmetric key, i.e. "kty":"oct" pair. 1391917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (jsonObject.find(kKeyTypeTag) != std::string::npos) { 1407bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong findValue(kKeyTypeTag, &value); 1417bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (0 != value.compare(kSymmetricKeyValue)) 1427bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 1437bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1447bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1451917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (jsonObject.find(kKeyIdTag) != std::string::npos) { 1467bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong findValue(kKeyIdTag, keyId); 1477bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1487bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1491917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (jsonObject.find(kKeyTag) != std::string::npos) { 1507bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong findValue(kKeyTag, encodedKey); 1517bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1527bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return true; 1537bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong} 1547bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1551917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkervoid JsonWebKey::findValue(const std::string &key, std::string* value) { 1567bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong value->clear(); 1577bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong const char* valueToken; 1581917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker for (std::vector<std::string>::const_iterator nextToken = mTokens.begin(); 1597bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong nextToken != mTokens.end(); ++nextToken) { 1607bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (0 == (*nextToken).compare(key)) { 1617bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (nextToken + 1 == mTokens.end()) 1627bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong break; 1631917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker valueToken = (*(nextToken + 1)).c_str(); 1641917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker value->assign(valueToken); 1657bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong nextToken++; 1667bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong break; 1677bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1687bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1697bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong} 1707bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1711917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerbool JsonWebKey::isJsonWebKeySet(const std::string& jsonObject) const { 1721917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (jsonObject.find(kKeysTag) == std::string::npos) { 1737bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong ALOGE("JSON Web Key does not contain keys."); 1747bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 1757bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1767bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return true; 1777bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong} 1787bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1797bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong/* 1807bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * Parses a JSON objects string and initializes a vector of tokens. 1817bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * 1827bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * @return Returns false for errors, true for success. 1837bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong */ 1841917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerbool JsonWebKey::parseJsonObject(const std::string& jsonObject, 1851917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker std::vector<std::string>* tokens) { 1867bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong jsmn_parser parser; 1877bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1887bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong jsmn_init(&parser); 1897bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong int numTokens = jsmn_parse(&parser, 1901917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker jsonObject.c_str(), jsonObject.size(), nullptr, 0); 1917bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (numTokens < 0) { 1927bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong ALOGE("Parser returns error code=%d", numTokens); 1937bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 1947bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 1957bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 1967bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong unsigned int jsmnTokensSize = numTokens * sizeof(jsmntok_t); 1977bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong mJsmnTokens.clear(); 1981917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker mJsmnTokens.resize(jsmnTokensSize); 1997bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 2007bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong jsmn_init(&parser); 2011917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker int status = jsmn_parse(&parser, jsonObject.c_str(), 2021917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker jsonObject.size(), mJsmnTokens.data(), numTokens); 2037bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (status < 0) { 2047bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong ALOGE("Parser returns error code=%d", status); 2057bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 2067bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 2077bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 2087bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong tokens->clear(); 2091917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker std::string token; 2107bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong const char *pjs; 2117bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong for (int j = 0; j < numTokens; ++j) { 2121917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker pjs = jsonObject.c_str() + mJsmnTokens[j].start; 2137bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (mJsmnTokens[j].type == JSMN_STRING || 2147bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong mJsmnTokens[j].type == JSMN_PRIMITIVE) { 2151917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker token.assign(pjs, mJsmnTokens[j].end - mJsmnTokens[j].start); 2161917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker tokens->push_back(token); 2177bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 2187bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 2197bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return true; 2207bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong} 2217bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 2227bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong/* 2237bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * Parses JSON Web Key Set string and initializes a vector of JSON objects. 2247bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * 2257bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong * @return Returns false for errors, true for success. 2267bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong */ 2271917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerbool JsonWebKey::parseJsonWebKeySet(const std::string& jsonWebKeySet, 2281917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker std::vector<std::string>* jsonObjects) { 2291917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (jsonWebKeySet.empty()) { 2307bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong ALOGE("Empty JSON Web Key"); 2317bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 2327bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 2337bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 2347bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong // The jsmn parser only supports unicode encoding. 2357bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong jsmn_parser parser; 2367bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 2377bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong // Computes number of tokens. A token marks the type, offset in 2387bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong // the original string. 2397bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong jsmn_init(&parser); 2407bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong int numTokens = jsmn_parse(&parser, 2411917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker jsonWebKeySet.c_str(), jsonWebKeySet.size(), nullptr, 0); 2427bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (numTokens < 0) { 2437bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong ALOGE("Parser returns error code=%d", numTokens); 2447bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 2457bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 2467bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 2477bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong unsigned int jsmnTokensSize = numTokens * sizeof(jsmntok_t); 2481917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker mJsmnTokens.resize(jsmnTokensSize); 2497bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 2507bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong jsmn_init(&parser); 2511917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker int status = jsmn_parse(&parser, jsonWebKeySet.c_str(), 2521917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker jsonWebKeySet.size(), mJsmnTokens.data(), numTokens); 2537bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (status < 0) { 2547bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong ALOGE("Parser returns error code=%d", status); 2557bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return false; 2567bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 2577bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 2581917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker std::string token; 2597bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong const char *pjs; 2607bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong for (int i = 0; i < numTokens; ++i) { 2611917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker pjs = jsonWebKeySet.c_str() + mJsmnTokens[i].start; 2627bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong if (mJsmnTokens[i].type == JSMN_OBJECT) { 2631917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker token.assign(pjs, mJsmnTokens[i].end - mJsmnTokens[i].start); 2641917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker jsonObjects->push_back(token); 2657bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 2667bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong } 2677bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong return true; 2687bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong} 2697bdf28d2b83e527f474e96b0984d6a3f5eb457f7Edwin Wong 2701917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace clearkey 2711917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace V1_1 2721917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace drm 2731917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace hardware 2741917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace android 2751917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 276