2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 /* standard library header */
19 /* SLP library header */
24 #include "PKCS15ODF.h"
25 #include "PKCS15DODF.h"
26 #include "NumberStream.h"
27 #include "SimpleTLV.h"
28 #include "AccessCondition.h"
31 #define EXTERN_API __attribute__((visibility("default")))
34 namespace smartcard_service_api
36 static unsigned char oid_globalplatform[] = { 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x81, 0x48, 0x01, 0x01 };
37 static ByteArray OID_GLOBALPLATFORM(ARRAY_AND_SIZE(oid_globalplatform));
39 GPARFACL::GPARFACL() : AccessControlList()
47 int GPARFACL::loadACL(Channel *channel)
49 int result = SCARD_ERROR_OK;
55 return SCARD_ERROR_ILLEGAL_PARAM;
58 PKCS15 pkcs15(channel);
60 /* basically, all requests will be accepted when PKCS #15 doesn't exist or global platform OID is not placed */
61 #if 1 /* FOR ORANGE */
62 /* for Orange, every requests will be denied in same cases */
68 result = pkcs15.select();
69 if (result >= SCARD_ERROR_OK)
73 result = SCARD_ERROR_OK;
75 if ((odf = pkcs15.getODF()) != NULL)
79 if ((dodf = odf->getDODF()) != NULL)
81 result = loadAccessControl(channel, dodf);
82 if (result == SCARD_ERROR_OK)
84 printAccessControlList();
88 #if 1 /* FOR ORANGE */
89 _ERR("loadAccessControl failed, every request will be denied.");
91 _INFO("loadAccessControl failed, every request will be accepted.");
93 result = SCARD_ERROR_OK;
98 #if 1 /* FOR ORANGE */
99 _ERR("dodf null, every request will be denied.");
101 _INFO("dodf null, every request will be accepted.");
107 #if 1 /* FOR ORANGE */
108 _ERR("odf null, every request will be denied.");
110 _INFO("odf null, every request will be accepted.");
116 #if 1 /* FOR ORANGE */
117 _ERR("failed to open PKCS#15, every request will be denied.");
119 _INFO("failed to open PKCS#15, every request will be accepted.");
128 int GPARFACL::loadAccessControl(Channel *channel, PKCS15DODF *dodf)
133 if ((result = dodf->searchOID(OID_GLOBALPLATFORM, path)) == 0)
136 FileObject file(channel);
138 _DBG("oid path : %s", path.toString().c_str());
140 file.select(NumberStream::getLittleEndianNumber(path));
141 file.readBinaryAll(0, data);
143 _DBG("data : %s", data.toString().c_str());
145 /* PKCS #15 and DODF OID exists. apply access control rule!! */
150 if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : AccessControlMainFile */
152 tlv.enterToValueTLV();
155 ByteArray refreshTag;
157 refreshTag = SimpleTLV::getOctetString(tlv);
158 _DBG("current refresh tag : %s", refreshTag.toString().c_str());
160 if (this->refreshTag != refreshTag) /* need to update access control list */
162 this->refreshTag = refreshTag;
166 /* access control rule path */
167 if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
169 /* TODO : parse path */
173 path = SimpleTLV::getOctetString(tlv.getValue());
174 _DBG("access control rule path : %s", path.toString().c_str());
176 if (loadRules(channel, path) == 0)
178 _DBG("loadRules success");
182 _ERR("loadRules failed");
188 _INFO("access rules are not changed. skip update");
190 tlv.returnToParentTLV();
194 _ERR("tlv.decodeTLV failed");
199 _ERR("OID not found");
205 int GPARFACL::loadRules(Channel *channel, const ByteArray &path)
207 FileObject file(channel);
210 file.select(NumberStream::getLittleEndianNumber(path));
211 file.readBinaryAll(0, data);
213 _DBG("data : %s", data.toString().c_str());
217 while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Rule */
219 tlv.enterToValueTLV();
220 if (tlv.decodeTLV() == true)
223 switch (tlv.getTag())
225 case 0xA0 : /* CHOICE 0 : EXPLICIT AID */
227 aid = SimpleTLV::getOctetString(tlv.getValue());
230 case 0x81 : /* CHOICE 1?? : default */
231 aid = AccessControlList::DEFAULT_SE_APP;
234 case 0x82 : /* CHOICE 2?? : any application */
235 aid = AccessControlList::ALL_SE_APPS;
239 _DBG("aid : %s", aid.toString().c_str());
241 /* access condition path */
242 if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
247 path = SimpleTLV::getOctetString(tlv.getValue());
248 _DBG("path : %s", path.toString().c_str());
250 if (loadAccessConditions(channel, aid, path) == 0)
252 _DBG("loadCertHashes success");
256 _ERR("loadCertHashes failed");
261 _ERR("decodeTLV failed");
266 _ERR("decodeTLV failed");
268 tlv.returnToParentTLV();
274 static void loadAPDUAccessRule(AccessRule *rule, const ByteArray &data)
279 _ERR("invalid parameter");
283 if (tlv.decodeTLV() == true)
285 switch (tlv.getTag())
287 case 0xA0 : /* CHOICE 0 : APDUPermission */
288 rule->setAPDUAccessRule(SimpleTLV::getBoolean(tlv.getValue()));
291 case 0xA1 : /* CHOICE 1 : APDUFilters */
292 tlv.enterToValueTLV();
293 while (tlv.decodeTLV() == true)
295 if (tlv.getTag() == 0x04) /* OCTET STRING */
297 ByteArray apdu, mask, value;
299 value = tlv.getValue();
301 _DBG("APDU rule : %s", value.toString().c_str());
303 if (value.size() == 8) /* apdu 4 bytes + mask 4 bytes */
305 apdu.assign(value.getBuffer(), 4);
306 mask.assign(value.getBuffer(4), 4);
308 rule->addAPDUAccessRule(apdu, mask);
312 _ERR("Invalid APDU rule : %s", value.toString().c_str());
317 _ERR("Unknown tag : 0x%02X", tlv.getTag());
320 tlv.returnToParentTLV();
324 _ERR("Unknown tag : 0x%02X", tlv.getTag());
330 static void loadNFCAccessRule(AccessRule *rule, const ByteArray &data)
333 _ERR("invalid parameter");
337 rule->setNFCAccessRule(SimpleTLV::getBoolean(data));
340 static void loadAccessCondition(AccessCondition &condition, const ByteArray &data)
347 while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE */
351 /* access granted for specific applications */
352 tlv.enterToValueTLV();
355 switch (tlv.getTag())
357 case 0x04 : /* OCTET STRING : CertHash */
358 _DBG("aid : %s, hash : %s", condition.getAID().toString().c_str(), tlv.getValue().toString().c_str());
360 hash = tlv.getValue();
361 condition.addAccessRule(tlv.getValue());
364 case 0xA0 : /* CHOICE 0 : AccessRules */
365 tlv.enterToValueTLV();
368 AccessRule *rule = condition.getAccessRule(hash);
370 condition.addAccessRule(hash);
371 rule = condition.getAccessRule(hash);
374 switch (tlv.getTag())
376 case 0xA0 : /* CHOICE 0 : APDUAccessRule */
377 loadAPDUAccessRule(rule, tlv.getValue());
380 case 0xA1 : /* CHOICE 1 : NFCAccessRule */
381 loadNFCAccessRule(rule, tlv.getValue());
385 _ERR("Unknown tag : 0x%02X", tlv.getTag());
391 _ERR("tlv.decodeTLV failed");
393 tlv.returnToParentTLV();
397 _ERR("Unknown tag : 0x%02X", tlv.getTag());
403 _ERR("tlv.decodeTLV failed");
405 tlv.returnToParentTLV();
409 /* empty rule, it means allow for all application */
410 _INFO("access allowed for all applications, aid : %s", condition.getAID().toString().c_str());
412 condition.setAccessCondition(true);
419 /* empty file, it means deny for all application */
420 _INFO("access denied for all applications, aid : %s", condition.getAID().toString().c_str());
422 condition.setAccessCondition(false);
426 int GPARFACL::loadAccessConditions(Channel *channel, const ByteArray &aid, const ByteArray &path)
428 FileObject file(channel);
431 file.select(NumberStream::getLittleEndianNumber(path));
432 file.readBinaryAll(0, data);
434 _DBG("data : %s", data.toString().c_str());
436 AccessCondition condition;
438 condition.setAID(aid);
439 loadAccessCondition(condition, data);
441 pair<ByteArray, AccessCondition> newItem(aid, condition);
443 mapConditions.insert(newItem);
448 } /* namespace smartcard_service_api */