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
16 #include "v1_0/media_key_session_service.h"
17 #include "v1_0/media_key_system_types.h"
18 #include "v1_0/media_decrypt_module_service.h"
19 #include <hdf_base.h>
20 #include <hdf_log.h>
21 #include <unistd.h>
22 #include <dirent.h>
23 #include <errno.h>
24 #include "base64_utils.h"
25 #include "data_parser.h"
26 #include "securec.h"
27
28 #define HDF_LOG_TAG media_key_session_service
29
30 namespace OHOS {
31 namespace HDI {
32 namespace Drm {
33 namespace V1_0 {
MediaKeySessionService()34 MediaKeySessionService::MediaKeySessionService()
35 {
36 HDF_LOGI("%{public}s: start", __func__);
37 HDF_LOGI("%{public}s: end", __func__);
38 }
39
MediaKeySessionService(ContentProtectionLevel level)40 MediaKeySessionService::MediaKeySessionService(ContentProtectionLevel level)
41 {
42 HDF_LOGI("%{public}s: start", __func__);
43 level_ = level;
44 HDF_LOGI("%{public}s: end", __func__);
45 }
46
GenerateMediaKeyRequest(const MediaKeyRequestInfo & licenseRequestInfo,MediaKeyRequest & licenseRequest)47 int32_t MediaKeySessionService::GenerateMediaKeyRequest(const MediaKeyRequestInfo &licenseRequestInfo,
48 MediaKeyRequest &licenseRequest)
49 {
50 HDF_LOGI("%{public}s: start", __func__);
51 int32_t ret = HDF_SUCCESS;
52 licenseRequest.requestType = MEDIA_KEY_REQUEST_TYPE_INITIAL;
53 licenseRequest.defaultUrl = "http://default.com";
54 if (vdiCallbackObj != nullptr) {
55 std::string eventData = "KEY NEEDED";
56 std::vector<uint8_t> data(eventData.begin(), eventData.end());
57 vdiCallbackObj->SendEvent(EVENTTYPE_KEYREQUIRED, 0, data);
58 }
59 ret = session_->getKeyRequest(licenseRequestInfo.initData, licenseRequestInfo.mimeType,
60 licenseRequestInfo.mediaKeyType, licenseRequestInfo.optionalData, &licenseRequest.data);
61 HDF_LOGI("%{public}s: end", __func__);
62 return ret;
63 }
64
ProcessMediaKeyResponse(const std::vector<uint8_t> & licenseResponse,std::vector<uint8_t> & licenseId)65 int32_t MediaKeySessionService::ProcessMediaKeyResponse(const std::vector<uint8_t> &licenseResponse,
66 std::vector<uint8_t> &licenseId)
67 {
68 HDF_LOGI("%{public}s: start", __func__);
69 licenseId.clear();
70 size_t commaPos = 0;
71 std::vector<std::vector<uint8_t>> keyIdAndValuePairs;
72 for (size_t i = 0; i < licenseResponse.size(); i++) {
73 if (licenseResponse[i] == ',') {
74 keyIdAndValuePairs.push_back(
75 std::vector<uint8_t>(licenseResponse.begin() + commaPos, licenseResponse.begin() + i));
76 commaPos = i + 1;
77 }
78 }
79 keyIdAndValuePairs.push_back(std::vector<uint8_t>(licenseResponse.begin() + commaPos, licenseResponse.end()));
80 for (auto &keyIdAndValuePair : keyIdAndValuePairs) {
81 size_t colonPos = 0;
82 MediaKeyType mediaKeyType = MEDIA_KEY_TYPE_ONLINE;
83 if (keyIdAndValuePair[0] == '0') {
84 mediaKeyType = MEDIA_KEY_TYPE_ONLINE;
85 } else if (keyIdAndValuePair[0] == '1') {
86 mediaKeyType = MEDIA_KEY_TYPE_OFFLINE;
87 } else {
88 HDF_LOGE("%{public}s: without '0/1'", __func__);
89 return HDF_ERR_INVALID_PARAM;
90 }
91 while (colonPos < keyIdAndValuePair.size() && keyIdAndValuePair[colonPos] != ':') {
92 ++colonPos;
93 }
94 if (colonPos == keyIdAndValuePair.size()) {
95 HDF_LOGE("%{public}s: without char ':'", __func__);
96 return HDF_ERR_INVALID_PARAM;
97 }
98 std::string keyIdBase64(keyIdAndValuePair.begin() + 1, keyIdAndValuePair.begin() + colonPos);
99 std::string keyValueBase64(keyIdAndValuePair.begin() + colonPos + 1, keyIdAndValuePair.end());
100 std::string keyIdString = Decode(keyIdBase64);
101 std::string keyValueString = Decode(keyValueBase64);
102
103 std::vector<uint8_t> localKeyId(keyIdString.begin(), keyIdString.end());
104 std::vector<uint8_t> value(keyValueString.begin(), keyValueString.end());
105 licenseId.assign(localKeyId.begin(), localKeyId.end());
106 int32_t ret = session_->setKeyIdAndKeyValue(localKeyId, value);
107 if (ret != HDF_SUCCESS) {
108 HDF_LOGE("%{public}s: setKeyIdAndKeyValue faild", __func__);
109 return ret;
110 }
111 if (mediaKeyType == MEDIA_KEY_TYPE_OFFLINE) {
112 offlineKeyMutex_.lock();
113 ret = GetOfflineKeyFromFile();
114 if (ret != HDF_SUCCESS) {
115 offlineKeyMutex_.unlock();
116 HDF_LOGE("%{public}s: GetOfflineKeyFromFile faild", __func__);
117 return ret;
118 }
119 offlineKeyIdAndKeyValueBase64_[keyIdBase64] = keyValueBase64;
120 ret = SetOfflineKeyToFile();
121 if (ret != HDF_SUCCESS) {
122 offlineKeyMutex_.unlock();
123 HDF_LOGE("%{public}s: SetOfflineKeyToFile faild", __func__);
124 return ret;
125 }
126 session_->keyIdStatusMap[licenseId] = OFFLINE_MEDIA_KEY_STATUS_USABLE;
127 offlineKeyMutex_.unlock();
128 }
129 }
130 if (vdiCallbackObj != nullptr) {
131 std::vector<uint8_t> licenseIdVec(licenseId.begin(), licenseId.end());
132 std::map<std::vector<uint8_t>, MediaKeySessionKeyStatus> keyStatus;
133 MediaKeySessionKeyStatus status = MEDIA_KEY_SESSION_KEY_STATUS_USABLE;
134 keyStatus.insert(std::make_pair(licenseIdVec, status));
135 vdiCallbackObj->SendEventKeyChange(keyStatus, true);
136 }
137
138 HDF_LOGI("%{public}s: end", __func__);
139 return HDF_SUCCESS;
140 }
141
CheckMediaKeyStatus(std::map<std::string,std::string> & mediaKeyStatus)142 int32_t MediaKeySessionService::CheckMediaKeyStatus(std::map<std::string, std::string>& mediaKeyStatus)
143 {
144 HDF_LOGI("%{public}s: start", __func__);
145 for (auto &keyValuePair : session_->keyIdAndKeyValue_) {
146 std::string name = std::string(keyValuePair.first.begin(), keyValuePair.first.end());
147 std::string value = "MediaKey is OK";
148 mediaKeyStatus.insert(std::make_pair(name, value));
149 }
150 HDF_LOGI("%{public}s: end", __func__);
151 return HDF_SUCCESS;
152 }
153
ClearMediaKeys()154 int32_t MediaKeySessionService::ClearMediaKeys()
155 {
156 HDF_LOGI("%{public}s: start", __func__);
157 session_->keyIdAndKeyValue_.clear();
158 if (session_->keyIdAndKeyValue_.size() != 0) {
159 return HDF_FAILURE;
160 }
161 if (vdiCallbackObj != nullptr) {
162 std::string eventData = "KEY EXPIRED";
163 std::vector<uint8_t> data(eventData.begin(), eventData.end());
164 vdiCallbackObj->SendEvent(EVENTTYPE_KEYEXPIRED, 0, data);
165 }
166 HDF_LOGI("%{public}s: end", __func__);
167 return HDF_SUCCESS;
168 }
169
GetOfflineReleaseRequest(const std::vector<uint8_t> & licenseId,std::vector<uint8_t> & releaseRequest)170 int32_t MediaKeySessionService::GetOfflineReleaseRequest(const std::vector<uint8_t> &licenseId,
171 std::vector<uint8_t> &releaseRequest)
172 {
173 HDF_LOGI("%{public}s: start", __func__);
174 releaseRequest.clear();
175 std::string requestJson;
176 std::vector<std::vector<uint8_t>> keyIds;
177 keyIds.push_back(licenseId);
178 if (generateRequest(MEDIA_KEY_TYPE_OFFLINE, keyIds, &requestJson) != HDF_SUCCESS) {
179 HDF_LOGE("%{public}s: generateRequest failed", __func__);
180 return HDF_ERR_INVALID_PARAM;
181 }
182 releaseRequest = std::vector<uint8_t>(requestJson.begin(), requestJson.end());
183 HDF_LOGI("%{public}s: end", __func__);
184 return HDF_SUCCESS;
185 }
186
ProcessOfflineReleaseResponse(const std::vector<uint8_t> & licenseId,const std::vector<uint8_t> & response)187 int32_t MediaKeySessionService::ProcessOfflineReleaseResponse(const std::vector<uint8_t> &licenseId,
188 const std::vector<uint8_t> &response)
189 {
190 HDF_LOGI("%{public}s: start", __func__);
191 std::string releaseResponseData(response.begin(), response.end());
192 HDF_LOGI("%{public}s: response: %{public}s", __func__, releaseResponseData.c_str());
193 offlineKeyMutex_.lock();
194 int32_t ret = GetOfflineKeyFromFile();
195 if (ret != HDF_SUCCESS) {
196 offlineKeyMutex_.unlock();
197 return ret;
198 }
199 std::string keyIdString(licenseId.begin(), licenseId.end());
200 std::string keyIdBase64 = Encode(keyIdString);
201 auto it = offlineKeyIdAndKeyValueBase64_.find(keyIdBase64);
202 if (it != offlineKeyIdAndKeyValueBase64_.end()) {
203 session_->keyIdStatusMap[licenseId] = OFFLINE_MEDIA_KEY_STATUS_INACTIVE;
204 offlineKeyMutex_.unlock();
205 HDF_LOGI("%{public}s: end", __func__);
206 return HDF_SUCCESS;
207 }
208 offlineKeyMutex_.unlock();
209 HDF_LOGI("%{public}s: do not find offline license, keyId: %{public}s", __func__, licenseId.data());
210 HDF_LOGI("%{public}s: end", __func__);
211 return HDF_FAILURE;
212 }
213
RestoreOfflineMediaKeys(const std::vector<uint8_t> & licenseId)214 int32_t MediaKeySessionService::RestoreOfflineMediaKeys(const std::vector<uint8_t> &licenseId)
215 {
216 HDF_LOGI("%{public}s: start", __func__);
217 if (session_ == nullptr) {
218 return HDF_FAILURE;
219 }
220 offlineKeyMutex_.lock();
221 int32_t ret = GetOfflineKeyFromFile();
222 if (ret != HDF_SUCCESS) {
223 offlineKeyMutex_.unlock();
224 return ret;
225 }
226 std::string keyIdString(licenseId.begin(), licenseId.end());
227 std::string keyIdBase64 = Encode(keyIdString);
228 keyIdBase64.erase(std::remove(keyIdBase64.begin(), keyIdBase64.end(), '\0'), keyIdBase64.end());
229 if (offlineKeyIdAndKeyValueBase64_.find(keyIdBase64) == offlineKeyIdAndKeyValueBase64_.end()) {
230 offlineKeyMutex_.unlock();
231 HDF_LOGE("%{public}s: do not find offline license, licenseId: %{public}s", __func__, licenseId.data());
232 return HDF_FAILURE;
233 }
234 session_->keyIdStatusMap[licenseId] = OFFLINE_MEDIA_KEY_STATUS_USABLE;
235 std::string keyValueString = Decode(offlineKeyIdAndKeyValueBase64_[keyIdBase64]);
236 std::vector<uint8_t> value(keyValueString.begin(), keyValueString.end());
237 offlineKeyIdAndKeyValueBase64_.clear();
238 offlineKeyMutex_.unlock();
239 if (vdiCallbackObj != nullptr) {
240 std::string eventData = "KEY EXPIRATION UPDATE";
241 std::vector<uint8_t> data(eventData.begin(), eventData.end());
242 vdiCallbackObj->SendEvent(EVENTTYPE_EXPIRATIONUPDATE, 0, data);
243 }
244 HDF_LOGI("%{public}s: end", __func__);
245 return ret;
246 }
247
GetContentProtectionLevel(ContentProtectionLevel & level)248 int32_t MediaKeySessionService::GetContentProtectionLevel(ContentProtectionLevel &level)
249 {
250 HDF_LOGI("%{public}s: start", __func__);
251 level = level_;
252 HDF_LOGI("%{public}s: end", __func__);
253 return HDF_SUCCESS;
254 }
255
RequiresSecureDecoderModule(const std::string & mimeType,bool & required)256 int32_t MediaKeySessionService::RequiresSecureDecoderModule(const std::string &mimeType, bool &required)
257 {
258 HDF_LOGI("%{public}s: start", __func__);
259 required = false;
260 HDF_LOGI("%{public}s: end", __func__);
261 return HDF_SUCCESS;
262 }
263
SetCallback(const sptr<OHOS::HDI::Drm::V1_0::IMediaKeySessionCallback> & sessionCallback)264 int32_t MediaKeySessionService::SetCallback(const sptr<OHOS::HDI::Drm::V1_0::IMediaKeySessionCallback> &sessionCallback)
265 {
266 HDF_LOGI("%{public}s: start", __func__);
267 vdiCallbackObj = new (std::nothrow) MediaKeySessionCallbackService(sessionCallback);
268 if (vdiCallbackObj == nullptr) {
269 HDF_LOGE("new MediaKeySessionCallbackService() failed");
270 return HDF_ERR_MALLOC_FAIL;
271 }
272
273 HDF_LOGI("%{public}s: end", __func__);
274 return HDF_SUCCESS;
275 }
276
GetMediaDecryptModule(sptr<OHOS::HDI::Drm::V1_0::IMediaDecryptModule> & decryptModule)277 int32_t MediaKeySessionService::GetMediaDecryptModule(sptr<OHOS::HDI::Drm::V1_0::IMediaDecryptModule> &decryptModule)
278 {
279 HDF_LOGI("%{public}s: start", __func__);
280 if (decryptModule_ == nullptr) {
281 return HDF_FAILURE;
282 }
283 decryptModule = decryptModule_;
284 HDF_LOGI("%{public}s: end", __func__);
285 return HDF_SUCCESS;
286 }
287
Init()288 int32_t MediaKeySessionService::Init()
289 {
290 HDF_LOGI("%{public}s: start", __func__);
291 session_ = new (std::nothrow) Session();
292 if (session_ == nullptr) {
293 return HDF_ERR_MALLOC_FAIL;
294 }
295 decryptModule_ = new (std::nothrow) MediaDecryptModuleService(session_);
296 if (decryptModule_ == nullptr) {
297 HDF_LOGE("new MediaDecryptModuleService() failed");
298 return HDF_ERR_MALLOC_FAIL;
299 }
300
301 HDF_LOGI("%{public}s: end", __func__);
302 return HDF_SUCCESS;
303 }
304
Destroy()305 int32_t MediaKeySessionService::Destroy()
306 {
307 HDF_LOGI("%{public}s: start", __func__);
308 offlineKeyMutex_.lock();
309 offlineKeyIdAndKeyValueBase64_.clear();
310 offlineKeyMutex_.unlock();
311 if (sessionCallback_ != nullptr) {
312 sessionCallback_->CloseKeySessionService(this);
313 }
314 sessionCallback_ = nullptr;
315 HDF_LOGI("%{public}s: end", __func__);
316 return HDF_SUCCESS;
317 }
318
SetKeySessionServiceCallback(sptr<KeySessionServiceCallback> callback)319 int32_t MediaKeySessionService::SetKeySessionServiceCallback(sptr<KeySessionServiceCallback> callback)
320 {
321 HDF_LOGI("%{public}s: start", __func__);
322 if (callback == nullptr) {
323 HDF_LOGE("SetKeySessionServiceCallback callback is null");
324 return HDF_ERR_INVALID_PARAM;
325 }
326 sessionCallback_ = callback;
327 HDF_LOGI("%{public}s: end", __func__);
328 return HDF_SUCCESS;
329 }
330
GetDecryptNumber()331 int32_t MediaKeySessionService::GetDecryptNumber()
332 {
333 HDF_LOGI("%{public}s: start", __func__);
334 HDF_LOGI("%{public}s: end", __func__);
335 return decryptModule_->GetDecryptNumber();
336 }
337
GetDecryptMaxTimes(double time,std::vector<double> & topThreeTimes)338 void MediaKeySessionService::GetDecryptMaxTimes(double time, std::vector<double> &topThreeTimes)
339 {
340 if (topThreeTimes.size() < topThree) {
341 topThreeTimes.push_back(time);
342 } else {
343 auto minIt = std::min_element(topThreeTimes.begin(), topThreeTimes.end());
344 if (time > *minIt) {
345 *minIt = time;
346 }
347 }
348 if (topThreeTimes.size() > topThree) {
349 topThreeTimes.resize(topThree);
350 }
351
352 std::sort(topThreeTimes.begin(), topThreeTimes.end(), std::greater<int>());
353 }
354
GetDecryptTimes(std::vector<double> & topThreeTimes)355 int32_t MediaKeySessionService::GetDecryptTimes(std::vector<double> &topThreeTimes)
356 {
357 HDF_LOGI("%{public}s: start", __func__);
358 std::vector<double> times;
359 decryptModule_->GetDecryptTimes(times);
360 for (auto time : times) {
361 GetDecryptMaxTimes(time, topThreeTimes);
362 }
363 HDF_LOGI("%{public}s: end", __func__);
364 return HDF_SUCCESS;
365 }
366
GetErrorDecryptNumber()367 int32_t MediaKeySessionService::GetErrorDecryptNumber()
368 {
369 HDF_LOGI("%{public}s: start", __func__);
370 HDF_LOGI("%{public}s: end", __func__);
371 return decryptModule_->GetErrorDecryptNumber();
372 }
373
GetOfflineKeyFromFile()374 int32_t MediaKeySessionService::GetOfflineKeyFromFile()
375 {
376 HDF_LOGI("%{public}s: start", __func__);
377 FILE *offlineKeyFile = fopen(offlineKeyFileName, "r+");
378 if (offlineKeyFile == NULL) {
379 HDF_LOGE("%{public}s: open: \"%{public}s\" failed", __func__, offlineKeyFileName);
380 // file do not exist, is allright
381 return HDF_SUCCESS;
382 }
383 char keyIdBase64Chars[keyIdMaxLength];
384 char keyValueBase64Chars[keyIdMaxLength];
385 while (fscanf_s(offlineKeyFile, "%s %s", keyIdBase64Chars, sizeof(keyIdBase64Chars), keyValueBase64Chars,
386 sizeof(keyValueBase64Chars)) != EOF) {
387 std::string tempKeyIdBase64 = keyIdBase64Chars;
388 std::string tempKeyValueBase64 = keyValueBase64Chars;
389 tempKeyIdBase64.erase(std::remove(tempKeyIdBase64.begin(), tempKeyIdBase64.end(), '\0'), tempKeyIdBase64.end());
390 offlineKeyIdAndKeyValueBase64_[tempKeyIdBase64] = tempKeyValueBase64;
391 }
392 fclose(offlineKeyFile);
393 HDF_LOGI("%{public}s: end", __func__);
394 return HDF_SUCCESS;
395 }
396
SetOfflineKeyToFile()397 int32_t MediaKeySessionService::SetOfflineKeyToFile()
398 {
399 HDF_LOGI("%{public}s: start", __func__);
400 FILE *offlineKeyFile = fopen(offlineKeyFileName, "w+");
401 if (offlineKeyFile == NULL) {
402 offlineKeyIdAndKeyValueBase64_.clear();
403 HDF_LOGE("%{public}s: create failed, ret: %{public}s", __func__, strerror(errno));
404 return HDF_FAILURE;
405 }
406 for (auto &keyIdValueBase64Pair : offlineKeyIdAndKeyValueBase64_) {
407 fprintf(offlineKeyFile, "%s %s\n", keyIdValueBase64Pair.first.c_str(), keyIdValueBase64Pair.second.c_str());
408 fflush(offlineKeyFile);
409 }
410 offlineKeyIdAndKeyValueBase64_.clear();
411 fclose(offlineKeyFile);
412 HDF_LOGI("%{public}s: end", __func__);
413 return HDF_SUCCESS;
414 }
415 } // V1_0
416 } // Drm
417 } // HDI
418 } // OHOS
419