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