Change the authorization sequence
[platform/core/connectivity/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():AccessControlList()
41         {
42         }
43
44         GPSEACL::~GPSEACL()
45         {
46         }
47
48         int GPSEACL::loadACL(Channel *channel)
49         {
50                 int result = 0;
51                 PKCS15 *pkcs15;
52
53                 if (channel == NULL)
54                 {
55                         return -1;
56                 }
57
58                 pkcs15 = new PKCS15(channel, channel->getSelectResponse());
59                 if (pkcs15 != NULL)
60                 {
61                         /* basically, all requests will be accepted when PKCS #15 doesn't exist or global platform OID is not placed */
62                         allGranted = true;
63
64                         if (pkcs15->isClosed() == false)
65                         {
66                                 PKCS15ODF *odf;
67
68                                 if ((odf = pkcs15->getODF()) != NULL)
69                                 {
70                                         PKCS15DODF *dodf;
71
72                                         if ((dodf = odf->getDODF()) != NULL)
73                                         {
74                                                 if (loadAccessControl(channel, dodf) == 0)
75                                                 {
76                                                         printAccessControlList();
77
78                                                         result = 0;
79                                                 }
80                                                 else
81                                                 {
82                                                         SCARD_DEBUG_ERR("loadAccessControl failed, every request will be accepted.");
83                                                 }
84                                         }
85                                         else
86                                         {
87                                                 SCARD_DEBUG_ERR("dodf null, every request will be accepted.");
88                                         }
89                                 }
90                                 else
91                                 {
92                                         SCARD_DEBUG_ERR("odf null, every request will be accepted.");
93                                 }
94                         }
95                         else
96                         {
97                                 SCARD_DEBUG_ERR("failed to open PKCS15, every request will be accepted.");
98                         }
99
100                         delete pkcs15;
101                 }
102                 else
103                 {
104                         return -1;
105                 }
106
107                 return result;
108         }
109
110         int GPSEACL::loadAccessControl(Channel *channel, PKCS15DODF *dodf)
111         {
112                 int result = -1;
113                 ByteArray path;
114
115                 if ((result = dodf->searchOID(OID_GLOBALPLATFORM, path)) == 0)
116                 {
117                         ByteArray data;
118                         FileObject file(channel);
119
120                         SCARD_DEBUG("oid path : %s", path.toString());
121
122                         file.select(NumberStream::getLittleEndianNumber(path));
123                         file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
124
125                         SCARD_DEBUG("data : %s", data.toString());
126
127                         /* PKCS #15 and DODF OID exists. apply access control rule!! */
128                         allGranted = false;
129
130                         SimpleTLV tlv(data);
131
132                         if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : AccessControlMainFile */
133                         {
134                                 tlv.enterToValueTLV();
135
136                                 /* refresh Tag */
137                                 ByteArray refreshTag;
138
139                                 refreshTag = SimpleTLV::getOctetString(tlv);
140                                 SCARD_DEBUG("current refresh tag : %s", refreshTag.toString());
141
142                                 if (this->refreshTag != refreshTag) /* need to update access control list */
143                                 {
144                                         this->refreshTag = refreshTag;
145
146                                         releaseACL();
147
148                                         /* access control rule path */
149                                         if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
150                                         {
151                                                 /* TODO : parse path */
152                                                 ByteArray path;
153
154                                                 /* OCTET STRING */
155                                                 path = SimpleTLV::getOctetString(tlv.getValue());
156                                                 SCARD_DEBUG("access control rule path : %s", path.toString());
157
158                                                 if (loadRules(channel, path) == 0)
159                                                 {
160                                                         SCARD_DEBUG("loadRules success");
161                                                 }
162                                                 else
163                                                 {
164                                                         SCARD_DEBUG_ERR("loadRules failed");
165                                                 }
166                                         }
167                                 }
168                                 tlv.returnToParentTLV();
169                         }
170                         else
171                         {
172                                 SCARD_DEBUG_ERR("tlv.decodeTLV failed");
173                         }
174                 }
175                 else
176                 {
177                         SCARD_DEBUG_ERR("OID not found");
178                 }
179
180                 return result;
181         }
182
183         int GPSEACL::loadRules(Channel *channel, ByteArray path)
184         {
185                 FileObject file(channel);
186                 ByteArray data, aid;
187
188                 file.select(NumberStream::getLittleEndianNumber(path));
189                 file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
190
191                 SCARD_DEBUG("data : %s", data.toString());
192
193                 SimpleTLV tlv(data);
194
195                 while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Rule */
196                 {
197                         tlv.enterToValueTLV();
198                         if (tlv.decodeTLV() == true)
199                         {
200                                 /* target */
201                                 switch (tlv.getTag())
202                                 {
203                                 case 0xA0 : /* CHOICE 0 : EXPLICIT AID */
204                                         /* OCTET STRING */
205                                         aid = SimpleTLV::getOctetString(tlv.getValue());
206                                         break;
207
208                                 case 0x81 : /* CHOICE 1?? : default */
209                                         aid = AccessControlList::AID_DEFAULT;
210                                         break;
211
212                                 case 0x82 : /* CHOICE 2?? : any application */
213                                         aid = AccessControlList::AID_ALL;
214                                         break;
215                                 }
216
217                                 SCARD_DEBUG("aid : %s", aid.toString());
218
219                                 /* access condition path */
220                                 if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
221                                 {
222                                         ByteArray path;
223
224                                         /* OCTET STRING */
225                                         path = SimpleTLV::getOctetString(tlv.getValue());
226                                         SCARD_DEBUG("path : %s", path.toString());
227
228                                         if (loadAccessConditions(channel, aid, path) == 0)
229                                         {
230                                                 SCARD_DEBUG("loadCertHashes success");
231                                         }
232                                         else
233                                         {
234                                                 SCARD_DEBUG_ERR("loadCertHashes failed");
235                                         }
236                                 }
237                                 else
238                                 {
239                                         SCARD_DEBUG_ERR("decodeTLV failed");
240                                 }
241                         }
242                         else
243                         {
244                                 SCARD_DEBUG_ERR("decodeTLV failed");
245                         }
246                         tlv.returnToParentTLV();
247                 }
248
249                 return 0;
250         }
251
252         int GPSEACL::loadAccessConditions(Channel *channel, ByteArray aid, ByteArray path)
253         {
254                 FileObject file(channel);
255                 ByteArray data;
256
257                 file.select(NumberStream::getLittleEndianNumber(path));
258                 file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
259
260                 SCARD_DEBUG("data : %s", data.toString());
261
262                 AccessCondition condition;
263
264                 condition.loadAccessCondition(aid, data);
265
266                 pair<ByteArray, AccessCondition> newItem(aid, condition);
267
268                 mapConditions.insert(newItem);
269
270                 return 0;
271         }
272
273 } /* namespace smartcard_service_api */
274
275 /* export C API */
276 #define GP_SE_ACL_EXTERN_BEGIN \
277         if (handle != NULL) \
278         { \
279                 GPSEACL *acl = (GPSEACL *)handle;
280
281 #define GP_SE_ACL_EXTERN_END \
282         } \
283         else \
284         { \
285                 SCARD_DEBUG_ERR("Invalid param"); \
286         }
287
288 using namespace smartcard_service_api;
289
290 EXTERN_API gp_se_acl_h gp_se_acl_create_instance()
291 {
292         GPSEACL *acl = new GPSEACL();
293
294         return (gp_se_acl_h)acl;
295 }
296
297 EXTERN_API int gp_se_acl_load_acl(gp_se_acl_h handle, channel_h channel)
298 {
299         int result = -1;
300
301         GP_SE_ACL_EXTERN_BEGIN;
302         result = acl->loadACL((Channel *)channel);
303         GP_SE_ACL_EXTERN_END;
304
305         return result;
306 }
307
308 EXTERN_API int gp_se_acl_update_acl(gp_se_acl_h handle, channel_h channel)
309 {
310         int result = -1;
311
312         GP_SE_ACL_EXTERN_BEGIN;
313         acl->updateACL((Channel *)channel);
314         GP_SE_ACL_EXTERN_END;
315
316         return result;
317 }
318
319 EXTERN_API void gp_se_acl_release_acl(gp_se_acl_h handle)
320 {
321         GP_SE_ACL_EXTERN_BEGIN;
322         acl->releaseACL();
323         GP_SE_ACL_EXTERN_END;
324 }
325
326 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)
327 {
328         bool result = false;
329
330         GP_SE_ACL_EXTERN_BEGIN;
331         result = acl->isAuthorizedAccess(aidBuffer, aidLength, certHashBuffer, certHashLength);
332         GP_SE_ACL_EXTERN_END;
333
334         return result;
335 }
336
337 EXTERN_API void gp_se_acl_destroy_instance(gp_se_acl_h handle)
338 {
339         GP_SE_ACL_EXTERN_BEGIN;
340         delete acl;
341         GP_SE_ACL_EXTERN_END;
342 }