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