• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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