1 /*
2 * Copyright (c) 2023 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
GetDecryptTimeAsString(std::vector<std::vector<double>> & topThreeTimes,std::string & decryptTimes)83 void MediaKeySystemService::GetDecryptTimeAsString(std::vector<std::vector<double>> &topThreeTimes,
84 std::string &decryptTimes)
85 {
86 for (auto &time : topThreeTimes) {
87 if (!decryptTimes.empty()) {
88 decryptTimes.append(";");
89 }
90 for (auto it = time.begin(); it != time.end(); ++it) {
91 if (it != time.begin()) {
92 decryptTimes.append(",");
93 }
94 decryptTimes.append(std::to_string(*it));
95 }
96 }
97 }
98
GetStatistics(std::map<std::string,std::string> & statistics)99 int32_t MediaKeySystemService::GetStatistics(std::map<std::string, std::string> &statistics)
100 {
101 HDF_LOGI("%{public}s: start", __func__);
102 mediaKeySessionMutex_.lock();
103 int sessionNum = mediaKeySessionMap_.size();
104 int decryptNumber = 0;
105 int errorDecryptNumber = 0;
106 std::vector<std::vector<double>> topThreeTimes;
107 std::string decryptTimes;
108 for (auto &pair : mediaKeySessionMap_) {
109 decryptNumber += pair.first->GetDecryptNumber();
110 errorDecryptNumber += pair.first->GetErrorDecryptNumber();
111 std::vector<double> topThreeTime;
112 pair.first->GetDecryptTimes(topThreeTime);
113 topThreeTimes.push_back(topThreeTime);
114 }
115 GetDecryptTimeAsString(topThreeTimes, decryptTimes);
116 mediaKeySessionMutex_.unlock();
117
118 statistics[versionName] = "clearplay";
119 statistics[currentSessionNumName] = std::to_string(sessionNum);
120 statistics[decryptNumberName] = std::to_string(decryptNumber);
121 statistics[errorDecryptNumberName] = std::to_string(errorDecryptNumber);
122 statistics[decryptTime] = decryptTimes;
123 HDF_LOGI("%{public}s: end", __func__);
124 return HDF_SUCCESS;
125 }
126
GetMaxContentProtectionLevel(ContentProtectionLevel & level)127 int32_t MediaKeySystemService::GetMaxContentProtectionLevel(ContentProtectionLevel &level)
128 {
129 HDF_LOGI("%{public}s: start", __func__);
130
131 level = OHOS::HDI::Drm::V1_0::ContentProtectionLevel::SW_SECURE_CRYPTO;
132 HDF_LOGI("%{public}s: end", __func__);
133 return HDF_SUCCESS;
134 }
135
GenerateKeySystemRequest(std::string & defaultUrl,std::vector<uint8_t> & request)136 int32_t MediaKeySystemService::GenerateKeySystemRequest(std::string &defaultUrl, std::vector<uint8_t> &request)
137 {
138 HDF_LOGI("%{public}s: start", __func__);
139 defaultUrl = "http://default.com";
140 std::string requestData = "{\"signedRequest\":\"KEYREQUESTTYPE_DOWNLOADCERT\"}";
141 size_t requestDataLen = requestData.size();
142 request.assign(requestData.c_str(), requestData.c_str() + requestDataLen);
143 if (vdiCallbackObj != nullptr) {
144 std::string eventData = "PROVISIONRE QUIRED";
145 std::vector<uint8_t> data(eventData.begin(), eventData.end());
146 vdiCallbackObj->SendEvent(EVENTTYPE_PROVISIONREQUIRED, 0, data);
147 }
148 HDF_LOGI("%{public}s: end", __func__);
149 return HDF_SUCCESS;
150 }
151
ProcessKeySystemResponse(const std::vector<uint8_t> & response)152 int32_t MediaKeySystemService::ProcessKeySystemResponse(const std::vector<uint8_t> &response)
153 {
154 HDF_LOGI("%{public}s: start", __func__);
155 std::string responseData(response.begin(), response.end());
156 HDF_LOGI("%{public}s: response: %{public}s", __func__, responseData.c_str());
157 HDF_LOGI("%{public}s: end", __func__);
158 return HDF_SUCCESS;
159 }
160
CreateMediaKeySession(ContentProtectionLevel level,sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession> & keySession)161 int32_t MediaKeySystemService::CreateMediaKeySession(ContentProtectionLevel level,
162 sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession> &keySession)
163 {
164 HDF_LOGI("%{public}s: start", __func__);
165 HDF_LOGI("%{public}s: start, level: %d", __func__, level);
166 sptr<MediaKeySessionService> keySessionService = nullptr;
167 keySessionService = new (std::nothrow) MediaKeySessionService(level);
168 if (keySessionService == nullptr) {
169 HDF_LOGE("MediaKeySystemService::CreateKeySession allocation failed");
170 return HDF_ERR_MALLOC_FAIL;
171 }
172 if (keySessionService->Init() != HDF_SUCCESS) {
173 HDF_LOGE("keySessionService::Init() failed");
174 delete keySessionService;
175 return HDF_ERR_MALLOC_FAIL;
176 }
177 keySessionService->SetKeySessionServiceCallback(this);
178 mediaKeySessionMutex_.lock();
179 mediaKeySessionMap_[keySessionService] = true;
180 mediaKeySessionMutex_.unlock();
181 keySession = keySessionService;
182 HDF_LOGI("%{public}s: end", __func__);
183 return HDF_SUCCESS;
184 }
185
GetOfflineMediaKeyIds(std::vector<std::vector<uint8_t>> & licenseIds)186 int32_t MediaKeySystemService::GetOfflineMediaKeyIds(std::vector<std::vector<uint8_t>> &licenseIds)
187 {
188 HDF_LOGI("%{public}s: start", __func__);
189 offlineKeyMutex_.lock();
190 int32_t ret = GetOfflineKeyFromFile();
191 if (ret != HDF_SUCCESS) {
192 offlineKeyMutex_.unlock();
193 return ret;
194 }
195 for (auto &keyIdValueBase64Pair : offlineKeyIdAndKeyValueBase64_) {
196 std::string keyIdString = Decode(keyIdValueBase64Pair.first);
197 std::vector<uint8_t> keyId(keyIdString.begin(), keyIdString.end());
198 licenseIds.push_back(keyId);
199 }
200 offlineKeyIdAndKeyValueBase64_.clear();
201 offlineKeyMutex_.unlock();
202 HDF_LOGI("%{public}s: end", __func__);
203 return HDF_SUCCESS;
204 }
205
GetOfflineMediaKeyStatus(const std::vector<uint8_t> & licenseId,OfflineMediaKeyStatus & licenseStatus)206 int32_t MediaKeySystemService::GetOfflineMediaKeyStatus(const std::vector<uint8_t> &licenseId,
207 OfflineMediaKeyStatus &licenseStatus)
208 {
209 HDF_LOGI("%{public}s: start", __func__);
210 offlineKeyMutex_.lock();
211 std::string keyIdString(licenseId.begin(), licenseId.end());
212 std::string keyIdBase64 = Encode(keyIdString);
213 int32_t ret = GetOfflineKeyFromFile();
214 if (ret != HDF_SUCCESS) {
215 offlineKeyMutex_.unlock();
216 return ret;
217 }
218 keyIdBase64.erase(std::remove(keyIdBase64.begin(), keyIdBase64.end(), '\0'), keyIdBase64.end());
219 if (offlineKeyIdAndKeyValueBase64_.find(keyIdBase64) == offlineKeyIdAndKeyValueBase64_.end()) {
220 licenseStatus = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN;
221 offlineKeyMutex_.unlock();
222 return HDF_SUCCESS;
223 }
224 for (auto it = mediaKeySessionMap_.begin(); it != mediaKeySessionMap_.end(); ++it) {
225 if (it->second == false) {
226 continue;
227 }
228 licenseStatus = it->first->session_->keyIdStatusMap[licenseId];
229 }
230 offlineKeyMutex_.unlock();
231 HDF_LOGI("%{public}s: end", __func__);
232 return HDF_SUCCESS;
233 }
234
ClearOfflineMediaKeys(const std::vector<uint8_t> & licenseId)235 int32_t MediaKeySystemService::ClearOfflineMediaKeys(const std::vector<uint8_t> &licenseId)
236 {
237 HDF_LOGI("%{public}s: start", __func__);
238 offlineKeyMutex_.lock();
239 int32_t ret = GetOfflineKeyFromFile();
240 if (ret != HDF_SUCCESS) {
241 offlineKeyMutex_.unlock();
242 return ret;
243 }
244 std::string keyIdString(licenseId.begin(), licenseId.end());
245 std::string keyIdBase64 = Encode(keyIdString);
246 auto it = offlineKeyIdAndKeyValueBase64_.find(keyIdBase64);
247 if (it != offlineKeyIdAndKeyValueBase64_.end()) {
248 offlineKeyIdAndKeyValueBase64_.erase(it);
249 ret = SetOfflineKeyToFile();
250 if (ret != HDF_SUCCESS) {
251 offlineKeyMutex_.unlock();
252 return ret;
253 }
254 for (auto it = mediaKeySessionMap_.begin(); it != mediaKeySessionMap_.end(); ++it) {
255 if (it->second == false) {
256 continue;
257 }
258 it->first->session_->keyIdStatusMap[licenseId] = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN;
259 }
260 offlineKeyMutex_.unlock();
261 HDF_LOGI("%{public}s: end", __func__);
262 return HDF_SUCCESS;
263 }
264 offlineKeyMutex_.unlock();
265 HDF_LOGI("%{public}s: do not find offline license, keyId: %{public}s", __func__, licenseId.data());
266 return HDF_FAILURE;
267 }
268
GetOemCertificate(sptr<OHOS::HDI::Drm::V1_0::IOemCertificate> & oemCert)269 int32_t MediaKeySystemService::GetOemCertificate(sptr<OHOS::HDI::Drm::V1_0::IOemCertificate> &oemCert)
270 {
271 HDF_LOGI("%{public}s: start", __func__);
272 HDF_LOGI("%{public}s: end", __func__);
273 return HDF_SUCCESS;
274 }
275
GetOemCertificateStatus(CertificateStatus & status)276 int32_t MediaKeySystemService::GetOemCertificateStatus(CertificateStatus &status)
277 {
278 HDF_LOGI("%{public}s: start", __func__);
279 HDF_LOGI("%{public}s: end", __func__);
280 return HDF_SUCCESS;
281 }
282
SetCallback(const sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystemCallback> & systemCallback)283 int32_t MediaKeySystemService::SetCallback(const sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystemCallback> &systemCallback)
284 {
285 vdiCallbackObj = new (std::nothrow) MediaKeySystemCallbackService(systemCallback);
286 if (vdiCallbackObj == nullptr) {
287 HDF_LOGE("new MediaKeySystemCallbackService() failed");
288 return HDF_ERR_MALLOC_FAIL;
289 }
290 return HDF_SUCCESS;
291 }
292
Destroy()293 int32_t MediaKeySystemService::Destroy()
294 {
295 HDF_LOGI("%{public}s: start", __func__);
296 if (systemCallback_ != nullptr) {
297 systemCallback_->CloseMediaKeySystemService(this);
298 }
299 systemCallback_ = nullptr;
300 HDF_LOGI("%{public}s: end", __func__);
301 return HDF_SUCCESS;
302 }
303
CloseKeySessionService(sptr<MediaKeySessionService> mediaKeySession)304 int32_t MediaKeySystemService::CloseKeySessionService(sptr<MediaKeySessionService> mediaKeySession)
305 {
306 HDF_LOGI("%{public}s: start", __func__);
307 mediaKeySessionMutex_.lock();
308 auto it = mediaKeySessionMap_.find(mediaKeySession);
309 if (it == mediaKeySessionMap_.end()) {
310 mediaKeySessionMutex_.unlock();
311 return HDF_FAILURE;
312 }
313 mediaKeySessionMap_.erase(it);
314 mediaKeySessionMutex_.unlock();
315 HDF_LOGI("%{public}s: end", __func__);
316 return HDF_SUCCESS;
317 }
318
SetKeySystemServiceCallback(sptr<MediaKeySystemServiceCallback> callback)319 int32_t MediaKeySystemService::SetKeySystemServiceCallback(sptr<MediaKeySystemServiceCallback> callback)
320 {
321 HDF_LOGI("%{public}s: start", __func__);
322 if (callback == nullptr) {
323 HDF_LOGE("MediaKeySystemServiceCallback callback is null");
324 return HDF_ERR_INVALID_PARAM;
325 }
326 systemCallback_ = callback;
327 HDF_LOGI("%{public}s: end", __func__);
328 return HDF_SUCCESS;
329 }
330
GetOfflineKeyFromFile()331 int32_t MediaKeySystemService::GetOfflineKeyFromFile()
332 {
333 HDF_LOGI("%{public}s: start", __func__);
334 FILE *offlineKeyFile = fopen(offlineKeyFileName, "r+");
335 if (offlineKeyFile == NULL) {
336 HDF_LOGE("%{public}s: open: \"%{public}s\" failed", __func__, offlineKeyFileName);
337 // file do not exist, is allright
338 return HDF_SUCCESS;
339 }
340 char keyIdBase64Chars[keyIdMaxLength];
341 char keyValueBase64Chars[keyIdMaxLength];
342 while (fscanf_s(offlineKeyFile, "%s %s", keyIdBase64Chars, sizeof(keyIdBase64Chars), keyValueBase64Chars, sizeof(keyValueBase64Chars)) != EOF) {
343 std::string tempKeyIdBase64 = keyIdBase64Chars;
344 std::string tempKeyValueBase64 = keyValueBase64Chars;
345 tempKeyIdBase64.erase(std::remove(tempKeyIdBase64.begin(), tempKeyIdBase64.end(), '\0'), tempKeyIdBase64.end());
346 offlineKeyIdAndKeyValueBase64_[tempKeyIdBase64] = tempKeyValueBase64;
347 }
348 fclose(offlineKeyFile);
349 HDF_LOGI("%{public}s: end", __func__);
350 return HDF_SUCCESS;
351 }
352
SetOfflineKeyToFile()353 int32_t MediaKeySystemService::SetOfflineKeyToFile()
354 {
355 HDF_LOGI("%{public}s: start", __func__);
356 FILE *offlineKeyFile = fopen(offlineKeyFileName, "w+");
357 if (offlineKeyFile == NULL) {
358 offlineKeyIdAndKeyValueBase64_.clear();
359 HDF_LOGE("%{public}s: create failed, ret: %{public}s", __func__, strerror(errno));
360 return HDF_FAILURE;
361 }
362 for (auto &keyIdValueBase64Pair : offlineKeyIdAndKeyValueBase64_) {
363 fprintf(offlineKeyFile, "%s %s\n", keyIdValueBase64Pair.first.c_str(), keyIdValueBase64Pair.second.c_str());
364 }
365 offlineKeyIdAndKeyValueBase64_.clear();
366 fclose(offlineKeyFile);
367 HDF_LOGI("%{public}s: end", __func__);
368 return HDF_SUCCESS;
369 }
370 } // V1_0
371 } // Drm
372 } // HDI
373 } // OHOS
374