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 HDF_FAILURE;
217 }
218 keyIdBase64.erase(std::remove(keyIdBase64.begin(), keyIdBase64.end(), '\0'), keyIdBase64.end());
219 if (offlineKeyIdAndKeyValueBase64_.find(keyIdBase64) == offlineKeyIdAndKeyValueBase64_.end()) {
220 offlineKeyMutex_.unlock();
221 return HDF_FAILURE;
222 }
223 for (auto it = mediaKeySessionMap_.begin(); it != mediaKeySessionMap_.end(); ++it) {
224 if (it->second == false) {
225 continue;
226 }
227 licenseStatus = it->first->session_->keyIdStatusMap[licenseId];
228 }
229 offlineKeyMutex_.unlock();
230 HDF_LOGI("%{public}s: end", __func__);
231 return HDF_SUCCESS;
232 }
233
ClearOfflineMediaKeys(const std::vector<uint8_t> & licenseId)234 int32_t MediaKeySystemService::ClearOfflineMediaKeys(const std::vector<uint8_t> &licenseId)
235 {
236 HDF_LOGI("%{public}s: start", __func__);
237 offlineKeyMutex_.lock();
238 int32_t ret = GetOfflineKeyFromFile();
239 if (ret != HDF_SUCCESS) {
240 offlineKeyMutex_.unlock();
241 return ret;
242 }
243 std::string keyIdString(licenseId.begin(), licenseId.end());
244 std::string keyIdBase64 = Encode(keyIdString);
245 auto it = offlineKeyIdAndKeyValueBase64_.find(keyIdBase64);
246 if (it != offlineKeyIdAndKeyValueBase64_.end()) {
247 offlineKeyIdAndKeyValueBase64_.erase(it);
248 ret = SetOfflineKeyToFile();
249 if (ret != HDF_SUCCESS) {
250 offlineKeyMutex_.unlock();
251 return ret;
252 }
253 for (auto it = mediaKeySessionMap_.begin(); it != mediaKeySessionMap_.end(); ++it) {
254 if (it->second == false) {
255 continue;
256 }
257 it->first->session_->keyIdStatusMap[licenseId] = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN;
258 }
259 offlineKeyMutex_.unlock();
260 HDF_LOGI("%{public}s: end", __func__);
261 return HDF_SUCCESS;
262 }
263 offlineKeyMutex_.unlock();
264 HDF_LOGI("%{public}s: do not find offline license, keyId: %{public}s", __func__, licenseId.data());
265 return HDF_FAILURE;
266 }
267
GetOemCertificate(sptr<OHOS::HDI::Drm::V1_0::IOemCertificate> & oemCert)268 int32_t MediaKeySystemService::GetOemCertificate(sptr<OHOS::HDI::Drm::V1_0::IOemCertificate> &oemCert)
269 {
270 HDF_LOGI("%{public}s: start", __func__);
271 HDF_LOGI("%{public}s: end", __func__);
272 return HDF_SUCCESS;
273 }
274
GetOemCertificateStatus(CertificateStatus & status)275 int32_t MediaKeySystemService::GetOemCertificateStatus(CertificateStatus &status)
276 {
277 HDF_LOGI("%{public}s: start", __func__);
278 HDF_LOGI("%{public}s: end", __func__);
279 return HDF_SUCCESS;
280 }
281
SetCallback(const sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystemCallback> & systemCallback)282 int32_t MediaKeySystemService::SetCallback(const sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystemCallback> &systemCallback)
283 {
284 vdiCallbackObj = new (std::nothrow) MediaKeySystemCallbackService(systemCallback);
285 if (vdiCallbackObj == nullptr) {
286 HDF_LOGE("new MediaKeySystemCallbackService() failed");
287 return HDF_ERR_MALLOC_FAIL;
288 }
289 return HDF_SUCCESS;
290 }
291
Destroy()292 int32_t MediaKeySystemService::Destroy()
293 {
294 HDF_LOGI("%{public}s: start", __func__);
295 if (systemCallback_ != nullptr) {
296 systemCallback_->CloseMediaKeySystemService(this);
297 }
298 systemCallback_ = nullptr;
299 HDF_LOGI("%{public}s: end", __func__);
300 return HDF_SUCCESS;
301 }
302
CloseKeySessionService(sptr<MediaKeySessionService> mediaKeySession)303 int32_t MediaKeySystemService::CloseKeySessionService(sptr<MediaKeySessionService> mediaKeySession)
304 {
305 HDF_LOGI("%{public}s: start", __func__);
306 mediaKeySessionMutex_.lock();
307 auto it = mediaKeySessionMap_.find(mediaKeySession);
308 if (it == mediaKeySessionMap_.end()) {
309 mediaKeySessionMutex_.unlock();
310 return HDF_FAILURE;
311 }
312 mediaKeySessionMap_.erase(it);
313 mediaKeySessionMutex_.unlock();
314 HDF_LOGI("%{public}s: end", __func__);
315 return HDF_SUCCESS;
316 }
317
SetKeySystemServiceCallback(sptr<MediaKeySystemServiceCallback> callback)318 int32_t MediaKeySystemService::SetKeySystemServiceCallback(sptr<MediaKeySystemServiceCallback> callback)
319 {
320 HDF_LOGI("%{public}s: start", __func__);
321 if (callback == nullptr) {
322 HDF_LOGE("MediaKeySystemServiceCallback callback is null");
323 return HDF_ERR_INVALID_PARAM;
324 }
325 systemCallback_ = callback;
326 HDF_LOGI("%{public}s: end", __func__);
327 return HDF_SUCCESS;
328 }
329
GetOfflineKeyFromFile()330 int32_t MediaKeySystemService::GetOfflineKeyFromFile()
331 {
332 HDF_LOGI("%{public}s: start", __func__);
333 FILE *offlineKeyFile = fopen(offlineKeyFileName, "r+");
334 if (offlineKeyFile == NULL) {
335 HDF_LOGE("%{public}s: open: \"%{public}s\" failed", __func__, offlineKeyFileName);
336 // file do not exist, is allright
337 return HDF_SUCCESS;
338 }
339 char keyIdBase64Chars[keyIdMaxLength];
340 char keyValueBase64Chars[keyIdMaxLength];
341 while (fscanf_s(offlineKeyFile, "%s %s", keyIdBase64Chars, sizeof(keyIdBase64Chars), keyValueBase64Chars, sizeof(keyValueBase64Chars)) != EOF) {
342 std::string tempKeyIdBase64 = keyIdBase64Chars;
343 std::string tempKeyValueBase64 = keyValueBase64Chars;
344 tempKeyIdBase64.erase(std::remove(tempKeyIdBase64.begin(), tempKeyIdBase64.end(), '\0'), tempKeyIdBase64.end());
345 offlineKeyIdAndKeyValueBase64_[tempKeyIdBase64] = tempKeyValueBase64;
346 }
347 fclose(offlineKeyFile);
348 HDF_LOGI("%{public}s: end", __func__);
349 return HDF_SUCCESS;
350 }
351
SetOfflineKeyToFile()352 int32_t MediaKeySystemService::SetOfflineKeyToFile()
353 {
354 HDF_LOGI("%{public}s: start", __func__);
355 FILE *offlineKeyFile = fopen(offlineKeyFileName, "w+");
356 if (offlineKeyFile == NULL) {
357 offlineKeyIdAndKeyValueBase64_.clear();
358 HDF_LOGE("%{public}s: create failed, ret: %{public}s", __func__, strerror(errno));
359 return HDF_FAILURE;
360 }
361 for (auto &keyIdValueBase64Pair : offlineKeyIdAndKeyValueBase64_) {
362 fprintf(offlineKeyFile, "%s %s\n", keyIdValueBase64Pair.first.c_str(), keyIdValueBase64Pair.second.c_str());
363 }
364 offlineKeyIdAndKeyValueBase64_.clear();
365 fclose(offlineKeyFile);
366 HDF_LOGI("%{public}s: end", __func__);
367 return HDF_SUCCESS;
368 }
369 } // V1_0
370 } // Drm
371 } // HDI
372 } // OHOS