/*
-* Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
/* standard library header */
#include <stdio.h>
/* local header */
#include "Debug.h"
#include "SimpleTLV.h"
+#include "AccessControlList.h"
#include "AccessCondition.h"
namespace smartcard_service_api
{
- void APDUAccessRule::loadAPDUAccessRule(const ByteArray &data)
+ void AccessRule::addAPDUAccessRule(const ByteArray &apdu,
+ const ByteArray &mask)
{
- SimpleTLV tlv(data);
-
- if (tlv.decodeTLV() == true)
- {
- switch (tlv.getTag())
- {
- case 0xA0 : /* CHOICE 0 : APDUPermission */
- permission = SimpleTLV::getBoolean(tlv.getValue());
- break;
-
- case 0xA1 : /* CHOICE 1 : APDUFilters */
- tlv.enterToValueTLV();
- while (tlv.decodeTLV() == true)
- {
- if (tlv.getTag() == 0x04) /* OCTET STRING */
- {
- ByteArray apdu, mask, value;
-
- value = tlv.getValue();
-
- SCARD_DEBUG("APDU rule : %s", value.toString());
-
- if (value.getLength() == 8) /* apdu 4 bytes + mask 4 bytes */
- {
- apdu.setBuffer(value.getBuffer(), 4);
- mask.setBuffer(value.getBuffer(4), 4);
-
- pair<ByteArray, ByteArray> newItem(apdu, mask);
-
- mapApduFilters.insert(newItem);
- }
- else
- {
- SCARD_DEBUG_ERR("Invalid APDU rule : %s", value.toString());
- }
- }
- else
- {
- SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
- }
- }
- tlv.returnToParentTLV();
- break;
+ pair<ByteArray, ByteArray> item(apdu, mask);
- default :
- SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
- break;
- }
- }
+ listFilters.push_back(item);
}
- bool APDUAccessRule::isAuthorizedAccess(const ByteArray &command)
+ bool AccessRule::isAuthorizedAPDUAccess(const ByteArray &command) const
{
bool result = false;
- if (mapApduFilters.size() > 0)
- {
- /* TODO : search command and check validity */
- }
- else
- {
+ if (command.size() < 4) /* apdu header size */
+ return false;
+
+ if (command.getBuffer() == NULL)
+ return false;
+
+ if (listFilters.size() > 0) {
+ unsigned int cmd, mask, rule;
+ vector<pair<ByteArray, ByteArray> >::const_iterator item;
+
+ cmd = *(unsigned int *)command.getBuffer();
+ for (item = listFilters.begin(); item != listFilters.end(); item++) {
+ unsigned int *temp1 = NULL;
+ unsigned int *temp2 = NULL;
+
+ temp1 = (unsigned int *)item->second.getBuffer();
+ temp2 = (unsigned int *)item->first.getBuffer();
+
+ if (temp1 == NULL || temp2 == NULL)
+ continue;
+
+ mask = *temp1;
+ rule = *temp2;
+
+ if ((cmd & mask) == rule) {
+ result = true;
+ break;
+ }
+ }
+ } else {
/* no filter entry. if permission is true, all access will be granted, if not, all access will be denied */
- result = permission;
+ result = apduRule;
}
return result;
}
- void APDUAccessRule::printAPDUAccessRules()
+ void AccessRule::printAccessRules() const
{
- SCARD_DEBUG(" +-- APDU Access Rule");
+ if (listFilters.size() > 0) {
+ vector<pair<ByteArray, ByteArray> >::const_iterator item;
- if (mapApduFilters.size() > 0)
- {
- map<ByteArray, ByteArray>::iterator iterMap;
+ _DBG(" +---- Granted APDUs");
- for (iterMap = mapApduFilters.begin(); iterMap != mapApduFilters.end(); iterMap++)
- {
- SCARD_DEBUG(" +--- APDU : %s, Mask : %s", ((ByteArray)(iterMap->first)).toString(), iterMap->second.toString());
+ for (item = listFilters.begin(); item != listFilters.end(); item++) {
+ _DBG(" +----- APDU: %s, Mask: %s", item->first.toString().c_str(), item->second.toString().c_str());
}
+ } else {
+ _DBG(" +---- APDU Access ALLOW: %s", apduRule ? "ALWAYS": "NEVER");
}
- else
- {
- SCARD_DEBUG(" +--- permission : %s", permission ? "granted all" : "denied all");
- }
+
+ _DBG(" +---- NFC Access ALLOW: %s", nfcRule ? "ALWAYS": "NEVER");
}
- void NFCAccessRule::loadNFCAccessRule(const ByteArray &data)
+ bool AccessRule::isAuthorizedNFCAccess(void) const
{
- permission = SimpleTLV::getBoolean(data);
+ return nfcRule;
}
- bool NFCAccessRule::isAuthorizedAccess(void)
+ AccessRule *AccessCondition::getAccessRule(const ByteArray &certHash)
{
- bool result = false;
+ AccessRule *result = NULL;
+ map<ByteArray, AccessRule>::iterator item;
- result = permission;
+ item = mapRules.find(certHash);
+ if (item != mapRules.end()) {
+ result = &item->second;
+ }
return result;
}
- void NFCAccessRule::printNFCAccessRules()
+ const AccessRule *AccessCondition::getAccessRule(const ByteArray &certHash) const
{
- SCARD_DEBUG(" +-- NFC Access Rule");
- SCARD_DEBUG(" +--- permission : %s", permission ? "granted all" : "denied all");
+ const AccessRule *result = NULL;
+ map<ByteArray, AccessRule>::const_iterator item;
+
+ item = mapRules.find(certHash);
+ if (item != mapRules.end()) {
+ result = &item->second;
+ }
+
+ return result;
}
- void AccessCondition::loadAccessCondition(ByteArray &aid, ByteArray &data)
+ void AccessCondition::addAccessRule(const ByteArray &hash)
{
- if (data.getLength() > 0)
- {
- SimpleTLV tlv(data);
-
- while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE */
- {
- if (tlv.getLength() > 0)
- {
- /* access granted for specific applications */
- tlv.enterToValueTLV();
- if (tlv.decodeTLV())
- {
- switch (tlv.getTag())
- {
- case 0x04 : /* OCTET STRING : CertHash */
- SCARD_DEBUG("aid : %s, hash : %s", aid.toString(), tlv.getValue().toString());
-
- hashes.push_back(tlv.getValue());
- break;
-
- case 0xA0 : /* CHOICE 0 : AccessRules */
- tlv.enterToValueTLV();
- if (tlv.decodeTLV())
- {
- switch (tlv.getTag())
- {
- case 0xA0 : /* CHOICE 0 : APDUAccessRule */
- apduRule.loadAPDUAccessRule(tlv.getValue());
- break;
-
- case 0xA1 : /* CHOICE 1 : NFCAccessRule */
- nfcRule.loadNFCAccessRule(tlv.getValue());
- break;
-
- default :
- SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
- break;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("tlv.decodeTLV failed");
- }
- tlv.returnToParentTLV();
- break;
-
- default :
- SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
- break;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("tlv.decodeTLV failed");
- }
- tlv.returnToParentTLV();
- }
- else
- {
- SCARD_DEBUG("access granted for all applications, aid : %s", aid.toString());
+ AccessRule rule;
- permission = true;
- break;
- }
- }
- }
- else
- {
- SCARD_DEBUG("access denied for all applications, aid : %s", aid.toString());
+ pair<ByteArray, AccessRule> item(hash, rule);
- permission = false;
+ mapRules.insert(item);
+ }
+
+ void AccessCondition::setAccessCondition(bool rule)
+ {
+ AccessRule *result;
+
+ result = getAccessRule(AccessControlList::ALL_DEVICE_APPS);
+ if (result == NULL) {
+ addAccessRule(AccessControlList::ALL_DEVICE_APPS);
+ result = getAccessRule(AccessControlList::ALL_DEVICE_APPS);
+ if (result == NULL)
+ return;
}
+
+ result->setAPDUAccessRule(rule);
+ result->setNFCAccessRule(rule);
}
- bool AccessCondition::isAuthorizedAccess(ByteArray &certHash)
+ bool AccessCondition::isAuthorizedAccess(const ByteArray &certHash) const
{
bool result = false;
+ const AccessRule *rule = getAccessRule(certHash);
- if (hashes.size() > 0)
- {
- size_t i;
+ if (rule != NULL) {
+ result = rule->isAuthorizedAccess();
+ }
- for (i = 0; i < hashes.size(); i++)
- {
- if (certHash == hashes[i])
- {
- result = true;
- break;
- }
+ return result;
+ }
+
+ void AccessCondition::printAccessConditions() const
+ {
+ _DBG(" +-- Access Condition");
+
+ if (mapRules.size() > 0) {
+ map<ByteArray, AccessRule>::const_iterator item;
+
+ for (item = mapRules.begin(); item != mapRules.end(); item++) {
+ ByteArray temp = item->first;
+
+ _DBG(" +--- hash: %s", (temp == AccessControlList::ALL_DEVICE_APPS) ? "All device applications": temp.toString().c_str());
+ item->second.printAccessRules();
}
+ } else {
+ _DBG(" +--- no rule found");
}
- else
- {
- result = permission;
+ }
+
+ void AccessCondition::setAPDUAccessRule(const ByteArray &certHash,
+ bool rule)
+ {
+ AccessRule *access = getAccessRule(certHash);
+
+ if (access != NULL) {
+ access->setAPDUAccessRule(rule);
}
+ }
- return result;
+ void AccessCondition::addAPDUAccessRule(const ByteArray &certHash,
+ const ByteArray &apdu, const ByteArray &mask)
+ {
+ AccessRule *access = getAccessRule(certHash);
+
+ if (access != NULL) {
+ access->addAPDUAccessRule(apdu, mask);
+ }
}
- bool AccessCondition::isAuthorizedAPDUAccess(ByteArray &command)
+ void AccessCondition::addAPDUAccessRule(const ByteArray &certHash,
+ const ByteArray &rule)
{
- bool result = false;
+ if (rule.size() != 8)
+ return;
- result = apduRule.isAuthorizedAccess(command);
+ addAPDUAccessRule(certHash, rule.sub(0, 4), rule.sub(4, 4));
+ }
- return result;
+ void AccessCondition::setNFCAccessRule(const ByteArray &certHash,
+ bool rule)
+ {
+ AccessRule *access = getAccessRule(certHash);
+
+ if (access != NULL) {
+ access->setNFCAccessRule(rule);
+ }
}
- bool AccessCondition::isAuthorizedNFCAccess()
+ bool AccessCondition::isAuthorizedAPDUAccess(const ByteArray &certHash,
+ const ByteArray &command) const
{
bool result = false;
+ const AccessRule *rule = getAccessRule(certHash);
- result = nfcRule.isAuthorizedAccess();
+ if (rule != NULL) {
+ result = rule->isAuthorizedAPDUAccess(command);
+ }
return result;
}
- void AccessCondition::printAccessConditions()
+ bool AccessCondition::isAuthorizedNFCAccess(const ByteArray &certHash) const
{
- SCARD_DEBUG(" +-- Access Condition");
-
- if (hashes.size() > 0)
- {
- size_t i;
+ bool result = false;
+ const AccessRule *rule = getAccessRule(certHash);
- for (i = 0; i < hashes.size(); i++)
- {
- SCARD_DEBUG(" +--- hash : %s", hashes[i].toString());
- }
- }
- else
- {
- SCARD_DEBUG(" +--- permission : %s", permission ? "granted all" : "denied all");
+ if (rule != NULL) {
+ result = rule->isAuthorizedNFCAccess();
}
+
+ return result;
}
} /* namespace smartcard_service_api */