update the latest source
[framework/system/smartcard-service.git] / common / GPSEACL.cpp
1 /*
2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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
18 /* standard library header */
19
20 /* SLP library header */
21
22 /* local header */
23 #include "Debug.h"
24 #include "GPSEACL.h"
25 #include "PKCS15ODF.h"
26 #include "PKCS15DODF.h"
27 #include "NumberStream.h"
28 #include "SimpleTLV.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 oid_globalplatform[] = { 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x81, 0x48, 0x01, 0x01 };
38         ByteArray GPSEACL::OID_GLOBALPLATFORM(ARRAY_AND_SIZE(oid_globalplatform));
39
40         GPSEACL::GPSEACL(Channel *channel):AccessControlList(channel)
41         {
42                 this->channel = channel;
43
44                 if (channel->getSelectResponse().isEmpty() == true)
45                 {
46                         pkcs15 = new PKCS15(channel);
47                 }
48                 else
49                 {
50                         pkcs15 = new PKCS15(channel, channel->getSelectResponse());
51                 }
52         }
53
54         GPSEACL::~GPSEACL()
55         {
56                 if (pkcs15 != NULL)
57                 {
58                         delete pkcs15;
59                 }
60         }
61
62         int GPSEACL::loadACL()
63         {
64                 ByteArray aid, certHash;
65                 PKCS15ODF *odf;
66
67                 if ((odf = pkcs15->getODF()) != NULL)
68                 {
69                         PKCS15DODF *dodf;
70
71                         if ((dodf = odf->getDODF()) != NULL)
72                         {
73                                 loadAccessControl(dodf);
74
75                                 printAccessControlList();
76                         }
77                         else
78                         {
79                                 SCARD_DEBUG_ERR("dodf null");
80                         }
81                 }
82                 else
83                 {
84                         SCARD_DEBUG_ERR("odf null");
85                 }
86
87                 return 0;
88         }
89
90         int GPSEACL::loadAccessControl(PKCS15DODF *dodf)
91         {
92                 ByteArray path;
93
94                 if (dodf->searchOID(OID_GLOBALPLATFORM, path) == 0)
95                 {
96                         ByteArray data;
97                         FileObject file(channel);
98
99                         SCARD_DEBUG("oid path : %s", path.toString());
100
101                         file.select(NumberStream::getLittleEndianNumber(path));
102                         file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
103
104                         SCARD_DEBUG("data : %s", data.toString());
105
106                         SimpleTLV tlv(data);
107
108                         if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : AccessControlMainFile */
109                         {
110                                 tlv.enterToValueTLV();
111
112                                 /* refresh Tag */
113                                 ByteArray refreshTag;
114
115                                 refreshTag = SimpleTLV::getOctetString(tlv);
116                                 SCARD_DEBUG("current refresh tag : %s", refreshTag.toString());
117
118                                 if (this->refreshTag != refreshTag) /* need to update access control list */
119                                 {
120                                         this->refreshTag = refreshTag;
121
122                                         releaseACL();
123
124                                         /* access control rule path */
125                                         if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
126                                         {
127                                                 /* TODO : parse path */
128                                                 ByteArray path;
129
130                                                 /* OCTET STRING */
131                                                 path = SimpleTLV::getOctetString(tlv.getValue());
132                                                 SCARD_DEBUG("access control rule path : %s", path.toString());
133
134                                                 if (loadRules(path) == 0)
135                                                 {
136                                                         SCARD_DEBUG("loadRules success");
137                                                 }
138                                                 else
139                                                 {
140                                                         SCARD_DEBUG_ERR("loadRules failed");
141                                                 }
142                                         }
143                                 }
144                                 tlv.returnToParentTLV();
145                         }
146                         else
147                         {
148                                 SCARD_DEBUG_ERR("tlv.decodeTLV failed");
149                         }
150                 }
151                 else
152                 {
153                         SCARD_DEBUG_ERR("search failed");
154                 }
155
156                 return 0;
157         }
158
159         int GPSEACL::loadRules(ByteArray path)
160         {
161                 FileObject file(channel);
162                 ByteArray data, aid;
163
164                 file.select(NumberStream::getLittleEndianNumber(path));
165                 file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
166
167                 SCARD_DEBUG("data : %s", data.toString());
168
169                 SimpleTLV tlv(data);
170
171                 while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Rule */
172                 {
173                         tlv.enterToValueTLV();
174                         if (tlv.decodeTLV() == true)
175                         {
176                                 /* target */
177                                 switch (tlv.getTag())
178                                 {
179                                 case 0xA0 : /* CHOICE 0 : EXPLICIT AID */
180                                         /* OCTET STRING */
181                                         aid = SimpleTLV::getOctetString(tlv.getValue());
182                                         break;
183
184                                 case 0x81 : /* CHOICE 1?? : default */
185                                         aid = AccessControlList::AID_DEFAULT;
186                                         break;
187
188                                 case 0x82 : /* CHOICE 2?? : any application */
189                                         aid = AccessControlList::AID_ALL;
190                                         break;
191                                 }
192
193                                 SCARD_DEBUG("aid : %s", aid.toString());
194
195                                 /* access condition path */
196                                 if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
197                                 {
198                                         ByteArray path;
199
200                                         /* OCTET STRING */
201                                         path = SimpleTLV::getOctetString(tlv.getValue());
202                                         SCARD_DEBUG("path : %s", path.toString());
203
204                                         if (loadAccessConditions(aid, path) == 0)
205                                         {
206                                                 SCARD_DEBUG("loadCertHashes success");
207                                         }
208                                         else
209                                         {
210                                                 SCARD_DEBUG_ERR("loadCertHashes failed");
211                                         }
212                                 }
213                                 else
214                                 {
215                                         SCARD_DEBUG_ERR("decodeTLV failed");
216                                 }
217                         }
218                         else
219                         {
220                                 SCARD_DEBUG_ERR("decodeTLV failed");
221                         }
222                         tlv.returnToParentTLV();
223                 }
224
225                 return 0;
226         }
227
228         int GPSEACL::loadAccessConditions(ByteArray aid, ByteArray path)
229         {
230                 FileObject file(channel);
231                 ByteArray data;
232
233                 file.select(NumberStream::getLittleEndianNumber(path));
234                 file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
235
236                 SCARD_DEBUG("data : %s", data.toString());
237
238                 AccessCondition condition;
239
240                 condition.loadAccessCondition(aid, data);
241
242                 pair<ByteArray, AccessCondition> newItem(aid, condition);
243
244                 mapConditions.insert(newItem);
245
246                 return 0;
247         }
248
249 } /* namespace smartcard_service_api */
250
251 /* export C API */
252 #define GP_SE_ACL_EXTERN_BEGIN \
253         if (handle != NULL) \
254         { \
255                 GPSEACL *acl = (GPSEACL *)handle;
256
257 #define GP_SE_ACL_EXTERN_END \
258         } \
259         else \
260         { \
261                 SCARD_DEBUG_ERR("Invalid param"); \
262         }
263
264 using namespace smartcard_service_api;
265
266 EXTERN_API gp_se_acl_h gp_se_acl_create_instance(channel_h channel)
267 {
268         GPSEACL *acl = new GPSEACL((Channel *)channel);
269
270         return (gp_se_acl_h)acl;
271 }
272
273 EXTERN_API int gp_se_acl_load_acl(gp_se_acl_h handle)
274 {
275         int result = -1;
276
277         GP_SE_ACL_EXTERN_BEGIN;
278         result = acl->loadACL();
279         GP_SE_ACL_EXTERN_END;
280
281         return result;
282 }
283
284 EXTERN_API int gp_se_acl_update_acl(gp_se_acl_h handle)
285 {
286         int result = -1;
287
288         GP_SE_ACL_EXTERN_BEGIN;
289         acl->updateACL();
290         GP_SE_ACL_EXTERN_END;
291
292         return result;
293 }
294
295 EXTERN_API void gp_se_acl_release_acl(gp_se_acl_h handle)
296 {
297         GP_SE_ACL_EXTERN_BEGIN;
298         acl->releaseACL();
299         GP_SE_ACL_EXTERN_END;
300 }
301
302 EXTERN_API bool gp_se_acl_is_authorized_access(gp_se_acl_h handle, unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength)
303 {
304         bool result = false;
305
306         GP_SE_ACL_EXTERN_BEGIN;
307         result = acl->isAuthorizedAccess(aidBuffer, aidLength, certHashBuffer, certHashLength);
308         GP_SE_ACL_EXTERN_END;
309
310         return result;
311 }
312
313 EXTERN_API void gp_se_acl_destroy_instance(gp_se_acl_h handle)
314 {
315         GP_SE_ACL_EXTERN_BEGIN;
316         delete acl;
317         GP_SE_ACL_EXTERN_END;
318 }