• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 & ownerID,const std::string & path,ByteBuffer & signature)142 int32_t LocalCodeSignClient::SignLocalCode(const std::string &ownerID, 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(ownerID, 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 }