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