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;
53 if (channel == NULL) {
54 return SCARD_ERROR_ILLEGAL_PARAM;
57 PKCS15 pkcs15(channel);
59 /* basically, all requests will be accepted when PKCS #15 doesn't exist or global platform OID is not placed */
60 #if 1 /* FOR ORANGE */
61 /* for Orange, every requests will be denied in same cases */
67 result = pkcs15.select();
68 if (result >= SCARD_ERROR_OK) {
71 result = SCARD_ERROR_OK;
73 if ((odf = pkcs15.getODF()) != NULL) {
76 if ((dodf = odf->getDODF()) != NULL) {
77 result = loadAccessControl(channel, dodf);
78 if (result == SCARD_ERROR_OK) {
79 printAccessControlList();
81 #if 1 /* FOR ORANGE */
82 _ERR("loadAccessControl failed, every request will be denied.");
84 _INFO("loadAccessControl failed, every request will be accepted.");
86 result = SCARD_ERROR_OK;
89 #if 1 /* FOR ORANGE */
90 _ERR("dodf null, every request will be denied.");
92 _INFO("dodf null, every request will be accepted.");
96 #if 1 /* FOR ORANGE */
97 _ERR("odf null, every request will be denied.");
99 _INFO("odf null, every request will be accepted.");
103 #if 1 /* FOR ORANGE */
104 _ERR("failed to open PKCS#15, every request will be denied.");
106 _INFO("failed to open PKCS#15, every request will be accepted.");
115 int GPARFACL::loadAccessControl(Channel *channel, PKCS15DODF *dodf)
120 if ((result = dodf->searchOID(OID_GLOBALPLATFORM, path)) == 0) {
122 FileObject file(channel);
124 _DBG("oid path : %s", path.toString().c_str());
126 file.select(NumberStream::getLittleEndianNumber(path));
127 file.readBinaryAll(0, data);
129 _DBG("data : %s", data.toString().c_str());
131 /* PKCS #15 and DODF OID exists. apply access control rule!! */
136 if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : AccessControlMainFile */ {
137 tlv.enterToValueTLV();
140 ByteArray refreshTag;
142 refreshTag = SimpleTLV::getOctetString(tlv);
143 _DBG("current refresh tag : %s", refreshTag.toString().c_str());
145 if (this->refreshTag != refreshTag) /* need to update access control list */ {
146 this->refreshTag = refreshTag;
150 /* access control rule path */
151 if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */ {
152 /* TODO : parse path */
156 path = SimpleTLV::getOctetString(tlv.getValue());
157 _DBG("access control rule path : %s", path.toString().c_str());
159 if (loadRules(channel, path) == 0) {
160 _DBG("loadRules success");
162 _ERR("loadRules failed");
166 _INFO("access rules are not changed. skip update");
168 tlv.returnToParentTLV();
170 _ERR("tlv.decodeTLV failed");
173 _ERR("OID not found");
179 int GPARFACL::loadRules(Channel *channel, const ByteArray &path)
181 FileObject file(channel);
184 file.select(NumberStream::getLittleEndianNumber(path));
185 file.readBinaryAll(0, data);
187 _DBG("data : %s", data.toString().c_str());
191 while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Rule */ {
192 tlv.enterToValueTLV();
193 if (tlv.decodeTLV() == true) {
195 switch (tlv.getTag()) {
196 case 0xA0 : /* CHOICE 0 : EXPLICIT AID */
198 aid = SimpleTLV::getOctetString(tlv.getValue());
201 case 0x81 : /* CHOICE 1?? : default */
202 aid = AccessControlList::DEFAULT_SE_APP;
205 case 0x82 : /* CHOICE 2?? : any application */
206 aid = AccessControlList::ALL_SE_APPS;
210 _DBG("aid : %s", aid.toString().c_str());
212 /* access condition path */
213 if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */ {
217 path = SimpleTLV::getOctetString(tlv.getValue());
218 _DBG("path : %s", path.toString().c_str());
220 if (loadAccessConditions(channel, aid, path) == 0) {
221 _DBG("loadCertHashes success");
223 _ERR("loadCertHashes failed");
226 _ERR("decodeTLV failed");
229 _ERR("decodeTLV failed");
231 tlv.returnToParentTLV();
237 static void loadAPDUAccessRule(AccessRule *rule, const ByteArray &data)
242 _ERR("invalid parameter");
246 if (tlv.decodeTLV() == true) {
247 switch (tlv.getTag()) {
248 case 0xA0 : /* CHOICE 0 : APDUPermission */
249 rule->setAPDUAccessRule(SimpleTLV::getBoolean(tlv.getValue()));
252 case 0xA1 : /* CHOICE 1 : APDUFilters */
253 tlv.enterToValueTLV();
254 while (tlv.decodeTLV() == true) {
255 if (tlv.getTag() == 0x04) /* OCTET STRING */ {
256 ByteArray apdu, mask, value;
258 value = tlv.getValue();
260 _DBG("APDU rule : %s", value.toString().c_str());
262 if (value.size() == 8) /* apdu 4 bytes + mask 4 bytes */ {
263 apdu.assign(value.getBuffer(), 4);
264 mask.assign(value.getBuffer(4), 4);
266 rule->addAPDUAccessRule(apdu, mask);
268 _ERR("Invalid APDU rule : %s", value.toString().c_str());
271 _ERR("Unknown tag : 0x%02X", tlv.getTag());
274 tlv.returnToParentTLV();
278 _ERR("Unknown tag : 0x%02X", tlv.getTag());
284 static void loadNFCAccessRule(AccessRule *rule, const ByteArray &data)
287 _ERR("invalid parameter");
291 rule->setNFCAccessRule(SimpleTLV::getBoolean(data));
294 static void loadAccessCondition(AccessCondition &condition, const ByteArray &data)
296 if (data.size() > 0) {
300 while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE */ {
301 if (tlv.size() > 0) {
302 /* access granted for specific applications */
303 tlv.enterToValueTLV();
304 if (tlv.decodeTLV()) {
305 switch (tlv.getTag()) {
306 case 0x04 : /* OCTET STRING : CertHash */
307 _DBG("aid : %s, hash : %s", condition.getAID().toString().c_str(), tlv.getValue().toString().c_str());
309 hash = tlv.getValue();
310 condition.addAccessRule(tlv.getValue());
313 case 0xA0 : /* CHOICE 0 : AccessRules */
314 tlv.enterToValueTLV();
315 if (tlv.decodeTLV()) {
316 AccessRule *rule = condition.getAccessRule(hash);
318 condition.addAccessRule(hash);
319 rule = condition.getAccessRule(hash);
322 switch (tlv.getTag()) {
323 case 0xA0 : /* CHOICE 0 : APDUAccessRule */
324 loadAPDUAccessRule(rule, tlv.getValue());
327 case 0xA1 : /* CHOICE 1 : NFCAccessRule */
328 loadNFCAccessRule(rule, tlv.getValue());
332 _ERR("Unknown tag : 0x%02X", tlv.getTag());
336 _ERR("tlv.decodeTLV failed");
338 tlv.returnToParentTLV();
342 _ERR("Unknown tag : 0x%02X", tlv.getTag());
346 _ERR("tlv.decodeTLV failed");
348 tlv.returnToParentTLV();
350 /* empty rule, it means allow for all application */
351 _INFO("access allowed for all applications, aid : %s", condition.getAID().toString().c_str());
353 condition.setAccessCondition(true);
358 /* empty file, it means deny for all application */
359 _INFO("access denied for all applications, aid : %s", condition.getAID().toString().c_str());
361 condition.setAccessCondition(false);
365 int GPARFACL::loadAccessConditions(Channel *channel, const ByteArray &aid, const ByteArray &path)
367 FileObject file(channel);
370 file.select(NumberStream::getLittleEndianNumber(path));
371 file.readBinaryAll(0, data);
373 _DBG("data : %s", data.toString().c_str());
375 AccessCondition condition;
377 condition.setAID(aid);
378 loadAccessCondition(condition, data);
380 pair<ByteArray, AccessCondition> newItem(aid, condition);
382 mapConditions.insert(newItem);
387 } /* namespace smartcard_service_api */