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