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