1 /*
2  * Copyright (c) 2022-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 "cm_sa.h"
17 
18 #include <pthread.h>
19 #include <unistd.h>
20 
21 #include "ipc_skeleton.h"
22 #include "iservice_registry.h"
23 #include "string_ex.h"
24 #include "system_ability_definition.h"
25 
26 #include "cert_manager.h"
27 #include "cm_event_observer.h"
28 #include "cm_event_process.h"
29 #include "cm_log.h"
30 #include "cm_mem.h"
31 #include "cm_ipc_service.h"
32 #include "ipc_skeleton.h"
33 #include "cert_manager_updateflag.h"
34 
35 namespace OHOS {
36 namespace Security {
37 namespace CertManager {
38 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&CertManagerService::GetInstance());
39 
40 const uint32_t MAX_MALLOC_LEN = 1 * 1024 * 1024; /* max malloc size 1 MB */
41 const uint32_t MAX_DELAY_TIMES = 100;
42 const uint32_t DELAY_INTERVAL = 200000; /* delay 200ms waiting for system event */
43 
44 const std::string TASK_ID = "unload";
45 const uint32_t DELAY_TIME = 180000; /* delay 180000ms to unload SA */
46 const std::string USER_REMOVED_EVENT = "usual.event.USER_REMOVED";
47 
48 constexpr int CM_IPC_THREAD_NUM = 32;
49 
50 using CmIpcHandlerFuncProc = void (*)(const struct CmBlob *msg, const CmContext *context);
51 
52 using CmIpcAppHandlerFuncProc = void (*)(const struct CmBlob *msg, struct CmBlob *outData,
53     const CmContext *context);
54 
55 struct CmIpcPoint {
56     CertManagerInterfaceCode msgId;
57     CmIpcAppHandlerFuncProc handler;
58 };
59 
60 static struct CmIpcPoint g_cmIpcHandler[] = {
61     { CM_MSG_INSTALL_APP_CERTIFICATE, CmIpcServiceInstallAppCert },
62     { CM_MSG_UNINSTALL_APP_CERTIFICATE, CmIpcServiceUninstallAppCert },
63     { CM_MSG_UNINSTALL_ALL_APP_CERTIFICATE, CmIpcServiceUninstallAllAppCert },
64     { CM_MSG_GET_APP_CERTIFICATE_LIST, CmIpcServiceGetAppCertList },
65     { CM_MSG_GET_CALLING_APP_CERTIFICATE_LIST, CmIpcServiceGetCallingAppCertList },
66     { CM_MSG_GET_APP_CERTIFICATE, CmIpcServiceGetAppCert },
67 
68     { CM_MSG_GRANT_APP_CERT, CmIpcServiceGrantAppCertificate },
69     { CM_MSG_GET_AUTHED_LIST, CmIpcServiceGetAuthorizedAppList },
70     { CM_MSG_CHECK_IS_AUTHED_APP, CmIpcServiceIsAuthorizedApp },
71     { CM_MSG_REMOVE_GRANT_APP, CmIpcServiceRemoveGrantedApp },
72     { CM_MSG_INIT, CmIpcServiceInit },
73     { CM_MSG_UPDATE, CmIpcServiceUpdate },
74     { CM_MSG_FINISH, CmIpcServiceFinish },
75     { CM_MSG_ABORT, CmIpcServiceAbort },
76 
77     { CM_MSG_GET_USER_CERTIFICATE_LIST, CmIpcServiceGetUserCertList },
78     { CM_MSG_GET_USER_CERTIFICATE_INFO, CmIpcServiceGetUserCertInfo },
79     { CM_MSG_SET_USER_CERTIFICATE_STATUS, CmIpcServiceSetUserCertStatus },
80     { CM_MSG_INSTALL_USER_CERTIFICATE, CmIpcServiceInstallUserCert },
81     { CM_MSG_UNINSTALL_USER_CERTIFICATE, CmIpcServiceUninstallUserCert },
82     { CM_MSG_UNINSTALL_ALL_USER_CERTIFICATE, CmIpcServiceUninstallAllUserCert },
83 
84     { CM_MSG_GET_CERTIFICATE_LIST, CmIpcServiceGetCertificateList },
85     { CM_MSG_GET_CERTIFICATE_INFO, CmIpcServiceGetCertificateInfo },
86     { CM_MSG_SET_CERTIFICATE_STATUS, CmIpcServiceSetCertStatus },
87 };
88 
SubscribEvent()89 static void SubscribEvent()
90 {
91     for (uint32_t i = 0; i < MAX_DELAY_TIMES; ++i) {
92         if (SystemEventObserver::SubscribeSystemEvent()) {
93             CM_LOG_D("subscribe system event success, i = %u", i);
94             return;
95         } else {
96             CM_LOG_E("subscribe system event failed %u times", i);
97             usleep(DELAY_INTERVAL);
98         }
99     }
100     CM_LOG_E("subscribe system event failed");
101     return;
102 }
103 
CmSubscribeSystemEvent()104 static void CmSubscribeSystemEvent()
105 {
106     pthread_t subscribeThread;
107     if ((pthread_create(&subscribeThread, nullptr, (void *(*)(void *))SubscribEvent, nullptr)) == -1) {
108         CM_LOG_E("create thread failed");
109         return;
110     }
111 
112     CM_LOG_D("create thread success");
113 }
114 
IsInvalidLength(uint32_t length)115 static inline bool IsInvalidLength(uint32_t length)
116 {
117     return (length == 0) || (length > MAX_MALLOC_LEN);
118 }
119 
ProcessMessage(uint32_t code,uint32_t outSize,const struct CmBlob & srcData,MessageParcel & reply)120 static int32_t ProcessMessage(uint32_t code, uint32_t outSize, const struct CmBlob &srcData, MessageParcel &reply)
121 {
122     uint32_t size = sizeof(g_cmIpcHandler) / sizeof(g_cmIpcHandler[0]);
123     for (uint32_t i = 0; i < size; ++i) {
124         if (code != static_cast<uint32_t>(g_cmIpcHandler[i].msgId)) {
125             continue;
126         }
127         struct CmBlob outData = { 0, nullptr };
128         if (outSize != 0) {
129             outData.size = outSize;
130             if (outData.size > MAX_MALLOC_LEN) {
131                 CM_LOG_E("outData size is invalid, size:%u", outData.size);
132                 return CM_SYSTEM_ERROR;
133             }
134             outData.data = static_cast<uint8_t *>(CmMalloc(outData.size));
135             if (outData.data == nullptr) {
136                 CM_LOG_E("Malloc outData failed.");
137                 return CM_SYSTEM_ERROR;
138             }
139             (void)memset_s(outData.data, outData.size, 0, outData.size);
140         }
141         g_cmIpcHandler[i].handler(static_cast<const struct CmBlob *>(&srcData), &outData,
142             reinterpret_cast<const struct CmContext *>(&reply));
143         CM_FREE_BLOB(outData);
144         break;
145     }
146 
147     return NO_ERROR;
148 }
149 
CertManagerService()150 CertManagerService::CertManagerService()
151     : SystemAbility(SA_ID_KEYSTORE_SERVICE, true), registerToService_(false), runningState_(STATE_NOT_START)
152 {
153     CM_LOG_D("CertManagerService");
154 }
155 
~CertManagerService()156 CertManagerService::~CertManagerService()
157 {
158     CM_LOG_D("~CertManagerService");
159 }
160 
Init()161 bool CertManagerService::Init()
162 {
163     CM_LOG_D("CertManagerService::Init Ready to init");
164 
165     if (!registerToService_) {
166         if (unloadHandler == nullptr) {
167             auto runner = AppExecFwk::EventRunner::Create("unload");
168             unloadHandler = std::make_shared<AppExecFwk::EventHandler>(runner);
169         }
170 
171         DelayUnload();
172         if (!Publish(this)) {
173             CM_LOG_E("CertManagerService::Init Publish Failed");
174             return false;
175         }
176         CM_LOG_D("CertManagerService::Init Publish service success");
177         registerToService_ = true;
178     }
179 
180     CM_LOG_D("CertManagerService::Init success.");
181     return true;
182 }
183 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)184 int CertManagerService::OnRemoteRequest(uint32_t code, MessageParcel &data,
185     MessageParcel &reply, MessageOption &option)
186 {
187     // this is the temporary version which comments the descriptor check
188     std::u16string descriptor = CertManagerService::GetDescriptor();
189     std::u16string remoteDescriptor = data.ReadInterfaceToken();
190     if (descriptor != remoteDescriptor) {
191         CM_LOG_E("descriptor is diff");
192         return CM_SYSTEM_ERROR;
193     }
194 
195     // check the code is valid
196     if (code < static_cast<uint32_t>(CM_MSG_BASE) || code >= static_cast<uint32_t>(CM_MSG_MAX)) {
197         return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
198     }
199 
200     DelayUnload();
201     uint32_t outSize = static_cast<uint32_t>(data.ReadUint32());
202     struct CmBlob srcData = { 0, nullptr };
203     srcData.size = static_cast<uint32_t>(data.ReadUint32());
204     if (IsInvalidLength(srcData.size)) {
205         CM_LOG_E("srcData size is invalid, size:%u", srcData.size);
206         return CM_SYSTEM_ERROR;
207     }
208 
209     srcData.data = static_cast<uint8_t *>(CmMalloc(srcData.size));
210     if (srcData.data == nullptr) {
211         CM_LOG_E("Malloc srcData failed.");
212         return CM_SYSTEM_ERROR;
213     }
214     const uint8_t *pdata = data.ReadBuffer(static_cast<size_t>(srcData.size));
215     if (pdata == nullptr) {
216         CM_FREE_BLOB(srcData);
217         CM_LOG_E("CMR_ERROR_NULL_POINTER");
218         return CMR_ERROR_NULL_POINTER;
219     }
220     if (memcpy_s(srcData.data, srcData.size, pdata, srcData.size) != EOK) {
221         CM_LOG_E("copy remote data failed!");
222         CM_FREE_BLOB(srcData);
223         return CMR_ERROR_INVALID_OPERATION;
224     }
225     if (ProcessMessage(code, outSize, srcData, reply) != NO_ERROR) {
226         CM_LOG_E("process message!");
227         CM_FREE_BLOB(srcData);
228         CM_LOG_E("copy remote data failed!");
229         return CMR_ERROR_INVALID_OPERATION;
230     }
231     CM_FREE_BLOB(srcData);
232     return NO_ERROR;
233 }
234 
OnStart(const SystemAbilityOnDemandReason & startReason)235 void CertManagerService::OnStart(const SystemAbilityOnDemandReason& startReason)
236 {
237     CM_LOG_D("CertManagerService OnStart startReason");
238 
239     if (runningState_ == STATE_RUNNING) {
240         CM_LOG_D("CertManagerService has already Started");
241         return;
242     }
243 
244     if (CertManagerInitialize() != CMR_OK) {
245         CM_LOG_E("Failed to init CertManagerService");
246         return;
247     }
248     CM_LOG_D("CertManager init success");
249 
250     if (!Init()) {
251         CM_LOG_E("Failed to init CertManagerService");
252         return;
253     }
254 
255     CM_LOG_D("certmanager start reason %s", startReason.GetName().c_str());
256     if (startReason.GetId() == OnDemandReasonId::COMMON_EVENT &&
257         startReason.GetName() == USER_REMOVED_EVENT) {
258         struct CmContext context = { 0, INVALID_VALUE, {0} };
259         context.userId = (uint32_t)startReason.GetExtraData().GetCode();
260         CM_LOG_D("user remove event, userId = %u", context.userId);
261         CmDeleteProcessInfo(&context);
262     }
263 
264     IPCSkeleton::SetMaxWorkThreadNum(CM_IPC_THREAD_NUM);
265     (void)AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
266 
267     runningState_ = STATE_RUNNING;
268     CM_LOG_D("CertManagerService start success.");
269 
270     (void)CmBackupAllSaUserCerts();
271 }
272 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)273 void CertManagerService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
274 {
275     CM_LOG_D("systemAbilityId is %d!", systemAbilityId);
276     CmSubscribeSystemEvent();
277 }
278 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)279 void CertManagerService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
280 {
281     CM_LOG_D("systemAbilityId is %d!", systemAbilityId);
282 }
283 
OnStop()284 void CertManagerService::OnStop()
285 {
286     CM_LOG_D("CertManagerService Service OnStop");
287     runningState_ = STATE_NOT_START;
288     registerToService_ = false;
289 }
290 
DelayUnload()291 void CertManagerService::DelayUnload()
292 {
293     auto unloadTask = []() {
294         CM_LOG_D("do unload task");
295         auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
296         if (saManager == nullptr) {
297             CM_LOG_E("Failed to get saManager");
298             return;
299         }
300 
301         int32_t ret = saManager->UnloadSystemAbility(SA_ID_KEYSTORE_SERVICE);
302         if (ret != ERR_OK) {
303             CM_LOG_E("Failed to remove system ability");
304             return;
305         }
306     };
307 
308     unloadHandler->RemoveTask(TASK_ID);
309     unloadHandler->PostTask(unloadTask, TASK_ID, DELAY_TIME);
310 }
311 
GetInstance()312 CertManagerService& CertManagerService::GetInstance()
313 {
314     static auto instance = new CertManagerService();
315     return *instance;
316 }
317 } // namespace CertManager
318 } // namespace Security
319 } // namespace OHOS
320