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