/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "v1_0/media_key_system_service.h" #include "v1_0/media_key_session_service.h" #include "base64_utils.h" #include "data_parser.h" #include "securec.h" #define HDF_LOG_TAG media_key_system_service namespace OHOS { namespace HDI { namespace Drm { namespace V1_0 { MediaKeySystemService::~MediaKeySystemService() { HDF_LOGI("%{public}s: start", __func__); mediaKeySessionMutex_.lock(); while (mediaKeySessionMap_.size() > 0) { sptr keySession = mediaKeySessionMap_.begin()->first; mediaKeySessionMutex_.unlock(); CloseKeySessionService(keySession); mediaKeySessionMutex_.lock(); } mediaKeySessionMutex_.unlock(); HDF_LOGI("%{public}s: end", __func__); } int32_t MediaKeySystemService::GetConfigurationString(const std::string &name, std::string &value) { HDF_LOGI("%{public}s: start", __func__); if (configurationString_.find(name) == configurationString_.end()) { HDF_LOGE("%{public}s: do not find value, name: %{public}s", __func__, name.c_str()); return HDF_ERR_INVALID_PARAM; } value = configurationString_[name]; HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::SetConfigurationString(const std::string &name, const std::string &value) { HDF_LOGI("%{public}s: start", __func__); configurationString_[name] = value; HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::GetConfigurationByteArray(const std::string &name, std::vector &value) { HDF_LOGI("%{public}s: start", __func__); if (configuration_.find(name) == configuration_.end()) { HDF_LOGE("%{public}s: do not find value, name: %{public}s", __func__, name.c_str()); return HDF_ERR_INVALID_PARAM; } value = configuration_[name]; HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::SetConfigurationByteArray(const std::string &name, const std::vector &value) { HDF_LOGI("%{public}s: start", __func__); configuration_[name] = value; HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } void MediaKeySystemService::GetDecryptTimeAsString(std::vector> &topThreeTimes, std::string &decryptTimes) { for (auto &time : topThreeTimes) { if (!decryptTimes.empty()) { decryptTimes.append(";"); } for (auto it = time.begin(); it != time.end(); ++it) { if (it != time.begin()) { decryptTimes.append(","); } decryptTimes.append(std::to_string(*it)); } } } int32_t MediaKeySystemService::GetStatistics(std::map &statistics) { HDF_LOGI("%{public}s: start", __func__); mediaKeySessionMutex_.lock(); int sessionNum = mediaKeySessionMap_.size(); int decryptNumber = 0; int errorDecryptNumber = 0; std::vector> topThreeTimes; std::string decryptTimes; for (auto &pair : mediaKeySessionMap_) { decryptNumber += pair.first->GetDecryptNumber(); errorDecryptNumber += pair.first->GetErrorDecryptNumber(); std::vector topThreeTime; pair.first->GetDecryptTimes(topThreeTime); topThreeTimes.push_back(topThreeTime); } GetDecryptTimeAsString(topThreeTimes, decryptTimes); mediaKeySessionMutex_.unlock(); statistics[versionName] = "clearplay"; statistics[currentSessionNumName] = std::to_string(sessionNum); statistics[decryptNumberName] = std::to_string(decryptNumber); statistics[errorDecryptNumberName] = std::to_string(errorDecryptNumber); statistics[decryptTime] = decryptTimes; HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::GetMaxContentProtectionLevel(ContentProtectionLevel &level) { HDF_LOGI("%{public}s: start", __func__); level = OHOS::HDI::Drm::V1_0::ContentProtectionLevel::SW_SECURE_CRYPTO; HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::GenerateKeySystemRequest(std::string &defaultUrl, std::vector &request) { HDF_LOGI("%{public}s: start", __func__); defaultUrl = "http://default.com"; std::string requestData = "{\"signedRequest\":\"KEYREQUESTTYPE_DOWNLOADCERT\"}"; size_t requestDataLen = requestData.size(); request.assign(requestData.c_str(), requestData.c_str() + requestDataLen); if (vdiCallbackObj != nullptr) { std::string eventData = "PROVISIONRE QUIRED"; std::vector data(eventData.begin(), eventData.end()); vdiCallbackObj->SendEvent(EVENTTYPE_PROVISIONREQUIRED, 0, data); } HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::ProcessKeySystemResponse(const std::vector &response) { HDF_LOGI("%{public}s: start", __func__); std::string responseData(response.begin(), response.end()); HDF_LOGI("%{public}s: response: %{public}s", __func__, responseData.c_str()); HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::CreateMediaKeySession(ContentProtectionLevel level, sptr &keySession) { HDF_LOGI("%{public}s: start", __func__); HDF_LOGI("%{public}s: start, level: %d", __func__, level); sptr keySessionService = nullptr; keySessionService = new (std::nothrow) MediaKeySessionService(level); if (keySessionService == nullptr) { HDF_LOGE("MediaKeySystemService::CreateKeySession allocation failed"); return HDF_ERR_MALLOC_FAIL; } if (keySessionService->Init() != HDF_SUCCESS) { HDF_LOGE("keySessionService::Init() failed"); delete keySessionService; return HDF_ERR_MALLOC_FAIL; } keySessionService->SetKeySessionServiceCallback(this); mediaKeySessionMutex_.lock(); mediaKeySessionMap_[keySessionService] = true; mediaKeySessionMutex_.unlock(); keySession = keySessionService; HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::GetOfflineMediaKeyIds(std::vector> &licenseIds) { HDF_LOGI("%{public}s: start", __func__); offlineKeyMutex_.lock(); int32_t ret = GetOfflineKeyFromFile(); if (ret != HDF_SUCCESS) { offlineKeyMutex_.unlock(); return ret; } for (auto &keyIdValueBase64Pair : offlineKeyIdAndKeyValueBase64_) { std::string keyIdString = Decode(keyIdValueBase64Pair.first); std::vector keyId(keyIdString.begin(), keyIdString.end()); licenseIds.push_back(keyId); } offlineKeyIdAndKeyValueBase64_.clear(); offlineKeyMutex_.unlock(); HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::GetOfflineMediaKeyStatus(const std::vector &licenseId, OfflineMediaKeyStatus &licenseStatus) { HDF_LOGI("%{public}s: start", __func__); offlineKeyMutex_.lock(); std::string keyIdString(licenseId.begin(), licenseId.end()); std::string keyIdBase64 = Encode(keyIdString); int32_t ret = GetOfflineKeyFromFile(); if (ret != HDF_SUCCESS) { offlineKeyMutex_.unlock(); return ret; } keyIdBase64.erase(std::remove(keyIdBase64.begin(), keyIdBase64.end(), '\0'), keyIdBase64.end()); if (offlineKeyIdAndKeyValueBase64_.find(keyIdBase64) == offlineKeyIdAndKeyValueBase64_.end()) { licenseStatus = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN; offlineKeyMutex_.unlock(); return HDF_SUCCESS; } for (auto it = mediaKeySessionMap_.begin(); it != mediaKeySessionMap_.end(); ++it) { if (it->second == false) { continue; } licenseStatus = it->first->session_->keyIdStatusMap[licenseId]; } offlineKeyMutex_.unlock(); HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::ClearOfflineMediaKeys(const std::vector &licenseId) { HDF_LOGI("%{public}s: start", __func__); offlineKeyMutex_.lock(); int32_t ret = GetOfflineKeyFromFile(); if (ret != HDF_SUCCESS) { offlineKeyMutex_.unlock(); return ret; } std::string keyIdString(licenseId.begin(), licenseId.end()); std::string keyIdBase64 = Encode(keyIdString); auto it = offlineKeyIdAndKeyValueBase64_.find(keyIdBase64); if (it != offlineKeyIdAndKeyValueBase64_.end()) { offlineKeyIdAndKeyValueBase64_.erase(it); ret = SetOfflineKeyToFile(); if (ret != HDF_SUCCESS) { offlineKeyMutex_.unlock(); return ret; } for (auto it = mediaKeySessionMap_.begin(); it != mediaKeySessionMap_.end(); ++it) { if (it->second == false) { continue; } it->first->session_->keyIdStatusMap[licenseId] = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN; } offlineKeyMutex_.unlock(); HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } offlineKeyMutex_.unlock(); HDF_LOGI("%{public}s: do not find offline license, keyId: %{public}s", __func__, licenseId.data()); return HDF_FAILURE; } int32_t MediaKeySystemService::GetOemCertificate(sptr &oemCert) { HDF_LOGI("%{public}s: start", __func__); HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::GetOemCertificateStatus(CertificateStatus &status) { HDF_LOGI("%{public}s: start", __func__); HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::SetCallback(const sptr &systemCallback) { vdiCallbackObj = new (std::nothrow) MediaKeySystemCallbackService(systemCallback); if (vdiCallbackObj == nullptr) { HDF_LOGE("new MediaKeySystemCallbackService() failed"); return HDF_ERR_MALLOC_FAIL; } return HDF_SUCCESS; } int32_t MediaKeySystemService::Destroy() { HDF_LOGI("%{public}s: start", __func__); if (systemCallback_ != nullptr) { systemCallback_->CloseMediaKeySystemService(this); } systemCallback_ = nullptr; HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::CloseKeySessionService(sptr mediaKeySession) { HDF_LOGI("%{public}s: start", __func__); mediaKeySessionMutex_.lock(); auto it = mediaKeySessionMap_.find(mediaKeySession); if (it == mediaKeySessionMap_.end()) { mediaKeySessionMutex_.unlock(); return HDF_FAILURE; } mediaKeySessionMap_.erase(it); mediaKeySessionMutex_.unlock(); HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::SetKeySystemServiceCallback(sptr callback) { HDF_LOGI("%{public}s: start", __func__); if (callback == nullptr) { HDF_LOGE("MediaKeySystemServiceCallback callback is null"); return HDF_ERR_INVALID_PARAM; } systemCallback_ = callback; HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::GetOfflineKeyFromFile() { HDF_LOGI("%{public}s: start", __func__); FILE *offlineKeyFile = fopen(offlineKeyFileName, "r+"); if (offlineKeyFile == NULL) { HDF_LOGE("%{public}s: open: \"%{public}s\" failed", __func__, offlineKeyFileName); // file do not exist, is allright return HDF_SUCCESS; } char keyIdBase64Chars[keyIdMaxLength]; char keyValueBase64Chars[keyIdMaxLength]; while (fscanf_s(offlineKeyFile, "%s %s", keyIdBase64Chars, sizeof(keyIdBase64Chars), keyValueBase64Chars, sizeof(keyValueBase64Chars)) != EOF) { std::string tempKeyIdBase64 = keyIdBase64Chars; std::string tempKeyValueBase64 = keyValueBase64Chars; tempKeyIdBase64.erase(std::remove(tempKeyIdBase64.begin(), tempKeyIdBase64.end(), '\0'), tempKeyIdBase64.end()); offlineKeyIdAndKeyValueBase64_[tempKeyIdBase64] = tempKeyValueBase64; } fclose(offlineKeyFile); HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } int32_t MediaKeySystemService::SetOfflineKeyToFile() { HDF_LOGI("%{public}s: start", __func__); FILE *offlineKeyFile = fopen(offlineKeyFileName, "w+"); if (offlineKeyFile == NULL) { offlineKeyIdAndKeyValueBase64_.clear(); HDF_LOGE("%{public}s: create failed, ret: %{public}s", __func__, strerror(errno)); return HDF_FAILURE; } for (auto &keyIdValueBase64Pair : offlineKeyIdAndKeyValueBase64_) { fprintf(offlineKeyFile, "%s %s\n", keyIdValueBase64Pair.first.c_str(), keyIdValueBase64Pair.second.c_str()); } offlineKeyIdAndKeyValueBase64_.clear(); fclose(offlineKeyFile); HDF_LOGI("%{public}s: end", __func__); return HDF_SUCCESS; } } // V1_0 } // Drm } // HDI } // OHOS