1 /*
2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <hdf_base.h>
16 #include <hdf_log.h>
17 #include "v1_0/media_key_system_service.h"
18 #include "v1_0/media_key_session_service.h"
19 #include "base64_utils.h"
20 #include "data_parser.h"
21 #include "securec.h"
22
23 #define HDF_LOG_TAG media_key_system_service
24
25 namespace OHOS {
26 namespace HDI {
27 namespace Drm {
28 namespace V1_0 {
~MediaKeySystemService()29 MediaKeySystemService::~MediaKeySystemService()
30 {
31 HDF_LOGI("%{public}s: start", __func__);
32 mediaKeySessionMutex_.lock();
33 while (mediaKeySessionMap_.size() > 0) {
34 sptr<OHOS::HDI::Drm::V1_0::MediaKeySessionService> keySession = mediaKeySessionMap_.begin()->first;
35 mediaKeySessionMutex_.unlock();
36 CloseKeySessionService(keySession);
37 mediaKeySessionMutex_.lock();
38 }
39 mediaKeySessionMutex_.unlock();
40 HDF_LOGI("%{public}s: end", __func__);
41 }
42
GetConfigurationString(const std::string & name,std::string & value)43 int32_t MediaKeySystemService::GetConfigurationString(const std::string &name, std::string &value)
44 {
45 HDF_LOGI("%{public}s: start", __func__);
46 if (configurationString_.find(name) == configurationString_.end()) {
47 HDF_LOGE("%{public}s: do not find value, name: %{public}s", __func__, name.c_str());
48 return HDF_ERR_INVALID_PARAM;
49 }
50 value = configurationString_[name];
51 HDF_LOGI("%{public}s: end", __func__);
52 return HDF_SUCCESS;
53 }
54
SetConfigurationString(const std::string & name,const std::string & value)55 int32_t MediaKeySystemService::SetConfigurationString(const std::string &name, const std::string &value)
56 {
57 HDF_LOGI("%{public}s: start", __func__);
58 configurationString_[name] = value;
59 HDF_LOGI("%{public}s: end", __func__);
60 return HDF_SUCCESS;
61 }
62
GetConfigurationByteArray(const std::string & name,std::vector<uint8_t> & value)63 int32_t MediaKeySystemService::GetConfigurationByteArray(const std::string &name, std::vector<uint8_t> &value)
64 {
65 HDF_LOGI("%{public}s: start", __func__);
66 if (configuration_.find(name) == configuration_.end()) {
67 HDF_LOGE("%{public}s: do not find value, name: %{public}s", __func__, name.c_str());
68 return HDF_ERR_INVALID_PARAM;
69 }
70 value = configuration_[name];
71 HDF_LOGI("%{public}s: end", __func__);
72 return HDF_SUCCESS;
73 }
74
SetConfigurationByteArray(const std::string & name,const std::vector<uint8_t> & value)75 int32_t MediaKeySystemService::SetConfigurationByteArray(const std::string &name, const std::vector<uint8_t> &value)
76 {
77 HDF_LOGI("%{public}s: start", __func__);
78 configuration_[name] = value;
79 HDF_LOGI("%{public}s: end", __func__);
80 return HDF_SUCCESS;
81 }
82
GetStatistics(std::map<std::string,std::string> & statistics)83 int32_t MediaKeySystemService::GetStatistics(std::map<std::string, std::string> &statistics)
84 {
85 HDF_LOGI("%{public}s: start", __func__);
86 mediaKeySessionMutex_.lock();
87 int sessionNum = mediaKeySessionMap_.size();
88 int decryptNumber = 0;
89 int errorDecryptNumber = 0;
90 for (auto &pair : mediaKeySessionMap_) {
91 decryptNumber += pair.first->GetDecryptNumber();
92 errorDecryptNumber += pair.first->GetErrorDecryptNumber();
93 }
94 mediaKeySessionMutex_.unlock();
95
96 statistics[versionName] = "clearplay";
97 statistics[currentSessionNumName] = std::to_string(sessionNum);
98 statistics[decryptNumberName] = std::to_string(decryptNumber);
99 statistics[errorDecryptNumberName] = std::to_string(errorDecryptNumber);
100 HDF_LOGI("%{public}s: end", __func__);
101 return HDF_SUCCESS;
102 }
103
GetMaxContentProtectionLevel(ContentProtectionLevel & level)104 int32_t MediaKeySystemService::GetMaxContentProtectionLevel(ContentProtectionLevel &level)
105 {
106 HDF_LOGI("%{public}s: start", __func__);
107
108 level = OHOS::HDI::Drm::V1_0::ContentProtectionLevel::SW_SECURE_CRYPTO;
109 HDF_LOGI("%{public}s: end", __func__);
110 return HDF_SUCCESS;
111 }
112
GenerateKeySystemRequest(std::string & defaultUrl,std::vector<uint8_t> & request)113 int32_t MediaKeySystemService::GenerateKeySystemRequest(std::string &defaultUrl, std::vector<uint8_t> &request)
114 {
115 HDF_LOGI("%{public}s: start", __func__);
116 defaultUrl = "http://default.com";
117 std::string requestData = "{\"signedRequest\":\"KEYREQUESTTYPE_DOWNLOADCERT\"}";
118 size_t requestDataLen = requestData.size();
119 request.assign(requestData.c_str(), requestData.c_str() + requestDataLen);
120 if (vdiCallbackObj != nullptr) {
121 std::string eventData = "PROVISIONRE QUIRED";
122 std::vector<uint8_t> data(eventData.begin(), eventData.end());
123 vdiCallbackObj->SendEvent(EVENTTYPE_PROVISIONREQUIRED, 0, data);
124 }
125 HDF_LOGI("%{public}s: end", __func__);
126 return HDF_SUCCESS;
127 }
128
ProcessKeySystemResponse(const std::vector<uint8_t> & response)129 int32_t MediaKeySystemService::ProcessKeySystemResponse(const std::vector<uint8_t> &response)
130 {
131 HDF_LOGI("%{public}s: start", __func__);
132 std::string responseData(response.begin(), response.end());
133 HDF_LOGI("%{public}s: response: %{public}s", __func__, responseData.c_str());
134 HDF_LOGI("%{public}s: end", __func__);
135 return HDF_SUCCESS;
136 }
137
CreateMediaKeySession(ContentProtectionLevel level,sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession> & keySession)138 int32_t MediaKeySystemService::CreateMediaKeySession(ContentProtectionLevel level,
139 sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession> &keySession)
140 {
141 HDF_LOGI("%{public}s: start", __func__);
142 HDF_LOGI("%{public}s: start, level: %d", __func__, level);
143 sptr<MediaKeySessionService> keySessionService = nullptr;
144 keySessionService = new (std::nothrow) MediaKeySessionService(level);
145 if (keySessionService == nullptr) {
146 HDF_LOGE("MediaKeySystemService::CreateKeySession allocation failed");
147 return HDF_ERR_MALLOC_FAIL;
148 }
149 if (keySessionService->Init() != HDF_SUCCESS) {
150 HDF_LOGE("keySessionService::Init() failed");
151 delete keySessionService;
152 return HDF_ERR_MALLOC_FAIL;
153 }
154 keySessionService->SetKeySessionServiceCallback(this);
155 mediaKeySessionMutex_.lock();
156 mediaKeySessionMap_[keySessionService] = true;
157 mediaKeySessionMutex_.unlock();
158 keySession = keySessionService;
159 HDF_LOGI("%{public}s: end", __func__);
160 return HDF_SUCCESS;
161 }
162
GetOfflineMediaKeyIds(std::vector<std::vector<uint8_t>> & licenseIds)163 int32_t MediaKeySystemService::GetOfflineMediaKeyIds(std::vector<std::vector<uint8_t>> &licenseIds)
164 {
165 HDF_LOGI("%{public}s: start", __func__);
166 offlineKeyMutex_.lock();
167 int32_t ret = GetOfflineKeyFromFile();
168 if (ret != HDF_SUCCESS) {
169 offlineKeyMutex_.unlock();
170 return ret;
171 }
172 for (auto &keyIdValueBase64Pair : offlineKeyIdAndKeyValueBase64_) {
173 std::string keyIdString = Decode(keyIdValueBase64Pair.first);
174 std::vector<uint8_t> keyId(keyIdString.begin(), keyIdString.end());
175 licenseIds.push_back(keyId);
176 }
177 offlineKeyIdAndKeyValueBase64_.clear();
178 offlineKeyMutex_.unlock();
179 HDF_LOGI("%{public}s: end", __func__);
180 return HDF_SUCCESS;
181 }
182
GetOfflineMediaKeyStatus(const std::vector<uint8_t> & licenseId,OfflineMediaKeyStatus & licenseStatus)183 int32_t MediaKeySystemService::GetOfflineMediaKeyStatus(const std::vector<uint8_t> &licenseId,
184 OfflineMediaKeyStatus &licenseStatus)
185 {
186 HDF_LOGI("%{public}s: start", __func__);
187 offlineKeyMutex_.lock();
188 std::string keyIdString(licenseId.begin(), licenseId.end());
189 std::string keyIdBase64 = Encode(keyIdString);
190 int32_t ret = GetOfflineKeyFromFile();
191 if (ret != HDF_SUCCESS) {
192 offlineKeyMutex_.unlock();
193 return ret;
194 }
195 keyIdBase64.erase(std::remove(keyIdBase64.begin(), keyIdBase64.end(), '\0'), keyIdBase64.end());
196 if (offlineKeyIdAndKeyValueBase64_.find(keyIdBase64) == offlineKeyIdAndKeyValueBase64_.end()) {
197 licenseStatus = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN;
198 offlineKeyMutex_.unlock();
199 return HDF_SUCCESS;
200 }
201 for (auto it = mediaKeySessionMap_.begin(); it != mediaKeySessionMap_.end(); ++it) {
202 if (it->second == false) {
203 continue;
204 }
205 licenseStatus = it->first->session_->keyIdStatusMap[licenseId];
206 }
207 offlineKeyMutex_.unlock();
208 HDF_LOGI("%{public}s: end", __func__);
209 return HDF_SUCCESS;
210 }
211
ClearOfflineMediaKeys(const std::vector<uint8_t> & licenseId)212 int32_t MediaKeySystemService::ClearOfflineMediaKeys(const std::vector<uint8_t> &licenseId)
213 {
214 HDF_LOGI("%{public}s: start", __func__);
215 offlineKeyMutex_.lock();
216 int32_t ret = GetOfflineKeyFromFile();
217 if (ret != HDF_SUCCESS) {
218 offlineKeyMutex_.unlock();
219 return ret;
220 }
221 std::string keyIdString(licenseId.begin(), licenseId.end());
222 std::string keyIdBase64 = Encode(keyIdString);
223 auto it = offlineKeyIdAndKeyValueBase64_.find(keyIdBase64);
224 if (it != offlineKeyIdAndKeyValueBase64_.end()) {
225 offlineKeyIdAndKeyValueBase64_.erase(it);
226 ret = SetOfflineKeyToFile();
227 if (ret != HDF_SUCCESS) {
228 offlineKeyMutex_.unlock();
229 return ret;
230 }
231 for (auto it = mediaKeySessionMap_.begin(); it != mediaKeySessionMap_.end(); ++it) {
232 if (it->second == false) {
233 continue;
234 }
235 it->first->session_->keyIdStatusMap[licenseId] = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN;
236 }
237 offlineKeyMutex_.unlock();
238 HDF_LOGI("%{public}s: end", __func__);
239 return HDF_SUCCESS;
240 }
241 offlineKeyMutex_.unlock();
242 HDF_LOGI("%{public}s: do not find offline license, keyId: %{public}s", __func__, licenseId.data());
243 return HDF_FAILURE;
244 }
245
GetOemCertificate(sptr<OHOS::HDI::Drm::V1_0::IOemCertificate> & oemCert)246 int32_t MediaKeySystemService::GetOemCertificate(sptr<OHOS::HDI::Drm::V1_0::IOemCertificate> &oemCert)
247 {
248 HDF_LOGI("%{public}s: start", __func__);
249 HDF_LOGI("%{public}s: end", __func__);
250 return HDF_SUCCESS;
251 }
252
GetOemCertificateStatus(CertificateStatus & status)253 int32_t MediaKeySystemService::GetOemCertificateStatus(CertificateStatus &status)
254 {
255 HDF_LOGI("%{public}s: start", __func__);
256 HDF_LOGI("%{public}s: end", __func__);
257 return HDF_SUCCESS;
258 }
259
SetCallback(const sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystemCallback> & systemCallback)260 int32_t MediaKeySystemService::SetCallback(const sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystemCallback> &systemCallback)
261 {
262 vdiCallbackObj = new (std::nothrow) MediaKeySystemCallbackService(systemCallback);
263 if (vdiCallbackObj == nullptr) {
264 HDF_LOGE("new MediaKeySystemCallbackService() failed");
265 return HDF_ERR_MALLOC_FAIL;
266 }
267 return HDF_SUCCESS;
268 }
269
Destroy()270 int32_t MediaKeySystemService::Destroy()
271 {
272 HDF_LOGI("%{public}s: start", __func__);
273 if (systemCallback_ != nullptr) {
274 systemCallback_->CloseMediaKeySystemService(this);
275 }
276 systemCallback_ = nullptr;
277 HDF_LOGI("%{public}s: end", __func__);
278 return HDF_SUCCESS;
279 }
280
CloseKeySessionService(sptr<MediaKeySessionService> mediaKeySession)281 int32_t MediaKeySystemService::CloseKeySessionService(sptr<MediaKeySessionService> mediaKeySession)
282 {
283 HDF_LOGI("%{public}s: start", __func__);
284 mediaKeySessionMutex_.lock();
285 auto it = mediaKeySessionMap_.find(mediaKeySession);
286 if (it == mediaKeySessionMap_.end()) {
287 mediaKeySessionMutex_.unlock();
288 return HDF_FAILURE;
289 }
290 mediaKeySessionMap_.erase(it);
291 mediaKeySessionMutex_.unlock();
292 HDF_LOGI("%{public}s: end", __func__);
293 return HDF_SUCCESS;
294 }
295
SetKeySystemServiceCallback(sptr<MediaKeySystemServiceCallback> callback)296 int32_t MediaKeySystemService::SetKeySystemServiceCallback(sptr<MediaKeySystemServiceCallback> callback)
297 {
298 HDF_LOGI("%{public}s: start", __func__);
299 if (callback == nullptr) {
300 HDF_LOGE("MediaKeySystemServiceCallback callback is null");
301 return HDF_ERR_INVALID_PARAM;
302 }
303 systemCallback_ = callback;
304 HDF_LOGI("%{public}s: end", __func__);
305 return HDF_SUCCESS;
306 }
307
GetOfflineKeyFromFile()308 int32_t MediaKeySystemService::GetOfflineKeyFromFile()
309 {
310 HDF_LOGI("%{public}s: start", __func__);
311 FILE *offlineKeyFile = fopen(offlineKeyFileName, "r+");
312 if (offlineKeyFile == NULL) {
313 HDF_LOGE("%{public}s: open: \"%{public}s\" failed", __func__, offlineKeyFileName);
314 // file do not exist, is allright
315 return HDF_SUCCESS;
316 }
317 char keyIdBase64Chars[keyIdMaxLength];
318 char keyValueBase64Chars[keyIdMaxLength];
319 while (fscanf_s(offlineKeyFile, "%s %s", keyIdBase64Chars, sizeof(keyIdBase64Chars), keyValueBase64Chars,
320 sizeof(keyValueBase64Chars)) != EOF) {
321 std::string tempKeyIdBase64 = keyIdBase64Chars;
322 std::string tempKeyValueBase64 = keyValueBase64Chars;
323 tempKeyIdBase64.erase(std::remove(tempKeyIdBase64.begin(), tempKeyIdBase64.end(), '\0'), tempKeyIdBase64.end());
324 offlineKeyIdAndKeyValueBase64_[tempKeyIdBase64] = tempKeyValueBase64;
325 }
326 fclose(offlineKeyFile);
327 HDF_LOGI("%{public}s: end", __func__);
328 return HDF_SUCCESS;
329 }
330
SetOfflineKeyToFile()331 int32_t MediaKeySystemService::SetOfflineKeyToFile()
332 {
333 HDF_LOGI("%{public}s: start", __func__);
334 FILE *offlineKeyFile = fopen(offlineKeyFileName, "w+");
335 if (offlineKeyFile == NULL) {
336 offlineKeyIdAndKeyValueBase64_.clear();
337 HDF_LOGE("%{public}s: create failed, ret: %{public}s", __func__, strerror(errno));
338 return HDF_FAILURE;
339 }
340 for (auto &keyIdValueBase64Pair : offlineKeyIdAndKeyValueBase64_) {
341 fprintf(offlineKeyFile, "%s %s\n", keyIdValueBase64Pair.first.c_str(), keyIdValueBase64Pair.second.c_str());
342 }
343 offlineKeyIdAndKeyValueBase64_.clear();
344 fclose(offlineKeyFile);
345 HDF_LOGI("%{public}s: end", __func__);
346 return HDF_SUCCESS;
347 }
348 } // V1_0
349 } // Drm
350 } // HDI
351 } // OHOS
352