Fix the Prevent problems
[platform/core/connectivity/smartcard-service.git] / common / GPARAM.cpp
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /* standard library header */
18
19 /* SLP library header */
20
21 /* local header */
22 #include "Debug.h"
23 #include "GPARAM.h"
24 #include "APDUHelper.h"
25 #include "FileObject.h"
26 #include "NumberStream.h"
27 #include "SimpleTLV.h"
28 #include "ISO7816BERTLV.h"
29 #include "AccessCondition.h"
30
31 #ifndef EXTERN_API
32 #define EXTERN_API __attribute__((visibility("default")))
33 #endif
34
35 namespace smartcard_service_api
36 {
37         static unsigned char aid_aram[] = { 0xA0, 0x00, 0x00, 0x01, 0x51, 0x41, 0x43, 0x4C, 00 };
38         static ByteArray AID_ARAM(ARRAY_AND_SIZE(aid_aram));
39
40 #define GET_DATA_ALL            0
41 #define GET_DATA_SPECIFIC       1
42 #define GET_DATA_REFRESH_TAG    2
43 #define GET_DATA_NEXT           3
44
45 #define ARAM_TAG_ALL_AR         0x0000FF40
46 #define ARAM_TAG_AR             0x0000FF50
47 #define ARAM_TAG_REFRESH        0x0000DF20
48
49 #define DO_TAG_AID_REF          0x0000004F
50 #define DO_TAG_AID_REF_DEFAULT  0x000000C0
51 #define DO_TAG_HASH_REF         0x000000C1
52 #define DO_TAG_APDU_AR          0x000000D0
53 #define DO_TAG_NFC_AR           0x000000D1
54 #define DO_TAG_REF              0x000000E1
55 #define DO_TAG_REF_AR           0x000000E2
56 #define DO_TAG_AR               0x000000E3
57
58         GPARAM::GPARAM(Channel *channel)
59                 : FileObject(channel)
60         {
61         }
62
63         int GPARAM::select()
64         {
65                 return FileObject::select(AID_ARAM);
66         }
67
68         static int doTransmit(Channel *channel, const ByteArray &command, ByteArray &response)
69         {
70                 int result;
71                 ByteArray resp;
72
73                 _BEGIN();
74
75                 result = channel->transmitSync(command, resp);
76                 if (result == SCARD_ERROR_OK) {
77                         result = ResponseHelper::getStatus(resp);
78                         if (result >= SCARD_ERROR_OK) {
79                                 response = ResponseHelper::getDataField(resp);
80                                 _DBG("response[%d] : %s", response.size(), response.toString().c_str());
81                         } else {
82                                 _ERR("transmit returns error, [%d]", result);
83                         }
84                 } else {
85                         _ERR("transmitSync failed, [%d]", result);
86                 }
87
88                 _END();
89
90                 return result;
91         }
92
93         static int doCommand(Channel *channel, int command, ByteArray &response)
94         {
95                 int result;
96                 APDUCommand helper;
97                 ByteArray cmd, resp;
98
99                 _BEGIN();
100
101                 switch (command) {
102                 case GET_DATA_ALL :
103                         helper.setCommand(0x80, 0xCA, 0xFF, 0x40, ByteArray::EMPTY, 0);
104                         break;
105
106                 case GET_DATA_REFRESH_TAG :
107                         helper.setCommand(0x80, 0xCA, 0xDF, 0x20, ByteArray::EMPTY, 0);
108                         break;
109
110                 case GET_DATA_NEXT :
111                         helper.setCommand(0x80, 0xCA, 0xFF, 0x60, ByteArray::EMPTY, 0);
112                         break;
113                 }
114
115                 helper.getBuffer(cmd);
116
117                 _DBG("command[%d] : %s", cmd.size(), cmd.toString().c_str());
118
119                 result = doTransmit(channel, cmd, response);
120
121                 _END();
122
123                 return result;
124         }
125
126         static int doCommand(Channel *channel, ByteArray &data, ByteArray &response)
127         {
128                 int result;
129                 APDUCommand helper;
130                 ByteArray cmd;
131
132                 helper.setCommand(0x80, 0xCA, 0xFF, 0x50, data, 0);
133                 helper.getBuffer(cmd);
134
135                 result = doTransmit(channel, cmd, response);
136
137                 return result;
138         }
139
140         int GPARAM::getDataAll(ByteArray &data)
141         {
142                 int result;
143                 ByteArray response;
144
145                 _BEGIN();
146
147                 result = doCommand(channel, GET_DATA_ALL, response);
148                 if (result >= SCARD_ERROR_OK) {
149                         ISO7816BERTLV tlv(response);
150
151                         if (tlv.decodeTLV() == true &&
152                                 tlv.getTag() == ARAM_TAG_ALL_AR) {
153                                 unsigned int length = tlv.size();
154
155                                 if (length > 0){
156                                         data = tlv.getValue();
157
158                                         while (length > data.size()) {
159                                                 result = doCommand(channel, GET_DATA_NEXT, response);
160                                                 if (result >= SCARD_ERROR_OK) {
161                                                         data += response;
162                                                 } else {
163                                                         _ERR("generateCommand failed, [%d]", result);
164                                                         data.clear();
165                                                         break;
166                                                 }
167                                         }
168
169                                         _DBG("data[%d] : %s", data.size(), data.toString().c_str());
170                                 } else {
171                                         _INFO("Response-ALL-AR-DO is empty");
172                                         data.clear();
173                                 }
174                         } else {
175                                 _ERR("decodeTLV failed, %s", response.toString().c_str());
176                                 result = SCARD_ERROR_ILLEGAL_PARAM;
177                         }
178                 } else {
179                         _ERR("generateCommand failed, [%d]", result);
180                 }
181
182                 _END();
183
184                 return result;
185         }
186
187         static int createRefDo(const ByteArray &aid, const ByteArray &hash, ByteArray &refDo)
188         {
189                 ByteArray temp;
190
191                 temp = SimpleTLV::encode(DO_TAG_AID_REF, aid);
192                 temp += SimpleTLV::encode(DO_TAG_HASH_REF, hash);
193
194                 refDo = SimpleTLV::encode(DO_TAG_REF, temp);
195                 _DBG("encoded Ref DO : %s", refDo.toString().c_str());
196
197                 return SCARD_ERROR_OK;
198         }
199
200         int GPARAM::getDataSpecific(const ByteArray &aid, const ByteArray &hash,
201                 ByteArray &data)
202         {
203                 int result;
204                 ByteArray refDo, response;
205
206                 _BEGIN();
207
208                 createRefDo(aid, hash, refDo);
209
210                 result = doCommand(channel, refDo, response);
211                 if (result >= SCARD_ERROR_OK) {
212                         ISO7816BERTLV tlv(response);
213
214                         if (tlv.decodeTLV() == true &&
215                                 tlv.getTag() == ARAM_TAG_AR) {
216                                 unsigned int length = tlv.size();
217
218                                 if (length > 0){
219                                         data = tlv.getValue();
220
221                                         while (length > data.size()) {
222                                                 result = doCommand(channel, GET_DATA_NEXT, response);
223                                                 if (result >= SCARD_ERROR_OK) {
224                                                         data += response;
225                                                 } else {
226                                                         _ERR("generateCommand failed, [%d]", result);
227                                                         data.clear();
228                                                         break;
229                                                 }
230                                         }
231                                         _DBG("data[%d] : %s", data.size(), data.toString().c_str());
232                                 } else {
233                                         _INFO("Response-ALL-AR-DO is empty");
234                                         data.clear();
235                                 }
236                         } else {
237                                 _ERR("decodeTLV failed, %s", response.toString().c_str());
238                                 result = SCARD_ERROR_ILLEGAL_PARAM;
239                         }
240                 } else {
241                         _ERR("doCommand failed, [%d]", result);
242                 }
243
244                 _END();
245
246                 return result;
247         }
248
249         int GPARAM::getDataRefreshTag(ByteArray &tag)
250         {
251                 int result;
252                 ByteArray response;
253
254                 _BEGIN();
255
256                 result = doCommand(channel, GET_DATA_REFRESH_TAG, response);
257                 if (result >= SCARD_ERROR_OK) {
258                         ISO7816BERTLV tlv(response);
259
260                         if (tlv.decodeTLV() == true &&
261                                 tlv.getTag() == ARAM_TAG_REFRESH &&
262                                 tlv.size() == 8) {
263                                 tag = tlv.getValue();
264                                 result = SCARD_ERROR_OK;
265                                 _DBG("refreshTag[%d] : %s", tag.size(), tag.toString().c_str());
266                         } else {
267                                 _ERR("decodeTLV failed, %s", response.toString().c_str());
268                                 result = SCARD_ERROR_ILLEGAL_PARAM;
269                         }
270                 } else {
271                         _ERR("generateCommand failed, [%d]", result);
272                 }
273
274                 _END();
275
276                 return result;
277         }
278 } /* namespace smartcard_service_api */