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 "hce_session_stub.h"
17
18 #include "hce_cmd_death_recipient.h"
19 #include "ipc_skeleton.h"
20 #include "loghelper.h"
21 #include "nfc_sdk_common.h"
22 #include "nfc_service_ipc_interface_code.h"
23 #include "hce_cmd_callback_proxy.h"
24 #include "nfc_permission_checker.h"
25 #include "external_deps_proxy.h"
26 #include "ce_payment_services_parcelable.h"
27 #include "ability_info.h"
28 #include "accesstoken_kit.h"
29 #include "hap_token_info.h"
30
31 namespace OHOS {
32 namespace NFC {
33 namespace HCE {
34 using AppExecFwk::AbilityInfo;
OnRemoteRequest(uint32_t code,OHOS::MessageParcel & data,OHOS::MessageParcel & reply,OHOS::MessageOption & option)35 int HceSessionStub::OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data, OHOS::MessageParcel &reply,
36 OHOS::MessageOption &option)
37 {
38 DebugLog("hceSessionStub OnRemoteRequest occur, code is %d", code);
39 if (data.ReadInterfaceToken() != GetDescriptor()) {
40 ErrorLog("hceSessionStub OnRemoteRequest GetDescriptor failed");
41 return KITS::ErrorCode::ERR_HCE_PARAMETERS;
42 }
43
44 switch (code) {
45 case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_CE_HCE_ON):
46 return HandleRegHceCmdCallback(data, reply);
47 case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_CE_HCE_TRANSMIT):
48 return HandleSendRawFrame(data, reply);
49 case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_CE_HCE_GET_PAYMENT_SERVICES):
50 return HandleGetPaymentServices(data, reply);
51 case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_CE_HCE_STOP):
52 return HandleStopHce(data, reply);
53 case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_CE_HCE_IS_DEFAULT_SERVICE):
54 return HandleIsDefaultService(data, reply);
55 case static_cast<uint32_t>(NfcServiceIpcInterfaceCode::COMMAND_CE_HCE_START):
56 return HandleStartHce(data, reply);
57 default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
58 }
59 }
60
HandleRegHceCmdCallback(MessageParcel & data,MessageParcel & reply)61 int HceSessionStub::HandleRegHceCmdCallback(MessageParcel &data, MessageParcel &reply)
62 {
63 if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
64 ErrorLog("HandleRegHceCmdCallback, ERR_NO_PERMISSION");
65 return KITS::ErrorCode::ERR_NO_PERMISSION;
66 }
67 std::string type = data.ReadString();
68 int exception = data.ReadInt32();
69 if (exception) {
70 return KITS::ERR_NFC_PARAMETERS;
71 }
72 KITS::ErrorCode ret = KITS::ERR_NFC_PARAMETERS;
73 do {
74 sptr<IRemoteObject> remote = data.ReadRemoteObject();
75 if (remote == nullptr) {
76 DebugLog("Failed to readRemoteObject!");
77 break;
78 }
79 std::unique_ptr<HceCmdDeathRecipient> recipient =
80 std::make_unique<HceCmdDeathRecipient>(this, IPCSkeleton::GetCallingTokenID());
81 sptr<IRemoteObject::DeathRecipient> dr(recipient.release());
82 if ((remote->IsProxyObject()) && (!remote->AddDeathRecipient(dr))) {
83 ErrorLog("Failed to add death recipient");
84 return ERR_NONE;
85 }
86 {
87 std::lock_guard<std::mutex> guard(mutex_);
88 deathRecipient_ = dr;
89 hceCmdCallback_ = iface_cast<KITS::IHceCmdCallback>(remote);
90 if (hceCmdCallback_ == nullptr) {
91 hceCmdCallback_ = new (std::nothrow) HceCmdCallbackProxy(remote);
92 DebugLog("create new `HceCmdCallbackProxy`!");
93 }
94 ret = RegHceCmdCallback(hceCmdCallback_, type);
95 }
96 } while (0);
97 reply.WriteInt32(ret);
98 return ERR_NONE;
99 }
HandleSendRawFrame(OHOS::MessageParcel & data,OHOS::MessageParcel & reply)100 int HceSessionStub::HandleSendRawFrame(OHOS::MessageParcel &data, OHOS::MessageParcel &reply)
101 {
102 if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
103 ErrorLog("HandleSendRawFrame, ERR_NO_PERMISSION");
104 return KITS::ErrorCode::ERR_NO_PERMISSION;
105 }
106
107 std::string hexCmdData = data.ReadString();
108 if (hexCmdData.size() > KITS::MAX_APDU_DATA_HEX_STR) {
109 ErrorLog("raw frame too long");
110 return KITS::ErrorCode::ERR_HCE_PARAMETERS;
111 }
112 bool raw = data.ReadBool();
113 std::string hexRespData;
114 int statusCode = SendRawFrame(hexCmdData, raw, hexRespData);
115 reply.WriteString(hexRespData);
116 return statusCode;
117 }
HandleGetPaymentServices(MessageParcel & data,MessageParcel & reply)118 int HceSessionStub::HandleGetPaymentServices(MessageParcel &data, MessageParcel &reply)
119 {
120 if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
121 ErrorLog("HandleGetPaymentServices, ERR_NO_PERMISSION");
122 return KITS::ErrorCode::ERR_NO_PERMISSION;
123 }
124
125 if (!ExternalDepsProxy::GetInstance().IsSystemApp(IPCSkeleton::GetCallingUid())) {
126 ErrorLog("HandleGetPaymentServices, ERR_NOT_SYSTEM_APP");
127 return KITS::ErrorCode::ERR_NOT_SYSTEM_APP;
128 }
129 int exception = data.ReadInt32();
130 if (exception) {
131 ErrorLog("HandleGetPaymentServices, exception");
132 return KITS::ERR_NFC_PARAMETERS;
133 }
134 std::vector<AbilityInfo> abilityInfos;
135 int result = GetPaymentServices(abilityInfos);
136 if (result != NFC::KITS::ErrorCode::ERR_NONE) {
137 ErrorLog("HandleGetPaymentServices, get payment service failed");
138 return KITS::ErrorCode::ERR_HCE_NOT_GET_PAYMENT_SERVICES;
139 }
140 KITS::CePaymentServicesParcelable paymentServiceMsg;
141 paymentServiceMsg.paymentAbilityInfos = abilityInfos;
142 if (!reply.WriteParcelable(&paymentServiceMsg)) {
143 ErrorLog("HandleGetPaymentServices, write payment service failed");
144 return KITS::ErrorCode::ERR_HCE_PARAMETERS;
145 }
146 return ERR_NONE;
147 }
148
HandleStopHce(MessageParcel & data,MessageParcel & reply)149 int HceSessionStub::HandleStopHce(MessageParcel &data, MessageParcel &reply)
150 {
151 if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
152 ErrorLog("HandleStopHce, ERR_NO_PERMISSION");
153 return KITS::ErrorCode::ERR_NO_PERMISSION;
154 }
155 InfoLog("HandleStopHce");
156 ElementName *element = ElementName::Unmarshalling(data);
157 if (element == nullptr) {
158 ErrorLog("HandleStopHce, unmarshalled element is null");
159 return KITS::ERR_HCE_PARAMETERS;
160 }
161 int exception = data.ReadInt32();
162 if (exception) {
163 // element is newed by Unmarshalling, should be deleted
164 delete element;
165 element = nullptr;
166 return KITS::ERR_HCE_PARAMETERS;
167 }
168 KITS::ErrorCode ret = StopHce(*(element));
169 DebugLog("HandleStopHce end##ret=%{public}d\n", ret);
170 reply.WriteInt32(ret);
171
172 // element is newed by Unmarshalling, should be deleted
173 delete element;
174 element = nullptr;
175 return ERR_NONE;
176 }
177
HandleStartHce(MessageParcel & data,MessageParcel & reply)178 int HceSessionStub::HandleStartHce(MessageParcel &data, MessageParcel &reply)
179 {
180 if (!ExternalDepsProxy::GetInstance().IsGranted(OHOS::NFC::CARD_EMU_PERM)) {
181 ErrorLog("HandleStartHce, ERR_NO_PERMISSION");
182 return KITS::ErrorCode::ERR_NO_PERMISSION;
183 }
184 InfoLog("HandleStartHce");
185 std::shared_ptr<KITS::StartHceInfoParcelable> startHceInfo = std::make_shared<KITS::StartHceInfoParcelable>(data);
186 if (startHceInfo == nullptr) {
187 ErrorLog("HandleStartHce, unmarshalled satrtHceInfo is null");
188 return KITS::ERR_HCE_PARAMETERS;
189 }
190 int exception = data.ReadInt32();
191 if (exception) {
192 ErrorLog("HandleStartHce, unmarshalled exception ");
193 return KITS::ERR_HCE_PARAMETERS;
194 }
195 KITS::ErrorCode ret = StartHceInner(startHceInfo);
196 DebugLog("HandleStartHce end##ret=%{public}d\n", ret);
197 reply.WriteInt32(ret);
198 return ERR_NONE;
199 }
200
StartHceInner(std::shared_ptr<KITS::StartHceInfoParcelable> startHceInfo)201 KITS::ErrorCode HceSessionStub::StartHceInner(std::shared_ptr<KITS::StartHceInfoParcelable> startHceInfo)
202 {
203 Security::AccessToken::HapTokenInfo hapTokenInfo;
204 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
205 int result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callerToken, hapTokenInfo);
206
207 InfoLog("get hap token info, result = %{public}d", result);
208 if (result) {
209 return KITS::ERR_HCE_PARAMETERS;
210 }
211 if (hapTokenInfo.bundleName.empty()) {
212 ErrorLog("StartHce: not got bundle name");
213 return KITS::ERR_HCE_PARAMETERS;
214 }
215 ElementName element = startHceInfo->GetElement();
216 std::vector<std::string> aids = startHceInfo->GetAids();
217 if (hapTokenInfo.bundleName != element.GetBundleName()) {
218 ErrorLog("StartHce: wrong bundle name");
219 return KITS::ERR_HCE_PARAMETERS;
220 }
221 return StartHce(element, aids);
222 }
223
HandleIsDefaultService(MessageParcel & data,MessageParcel & reply)224 int HceSessionStub::HandleIsDefaultService(MessageParcel &data, MessageParcel &reply)
225 {
226 InfoLog("HandleIsDefaultService");
227 ElementName *element = ElementName::Unmarshalling(data);
228 if (element == nullptr) {
229 ErrorLog("HandleIsDefaultService, unmarshalled element is null");
230 return KITS::ERR_HCE_PARAMETERS;
231 }
232
233 std::string type = data.ReadString();
234
235 int exception = data.ReadInt32();
236 if (exception) {
237 // element is newed by Unmarshalling, should be deleted
238 delete element;
239 element = nullptr;
240 return KITS::ERR_HCE_PARAMETERS;
241 }
242 bool isDefaultService = false;
243 KITS::ErrorCode ret = IsDefaultService(*(element), type, isDefaultService);
244 DebugLog("HandleIsDefaultService end##ret=%{public}d\n", ret);
245 reply.WriteBool(isDefaultService);
246 // element is newed by Unmarshalling, should be deleted
247 delete element;
248 element = nullptr;
249 return ERR_NONE;
250 }
RegHceCmdCallback(const sptr<KITS::IHceCmdCallback> & callback,const std::string & type)251 KITS::ErrorCode HceSessionStub::RegHceCmdCallback(const sptr<KITS::IHceCmdCallback> &callback,
252 const std::string &type)
253 {
254 return RegHceCmdCallbackByToken(callback, type, IPCSkeleton::GetCallingTokenID());
255 }
256
SendRawFrame(std::string hexCmdData,bool raw,std::string & hexRespData)257 int HceSessionStub::SendRawFrame(std::string hexCmdData, bool raw, std::string &hexRespData)
258 {
259 return SendRawFrameByToken(hexCmdData, raw, hexRespData, IPCSkeleton::GetCallingTokenID());
260 }
261
StopHce(ElementName & element)262 KITS::ErrorCode HceSessionStub::StopHce(ElementName &element)
263 {
264 Security::AccessToken::HapTokenInfo hapTokenInfo;
265 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
266 int result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callerToken, hapTokenInfo);
267
268 InfoLog("get hap token info, result = %{public}d", result);
269 if (result) {
270 return KITS::ERR_HCE_PARAMETERS;
271 }
272 if (hapTokenInfo.bundleName.empty()) {
273 ErrorLog("StopHce: not got bundle name");
274 return KITS::ERR_HCE_PARAMETERS;
275 }
276 if (hapTokenInfo.bundleName != element.GetBundleName()) {
277 ErrorLog("StopHce: wrong bundle name");
278 return KITS::ERR_HCE_PARAMETERS;
279 }
280
281 return StopHce(element, IPCSkeleton::GetCallingTokenID());
282 }
283
RemoveHceDeathRecipient(const wptr<IRemoteObject> & remote)284 void HceSessionStub::RemoveHceDeathRecipient(const wptr<IRemoteObject> &remote)
285 {
286 std::lock_guard<std::mutex> guard(mutex_);
287 if (hceCmdCallback_ == nullptr) {
288 ErrorLog("hce OnRemoteDied callback_ is nullptr");
289 return;
290 }
291 auto serviceRemote = hceCmdCallback_->AsObject();
292 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
293 serviceRemote->RemoveDeathRecipient(deathRecipient_);
294 hceCmdCallback_ = nullptr;
295 ErrorLog("hce on remote died");
296 }
297 }
298 } // namespace HCE
299 } // namespace NFC
300 } // namespace OHOS
301