1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include <arpa/inet.h> 17094332d3Sopenharmony_ci#include <hdf_base.h> 18094332d3Sopenharmony_ci#include <hdf_log.h> 19094332d3Sopenharmony_ci#include <string> 20094332d3Sopenharmony_ci#include "clearplay_uuid.h" 21094332d3Sopenharmony_ci#include "mime_type.h" 22094332d3Sopenharmony_ci#include "base64_utils.h" 23094332d3Sopenharmony_ci#include "data_parser.h" 24094332d3Sopenharmony_ci#include "cJSON.h" 25094332d3Sopenharmony_ci#include "securec.h" 26094332d3Sopenharmony_ci 27094332d3Sopenharmony_ci#define HDF_LOG_TAG data_parse 28094332d3Sopenharmony_ci 29094332d3Sopenharmony_cinamespace OHOS { 30094332d3Sopenharmony_cinamespace HDI { 31094332d3Sopenharmony_cinamespace Drm { 32094332d3Sopenharmony_cinamespace V1_0 { 33094332d3Sopenharmony_ciint32_t ParsePssh(const std::vector<uint8_t> &initData, std::vector<std::vector<uint8_t>> &keyIds) 34094332d3Sopenharmony_ci{ 35094332d3Sopenharmony_ci HDF_LOGD("%{public}s: start", __func__); 36094332d3Sopenharmony_ci size_t readPosition = 0; 37094332d3Sopenharmony_ci 38094332d3Sopenharmony_ci // Validate size field 39094332d3Sopenharmony_ci uint32_t expectedSize = initData.size(); 40094332d3Sopenharmony_ci expectedSize = htonl(expectedSize); 41094332d3Sopenharmony_ci if (memcmp(&initData[readPosition], &expectedSize, sizeof(expectedSize)) != 0) { 42094332d3Sopenharmony_ci HDF_LOGD("%{public}s: memcmp(&initData[readPosition], &expectedSize, sizeof(expectedSize)) != 0", __func__); 43094332d3Sopenharmony_ci } 44094332d3Sopenharmony_ci readPosition += sizeof(expectedSize); 45094332d3Sopenharmony_ci 46094332d3Sopenharmony_ci // Validate PSSH box identifier 47094332d3Sopenharmony_ci const char psshIdentifier[4] = {'p', 's', 's', 'h'}; 48094332d3Sopenharmony_ci if (memcmp(&initData[readPosition], psshIdentifier, sizeof(psshIdentifier)) != 0) { 49094332d3Sopenharmony_ci HDF_LOGD("%{public}s: without \"pssh\"", __func__); 50094332d3Sopenharmony_ci } 51094332d3Sopenharmony_ci readPosition += sizeof(psshIdentifier); 52094332d3Sopenharmony_ci 53094332d3Sopenharmony_ci // Validate EME version number 54094332d3Sopenharmony_ci const uint8_t psshVersion1[4] = {1, 0, 0, 0}; 55094332d3Sopenharmony_ci const uint8_t psshVersion0[4] = {0, 0, 0, 0}; 56094332d3Sopenharmony_ci int psshVersionId = 0; 57094332d3Sopenharmony_ci if (memcmp(&initData[readPosition], psshVersion0, sizeof(psshVersion0)) != 0) { 58094332d3Sopenharmony_ci if (memcmp(&initData[readPosition], psshVersion1, sizeof(psshVersion1)) != 0) { 59094332d3Sopenharmony_ci HDF_LOGD("%{public}s: psshVersion error", __func__); 60094332d3Sopenharmony_ci } 61094332d3Sopenharmony_ci psshVersionId = 1; 62094332d3Sopenharmony_ci } 63094332d3Sopenharmony_ci readPosition += sizeof(psshVersion1); 64094332d3Sopenharmony_ci 65094332d3Sopenharmony_ci // Validate system ID 66094332d3Sopenharmony_ci std::string uuid((reinterpret_cast<const char*>(initData.data())) + readPosition, CLEARPLAY_NAME.size()); 67094332d3Sopenharmony_ci if (IsClearPlayUuid(uuid)) { 68094332d3Sopenharmony_ci HDF_LOGD("%{public}s: uuid error", __func__); 69094332d3Sopenharmony_ci } 70094332d3Sopenharmony_ci readPosition += SYSTEM_ID_SIZE; 71094332d3Sopenharmony_ci 72094332d3Sopenharmony_ci if (psshVersionId == 0) { 73094332d3Sopenharmony_ci std::vector<uint8_t> keyIdString = { 'k', 'i', 'd', 's' }; 74094332d3Sopenharmony_ci int32_t keyIdPos = findSubVector(initData, keyIdString); 75094332d3Sopenharmony_ci if (keyIdPos == -1) { 76094332d3Sopenharmony_ci HDF_LOGD("%{public}s: without \"kids\"", __func__); 77094332d3Sopenharmony_ci } 78094332d3Sopenharmony_ci while (keyIdPos < initData.size() && initData[keyIdPos] != '[') { 79094332d3Sopenharmony_ci ++keyIdPos; 80094332d3Sopenharmony_ci } 81094332d3Sopenharmony_ci std::string keyIdBase64 = ""; 82094332d3Sopenharmony_ci bool isLeft = false; 83094332d3Sopenharmony_ci while (keyIdPos < initData.size() && initData[keyIdPos] != ']') { 84094332d3Sopenharmony_ci if (initData[keyIdPos] == '"') { 85094332d3Sopenharmony_ci isLeft = !isLeft; 86094332d3Sopenharmony_ci if (!isLeft) { 87094332d3Sopenharmony_ci std::string keyIdString = Decode(keyIdBase64); 88094332d3Sopenharmony_ci keyIdBase64 = ""; 89094332d3Sopenharmony_ci std::vector<uint8_t> keyId(keyIdString.begin(), keyIdString.end()); 90094332d3Sopenharmony_ci keyIds.push_back(keyId); 91094332d3Sopenharmony_ci } 92094332d3Sopenharmony_ci } else if (isLeft) { 93094332d3Sopenharmony_ci keyIdBase64 += initData[keyIdPos]; 94094332d3Sopenharmony_ci } 95094332d3Sopenharmony_ci ++keyIdPos; 96094332d3Sopenharmony_ci } 97094332d3Sopenharmony_ci if (keyIdPos == initData.size()) { 98094332d3Sopenharmony_ci HDF_LOGD("%{public}s: kids parse error", __func__); 99094332d3Sopenharmony_ci } 100094332d3Sopenharmony_ci } else if (psshVersionId == 1) { 101094332d3Sopenharmony_ci // Read key ID count 102094332d3Sopenharmony_ci uint32_t keyIdCount; 103094332d3Sopenharmony_ci int32_t ret = HDF_FAILURE; 104094332d3Sopenharmony_ci ret = memcpy_s(&keyIdCount, sizeof(keyIdCount), &initData[readPosition], sizeof(keyIdCount)); 105094332d3Sopenharmony_ci if(ret != 0) { 106094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s faild", __func__); 107094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 108094332d3Sopenharmony_ci } 109094332d3Sopenharmony_ci keyIdCount = ntohl(keyIdCount); 110094332d3Sopenharmony_ci readPosition += sizeof(keyIdCount); 111094332d3Sopenharmony_ci 112094332d3Sopenharmony_ci // Calculate the key ID offsets 113094332d3Sopenharmony_ci for (uint32_t i = 0; i < keyIdCount; ++i) { 114094332d3Sopenharmony_ci std::vector<uint8_t> keyId; 115094332d3Sopenharmony_ci for (size_t j = 0; i < KEY_ID_SIZE; ++j) { 116094332d3Sopenharmony_ci keyId.push_back(initData[readPosition + i * KEY_ID_SIZE + j]); 117094332d3Sopenharmony_ci } 118094332d3Sopenharmony_ci keyIds.push_back(keyId); 119094332d3Sopenharmony_ci } 120094332d3Sopenharmony_ci } 121094332d3Sopenharmony_ci return HDF_SUCCESS; 122094332d3Sopenharmony_ci} 123094332d3Sopenharmony_ci 124094332d3Sopenharmony_ciint32_t generateRequest(const MediaKeyType keyType, const std::vector<std::vector<uint8_t>> &keyIds, 125094332d3Sopenharmony_ci std::string *request) 126094332d3Sopenharmony_ci{ 127094332d3Sopenharmony_ci // begin 128094332d3Sopenharmony_ci *request = "{\"kids\":["; 129094332d3Sopenharmony_ci std::string encodedKeyId; 130094332d3Sopenharmony_ci for (size_t i = 0; i < keyIds.size(); ++i) { 131094332d3Sopenharmony_ci encodedKeyId.clear(); 132094332d3Sopenharmony_ci std::string keyId(keyIds[i].begin(), keyIds[i].end()); 133094332d3Sopenharmony_ci encodedKeyId = Encode(keyId); 134094332d3Sopenharmony_ci if (i != 0) { 135094332d3Sopenharmony_ci request->append(","); 136094332d3Sopenharmony_ci } 137094332d3Sopenharmony_ci request->append("\""); 138094332d3Sopenharmony_ci request->append(encodedKeyId); 139094332d3Sopenharmony_ci request->append("\""); 140094332d3Sopenharmony_ci } 141094332d3Sopenharmony_ci if (keyType == MEDIA_KEY_TYPE_ONLINE) { 142094332d3Sopenharmony_ci request->append("],\"type\":\"temporary\"}"); 143094332d3Sopenharmony_ci } else if (keyType == MEDIA_KEY_TYPE_OFFLINE) { 144094332d3Sopenharmony_ci request->append("],\"type\":\"persistent-license\"}"); 145094332d3Sopenharmony_ci } else { 146094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 147094332d3Sopenharmony_ci } 148094332d3Sopenharmony_ci return HDF_SUCCESS; 149094332d3Sopenharmony_ci} 150094332d3Sopenharmony_ci 151094332d3Sopenharmony_ciint32_t findSubVector(const std::vector<uint8_t> &main, const std::vector<uint8_t> &sub) 152094332d3Sopenharmony_ci{ 153094332d3Sopenharmony_ci for (size_t i = 0; i < main.size(); ++i) { 154094332d3Sopenharmony_ci size_t j = 0; 155094332d3Sopenharmony_ci for (j = 0; j < sub.size() && main[i + j] == sub[j]; ++j) { 156094332d3Sopenharmony_ci } 157094332d3Sopenharmony_ci // for j end 158094332d3Sopenharmony_ci if (j == sub.size()) { 159094332d3Sopenharmony_ci return i; 160094332d3Sopenharmony_ci } 161094332d3Sopenharmony_ci } 162094332d3Sopenharmony_ci return -1; 163094332d3Sopenharmony_ci} 164094332d3Sopenharmony_ci} // V1_0 165094332d3Sopenharmony_ci} // Drm 166094332d3Sopenharmony_ci} // HDI 167094332d3Sopenharmony_ci} // OHOS