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
16 #include "local_code_sign_client.h"
17 #include <iservice_registry.h>
18 #include "cs_hisysevent.h"
19 #include "local_code_sign_proxy.h"
20 #include "local_code_sign_load_callback.h"
21 #include "log.h"
22
23 namespace OHOS {
24 namespace Security {
25 namespace CodeSign {
26 constexpr int32_t LOAD_SA_TIMEOUT_MS = 5000;
27
LocalCodeSignClient()28 LocalCodeSignClient::LocalCodeSignClient()
29 {
30 localCodeSignSvrRecipient_ = new (std::nothrow) LocalCodeSignSvrRecipient();
31 if (localCodeSignSvrRecipient_ == nullptr) {
32 LOG_ERROR(LABEL, "Create LocalCodeSignSvrRecipient failed.");
33 }
34 }
35
OnRemoteDied(const wptr<IRemoteObject> & remote)36 void LocalCodeSignClient::LocalCodeSignSvrRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
37 {
38 if (remote == nullptr) {
39 LOG_ERROR(LABEL, "OnRemoteDied remote is nullptr.");
40 return;
41 }
42 LOG_INFO(LABEL, "LocalCodeSignSvrRecipient OnRemoteDied.");
43 LocalCodeSignClient::GetInstance().OnRemoteLocalCodeSignSvrDied(remote);
44 }
45
StartSA()46 int32_t LocalCodeSignClient::StartSA()
47 {
48 std::unique_lock<std::mutex> lock(proxyMutex_);
49 LOG_DEBUG(LABEL, "Start LocalCodeSignService");
50 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
51 if (samgr == nullptr) {
52 LOG_ERROR(LABEL, "Get system ability mgr failed.");
53 return CS_ERR_SA_GET_SAMGR;
54 }
55 sptr<LocalCodeSignLoadCallback> loadCallback = new (std::nothrow) LocalCodeSignLoadCallback();
56 if (loadCallback == nullptr) {
57 return CS_ERR_MEMORY;
58 }
59 int32_t ret = samgr->LoadSystemAbility(LOCAL_CODE_SIGN_SA_ID, loadCallback);
60 if (ret != ERR_OK) {
61 LOG_ERROR(LABEL, "Load systemAbility failed, systemAbilityId:%{public}d ret code:%{public}d",
62 LOCAL_CODE_SIGN_SA_ID, ret);
63 return CS_ERR_SA_LOAD_FAILED;
64 }
65 LOG_INFO(LABEL, "To load system ability.");
66 auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS),
67 [this]() { return localCodeSignProxy_ != nullptr; });
68 if (!waitStatus) {
69 LOG_ERROR(LABEL, "code sign load SA timeout");
70 return CS_ERR_SA_LOAD_TIMEOUT;
71 }
72 LOG_INFO(LABEL, "code sign load SA successfully");
73 return CS_SUCCESS;
74 }
75
FinishStartSA(const sptr<IRemoteObject> & remoteObject)76 void LocalCodeSignClient::FinishStartSA(const sptr<IRemoteObject> &remoteObject)
77 {
78 LOG_DEBUG(LABEL, "LocalCodeSignClient FinishStartSA");
79 std::lock_guard<std::mutex> lock(proxyMutex_);
80 if (localCodeSignSvrRecipient_ == nullptr) {
81 LOG_ERROR(LABEL, "localCodeSignSvrRecipient_ is nullptr.");
82 return;
83 }
84 if (!remoteObject->AddDeathRecipient(localCodeSignSvrRecipient_)) {
85 LOG_ERROR(LABEL, "AddDeathRecipient failed");
86 }
87 localCodeSignProxy_ = iface_cast<LocalCodeSignInterface>(remoteObject);
88 if ((localCodeSignProxy_ == nullptr) || (localCodeSignProxy_->AsObject() == nullptr)) {
89 LOG_ERROR(LABEL, "Get code sign proxy failed.");
90 return;
91 }
92 proxyConVar_.notify_one();
93 }
94
FailStartSA()95 void LocalCodeSignClient::FailStartSA()
96 {
97 std::lock_guard<std::mutex> lock(proxyMutex_);
98 localCodeSignProxy_ = nullptr;
99 proxyConVar_.notify_one();
100 }
101
CheckLocalCodeSignProxy()102 void LocalCodeSignClient::CheckLocalCodeSignProxy()
103 {
104 {
105 std::lock_guard<std::mutex> lock(proxyMutex_);
106 if (localCodeSignProxy_ != nullptr) {
107 return;
108 }
109 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
110 if (samgr == nullptr) {
111 LOG_ERROR(LABEL, "Get system ability mgr failed.");
112 return;
113 }
114 auto remoteObject = samgr->CheckSystemAbility(LOCAL_CODE_SIGN_SA_ID);
115 if (remoteObject != nullptr) {
116 localCodeSignProxy_ = iface_cast<LocalCodeSignInterface>(remoteObject);
117 return;
118 }
119 }
120 int32_t ret = StartSA();
121 if (ret != CS_SUCCESS) {
122 ReportLoadSAError(ret);
123 }
124 }
125
InitLocalCertificate(ByteBuffer & cert)126 int32_t LocalCodeSignClient::InitLocalCertificate(ByteBuffer &cert)
127 {
128 LOG_DEBUG(LABEL, "InitLocalCertificate called");
129 CheckLocalCodeSignProxy();
130 std::lock_guard<std::mutex> lock(proxyMutex_);
131 if (localCodeSignProxy_ == nullptr) {
132 return CS_ERR_SA_GET_PROXY;
133 }
134 int32_t ret = localCodeSignProxy_->InitLocalCertificate(cert);
135 if (ret != CS_SUCCESS) {
136 LOG_ERROR(LABEL, "InitLocalCertificate err, error code = %{public}d", ret);
137 return ret;
138 }
139 return CS_SUCCESS;
140 }
141
SignLocalCode(const std::string & path,ByteBuffer & signature)142 int32_t LocalCodeSignClient::SignLocalCode(const std::string &path, ByteBuffer &signature)
143 {
144 LOG_DEBUG(LABEL, "SignLocalCode called");
145 CheckLocalCodeSignProxy();
146 std::lock_guard<std::mutex> lock(proxyMutex_);
147 if (localCodeSignProxy_ == nullptr) {
148 return CS_ERR_SA_GET_PROXY;
149 }
150 int32_t ret = localCodeSignProxy_->SignLocalCode(path, signature);
151 if (ret != CS_SUCCESS) {
152 LOG_ERROR(LABEL, "SignLocalCode err, error code = %{public}d", ret);
153 return ret;
154 }
155 LOG_INFO(LABEL, "SignLocalCode successfully");
156 return CS_SUCCESS;
157 }
158
OnRemoteLocalCodeSignSvrDied(const wptr<IRemoteObject> & remote)159 void LocalCodeSignClient::OnRemoteLocalCodeSignSvrDied(const wptr<IRemoteObject> &remote)
160 {
161 std::lock_guard<std::mutex> lock(proxyMutex_);
162 if (localCodeSignProxy_ == nullptr) {
163 LOG_ERROR(LABEL, "localCodeSignProxy_ is nullptr.");
164 return;
165 }
166 sptr<IRemoteObject> remoteObject = remote.promote();
167 if (remoteObject == nullptr) {
168 LOG_ERROR(LABEL, "OnRemoteDied remote promoted failed");
169 return;
170 }
171
172 if (localCodeSignProxy_->AsObject() != remoteObject) {
173 LOG_ERROR(LABEL, "OnRemoteLocalCodeSignSvrDied not found remote object.");
174 return;
175 }
176 localCodeSignProxy_->AsObject()->RemoveDeathRecipient(localCodeSignSvrRecipient_);
177 localCodeSignProxy_ = nullptr;
178 }
179
GetInstance()180 LocalCodeSignClient &LocalCodeSignClient::GetInstance()
181 {
182 static LocalCodeSignClient singleLocalCodeSignClient;
183 return singleLocalCodeSignClient;
184 }
185
GetLocalCodeSignClient()186 LocalCodeSignClient *GetLocalCodeSignClient()
187 {
188 return &LocalCodeSignClient::GetInstance();
189 }
190 }
191 }
192 }