/* SLP library header */
/* local header */
+#include "smartcard-types.h"
#include "Debug.h"
#include "APDUHelper.h"
bool ResponseHelper::setResponse(const ByteArray &response)
{
bool result = false;
- status = 0;
+ status = SCARD_ERROR_UNKNOWN;
dataField.releaseBuffer();
this->response = response;
/* 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);
+ pair<ByteArray, ByteArray> item(apdu, mask);
- 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();
-
- _DBG("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
- {
- _ERR("Invalid APDU rule : %s", value.toString());
- }
- }
- else
- {
- _ERR("Unknown tag : 0x%02X", tlv.getTag());
- }
- }
- tlv.returnToParentTLV();
- break;
-
- default :
- _ERR("Unknown tag : 0x%02X", tlv.getTag());
- break;
- }
- }
+ listFilters.push_back(item);
}
- bool APDUAccessRule::isAuthorizedAccess(const ByteArray &command)
+ bool AccessRule::isAuthorizedAPDUAccess(const ByteArray &command)
{
bool result = false;
- if (mapApduFilters.size() > 0)
+ if (command.getLength() < 4) /* apdu header size */
+ return false;
+
+ if (listFilters.size() > 0)
{
- /* TODO : search command and check validity */
+ unsigned int cmd, mask, rule;
+ vector<pair<ByteArray, ByteArray> >::iterator item;
+
+ cmd = *(unsigned int *)command.getBuffer();
+ for (item = listFilters.begin(); item != listFilters.end(); item++)
+ {
+ mask = *(unsigned int *)item->second.getBuffer();
+ rule = *(unsigned int *)item->first.getBuffer();
+
+ 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()
{
- _DBG(" +-- APDU Access Rule");
-
- if (mapApduFilters.size() > 0)
+ if (listFilters.size() > 0)
{
- map<ByteArray, ByteArray>::iterator iterMap;
+ vector<pair<ByteArray, ByteArray> >::iterator item;
- for (iterMap = mapApduFilters.begin(); iterMap != mapApduFilters.end(); iterMap++)
+ _DBG(" +---- Granted APDUs");
+
+ for (item = listFilters.begin(); item != listFilters.end(); item++)
{
- _DBG(" +--- APDU : %s, Mask : %s", ((ByteArray)(iterMap->first)).toString(), iterMap->second.toString());
+ _DBG(" +----- APDU : %s, Mask : %s", item->first.toString(), item->second.toString());
}
}
else
{
- _DBG(" +--- permission : %s", permission ? "granted all" : "denied all");
+ _DBG(" +---- APDU Access ALLOW : %s", apduRule ? "ALWAYS" : "NEVER");
}
+
+ _DBG(" +---- NFC Access ALLOW : %s", nfcRule ? "ALWAYS" : "NEVER");
}
- void NFCAccessRule::loadNFCAccessRule(const ByteArray &data)
+ bool AccessRule::isAuthorizedNFCAccess(void)
{
- 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()
+ void AccessCondition::addAccessRule(const ByteArray &hash)
{
- _DBG(" +-- NFC Access Rule");
- _DBG(" +--- permission : %s", permission ? "granted all" : "denied all");
+ AccessRule rule;
+
+ pair<ByteArray, AccessRule> item(hash, rule);
+
+ mapRules.insert(item);
}
- void AccessCondition::loadAccessCondition(ByteArray &aid, ByteArray &data)
+ bool AccessCondition::isAuthorizedAccess(const ByteArray &certHash)
{
- 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 */
- _DBG("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 :
- _ERR("Unknown tag : 0x%02X", tlv.getTag());
- break;
- }
- }
- else
- {
- _ERR("tlv.decodeTLV failed");
- }
- tlv.returnToParentTLV();
- break;
-
- default :
- _ERR("Unknown tag : 0x%02X", tlv.getTag());
- break;
- }
- }
- else
- {
- _ERR("tlv.decodeTLV failed");
- }
- tlv.returnToParentTLV();
- }
- else
- {
- _INFO("access granted for all applications, aid : %s", aid.toString());
+ bool result = false;
+ map<ByteArray, AccessRule>::iterator item;
- permission = true;
- break;
- }
- }
+ item = mapRules.find(certHash);
+ if (item != mapRules.end())
+ {
+ result = true;
}
else
{
- _INFO("access denied for all applications, aid : %s", aid.toString());
-
- permission = false;
+ /* TODO */
+ result = permission;
}
+
+ return result;
}
- bool AccessCondition::isAuthorizedAccess(ByteArray &certHash)
+ void AccessCondition::printAccessConditions()
{
- bool result = false;
+ _DBG(" +-- Access Condition");
- if (hashes.size() > 0)
+ if (mapRules.size() > 0)
{
- size_t i;
+ map<ByteArray, AccessRule>::iterator item;
- for (i = 0; i < hashes.size(); i++)
+ for (item = mapRules.begin(); item != mapRules.end(); item++)
{
- if (certHash == hashes[i])
- {
- result = true;
- break;
- }
+ ByteArray temp = item->first;
+
+ _DBG(" +--- hash : %s", (temp == AccessControlList::ALL_DEVICE_APPS) ? "All device applications" : temp.toString());
+ item->second.printAccessRules();
}
}
else
{
- result = permission;
+ _DBG(" +--- permission : %s", permission ? "granted all" : "denied all");
}
+ }
- return result;
+ void AccessCondition::setAPDUAccessRule(const ByteArray &certHash,
+ bool rule)
+ {
+ AccessRule *access = getAccessRule(certHash);
+
+ if (access != NULL) {
+ access->setAPDUAccessRule(rule);
+ }
}
- bool AccessCondition::isAuthorizedAPDUAccess(ByteArray &command)
+ void AccessCondition::addAPDUAccessRule(const ByteArray &certHash,
+ const ByteArray &apdu, const ByteArray &mask)
{
- bool result = false;
+ AccessRule *access = getAccessRule(certHash);
- result = apduRule.isAuthorizedAccess(command);
+ if (access != NULL) {
+ access->addAPDUAccessRule(apdu, mask);
+ }
+ }
- return result;
+ void AccessCondition::addAPDUAccessRule(const ByteArray &certHash,
+ const ByteArray &rule)
+ {
+ if (rule.getLength() != 8)
+ return;
+
+ addAPDUAccessRule(certHash, rule.sub(0, 4), rule.sub(4, 4));
+ }
+
+ 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)
{
bool result = false;
+ AccessRule *access = getAccessRule(certHash);
- result = nfcRule.isAuthorizedAccess();
+ if (access != NULL) {
+ result = access->isAuthorizedAPDUAccess(command);
+ }
return result;
}
- void AccessCondition::printAccessConditions()
+ bool AccessCondition::isAuthorizedNFCAccess(const ByteArray &certHash)
{
- _DBG(" +-- Access Condition");
-
- if (hashes.size() > 0)
- {
- size_t i;
+ bool result = false;
+ AccessRule *access = getAccessRule(certHash);
- for (i = 0; i < hashes.size(); i++)
- {
- _DBG(" +--- hash : %s", hashes[i].toString());
- }
- }
- else
- {
- _DBG(" +--- permission : %s", permission ? "granted all" : "denied all");
+ if (access != NULL) {
+ result = access->isAuthorizedNFCAccess();
}
+
+ return result;
}
} /* namespace smartcard_service_api */
#include "Debug.h"
#include "AccessControlList.h"
#include "PKCS15.h"
-#include "AccessCondition.h"
namespace smartcard_service_api
{
- const unsigned char aid_all[] = { 0x00, 0x00 };
- const unsigned char aid_default[] = { 0x00, 0x01 };
+ const unsigned char all_se_apps[] = { 0x00, 0x00 };
+ const unsigned char default_se_app[] = { 0x00, 0x01 };
+ const unsigned char all_device_apps[] = { 0x00, 0x02 };
- ByteArray AccessControlList::AID_ALL(ARRAY_AND_SIZE(aid_all));
- ByteArray AccessControlList::AID_DEFAULT(ARRAY_AND_SIZE(aid_default));
+ ByteArray AccessControlList::ALL_SE_APPS(ARRAY_AND_SIZE(all_se_apps));
+ ByteArray AccessControlList::DEFAULT_SE_APP(ARRAY_AND_SIZE(default_se_app));
+ ByteArray AccessControlList::ALL_DEVICE_APPS(ARRAY_AND_SIZE(all_device_apps));
- AccessControlList::AccessControlList()
+ AccessControlList::AccessControlList() : allGranted(false)
{
- allGranted = false;
}
AccessControlList::~AccessControlList()
allGranted = false;
}
- bool AccessControlList::isAuthorizedAccess(ByteArray aid, ByteArray certHash, bool update)
+ AccessCondition &AccessControlList::getAccessCondition(const ByteArray &aid)
{
- bool result = allGranted;
- map<ByteArray, AccessCondition>::iterator iterMap;
+ map<ByteArray, AccessCondition>::iterator item;
- if (result == false)
+ item = mapConditions.find(aid);
+ if (item == mapConditions.end())
{
- _DBG("aid : %s", aid.toString());
- _DBG("hash : %s", certHash.toString());
+ AccessCondition condition;
+ pair<ByteArray, AccessCondition> temp(aid, condition);
+ mapConditions.insert(temp);
- /* null aid means default applet */
- if (aid.isEmpty() == true)
- {
- aid = AID_DEFAULT;
- }
+ item = mapConditions.find(aid);
+ }
- /* first.. find hashes matched with aid */
- if ((iterMap = mapConditions.find(aid)) != mapConditions.end())
- {
- result = iterMap->second.isAuthorizedAccess(certHash);
- }
- /* finally.. find hashes in 'all' list */
- else if ((iterMap = mapConditions.find(AID_ALL)) != mapConditions.end())
- {
- result = iterMap->second.isAuthorizedAccess(certHash);
- }
+ return item->second;
+ }
+
+ AccessRule *AccessControlList::findAccessRule(const ByteArray &aid,
+ const ByteArray &hash)
+ {
+ AccessRule *result = NULL;
+ map<ByteArray, AccessCondition>::iterator item;
+
+ item = mapConditions.find(aid);
+ if (item != mapConditions.end()) {
+ result = item->second.getAccessRule(hash);
}
return result;
}
- bool AccessControlList::isAuthorizedAccess(ByteArray aid, ByteArray certHash)
+ bool AccessControlList::isAuthorizedAccess(ByteArray &aid,
+ ByteArray &certHash)
+ {
+ vector<ByteArray> hashes;
+
+ hashes.push_back(certHash);
+
+ return isAuthorizedAccess(aid, hashes);
+ }
+
+ bool AccessControlList::isAuthorizedAccess(unsigned char *aidBuffer,
+ unsigned int aidLength, unsigned char *certHashBuffer,
+ unsigned int certHashLength)
{
- return isAuthorizedAccess(aid, certHash, true);
+ ByteArray aid(aidBuffer, aidLength);
+ ByteArray certHash(certHashBuffer, certHashLength);
+
+ return isAuthorizedAccess(aid, certHash);
}
- bool AccessControlList::isAuthorizedAccess(unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength)
+ bool AccessControlList::isAuthorizedAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes)
{
- return isAuthorizedAccess(ByteArray(aidBuffer, aidLength), ByteArray(certHashBuffer, certHashLength), true);
+ return isAuthorizedAccess(aid, certHashes, ByteArray::EMPTY);
}
- bool AccessControlList::isAuthorizedAccess(ByteArray aid, vector<ByteArray> &certHashes)
+ bool AccessControlList::isAuthorizedAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes, ByteArray &command)
{
- bool result;
- size_t i;
+ bool result = allGranted;
+ vector<ByteArray>::reverse_iterator item;
+ AccessRule *rule = NULL;
- result = allGranted;
+ if (result == true) {
+ goto END;
+ }
- if (result == false)
- {
- for (i = 0; result == false && i < certHashes.size(); i++)
- {
- result = isAuthorizedAccess(aid, certHashes[i], false);
+ /* Step A, find with aid and cert hashes */
+ for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
+ rule = findAccessRule(aid, *item);
+ if (rule != NULL) {
+ if (command.isEmpty()) {
+ result = rule->isAuthorizedAccess();
+ } else {
+ result = rule->isAuthorizedAPDUAccess(command);
+ }
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString(), (*item).toString());
+ goto END;
+ }
+ }
+
+ /* Step B, find with aid and ALL_DEVICES_APPS */
+ rule = findAccessRule(aid, ALL_DEVICE_APPS);
+ if (rule != NULL) {
+ if (command.isEmpty()) {
+ result = rule->isAuthorizedAccess();
+ } else {
+ result = rule->isAuthorizedAPDUAccess(command);
+ }
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString(), ALL_DEVICE_APPS.toString());
+ goto END;
+ }
+
+ /* Step C, find with ALL_SE_APPS and hashes */
+ for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
+ rule = findAccessRule(ALL_SE_APPS, *item);
+ if (rule != NULL) {
+ if (command.isEmpty()) {
+ result = rule->isAuthorizedAccess();
+ } else {
+ result = rule->isAuthorizedAPDUAccess(command);
+ }
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", (*item).toString());
+ goto END;
+ }
+ }
+
+ /* Step D, find with ALL_SE_APPS and ALL_DEVICES_APPS */
+ rule = findAccessRule(ALL_SE_APPS, ALL_DEVICE_APPS);
+ if (rule != NULL) {
+ if (command.isEmpty()) {
+ result = rule->isAuthorizedAccess();
+ } else {
+ result = rule->isAuthorizedAPDUAccess(command);
+ }
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", "All device applications");
+ }
+
+END :
+ return result;
+ }
+
+ bool AccessControlList::isAuthorizedNFCAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes)
+ {
+ bool result = allGranted;
+ vector<ByteArray>::reverse_iterator item;
+ AccessRule *rule = NULL;
+
+ if (result == true) {
+ goto END;
+ }
+
+ /* Step A, find with aid and cert hashes */
+ for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
+ rule = findAccessRule(aid, *item);
+ if (rule != NULL) {
+ result = rule->isAuthorizedNFCAccess();
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString(), (*item).toString());
+ goto END;
+ }
+ }
+
+ /* Step B, find with aid and ALL_DEVICES_APPS */
+ rule = findAccessRule(aid, ALL_DEVICE_APPS);
+ if (rule != NULL) {
+ result = rule->isAuthorizedNFCAccess();
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString(), "All device applications");
+ goto END;
+ }
+
+ /* Step C, find with ALL_SE_APPS and hashes */
+ for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
+ rule = findAccessRule(ALL_SE_APPS, *item);
+ if (rule != NULL) {
+ result = rule->isAuthorizedNFCAccess();
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", (*item).toString());
+ goto END;
}
}
+ /* Step D, find with ALL_SE_APPS and ALL_DEVICES_APPS */
+ rule = findAccessRule(ALL_SE_APPS, ALL_DEVICE_APPS);
+ if (rule != NULL) {
+ result = rule->isAuthorizedNFCAccess();
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", "All device applications");
+ }
+
+END :
return result;
}
void AccessControlList::printAccessControlList()
{
ByteArray temp;
-
- /* release map and vector */
map<ByteArray, AccessCondition>::iterator iterMap;
- _DBG("================ Certification Hashes ==================");
+ _DBG("================ Access Control Rules ==================");
for (iterMap = mapConditions.begin(); iterMap != mapConditions.end(); iterMap++)
{
temp = iterMap->first;
- _DBG("+ aid : %s", (temp == AID_DEFAULT) ? "DEFAULT" : (temp == AID_ALL) ? "ALL" : temp.toString());
+ _DBG("+ aid : %s", (temp == DEFAULT_SE_APP) ? "Default Application" : (temp == ALL_SE_APPS) ? "All SE Applications" : temp.toString());
iterMap->second.printAccessConditions();
}
return min_len;
}
+ ByteArray ByteArray::sub(uint32_t offset, uint32_t size) const
+ {
+ ByteArray newArray;
+
+ if (length == 0 || offset >= length || (offset + size) > length)
+ {
+ _DBG("length is zero");
+
+ return newArray;
+ }
+
+ newArray.setBuffer(buffer + offset, size);
+
+ return newArray;
+ }
+
void ByteArray::releaseBuffer()
{
if (buffer != NULL)
include/TerminalInterface.h
include/Terminal.h
include/SignatureHelper.h
- include/GPSEACL.h
)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
namespace smartcard_service_api
{
+ static unsigned char path_efdir[] = { 0x2f, 0x00 };
+ static ByteArray PATH_EFDIR(ARRAY_AND_SIZE(path_efdir));
+
EFDIR::EFDIR(Channel *channel) : FileObject(channel)
{
- unsigned char path[] = { 0x2f, 0x00 };
- ByteArray dirPath(ARRAY_AND_SIZE(path));
- int ret;
-
- ret = select(dirPath, false);
- if (ret >= SCARD_ERROR_OK)
- {
- _DBG("response : %s", selectResponse.toString());
- }
- else
- {
- _ERR("EFDIR select failed, [%d]", ret);
- }
}
- EFDIR::EFDIR(Channel *channel, ByteArray selectResponse)
- : FileObject(channel, selectResponse)
+ EFDIR::EFDIR(Channel *channel, ByteArray selectResponse) :
+ FileObject(channel, selectResponse)
{
}
{
}
+ int EFDIR::select()
+ {
+ int ret;
+
+ ret = FileObject::select(PATH_EFDIR, false);
+ if (ret < SCARD_ERROR_OK)
+ {
+ _ERR("EFDIR select failed, [%d]", ret);
+ }
+
+ return ret;
+ }
+
ByteArray EFDIR::parseRecord(Record &record, ByteArray &aid)
{
bool matched = false;
opened = false;
}
- FileObject::FileObject(Channel *channel, ByteArray selectResponse)
+ FileObject::FileObject(Channel *channel, const ByteArray &selectResponse)
: ProviderHelper(channel)
{
opened = false;
selectResponse.releaseBuffer();
}
- bool FileObject::setSelectResponse(ByteArray response)
+ bool FileObject::setSelectResponse(const ByteArray &response)
{
bool result = false;
}
else
{
- _ERR("invalid response : %s", response.toString());
+ _ERR("invalid response");
}
return result;
}
- int FileObject::_select(ByteArray command)
+ int FileObject::_select(const ByteArray &command)
{
int ret = ERROR_ILLEGAL_STATE;
ByteArray result;
return ret;
}
- int FileObject::select(ByteArray aid)
+ int FileObject::select(const ByteArray &aid)
{
int ret = ERROR_ILLEGAL_STATE;
ByteArray command;
return ret;
}
- int FileObject::select(ByteArray path, bool fromCurrentDF)
+ int FileObject::select(const ByteArray &path, bool fromCurrentDF)
{
int ret = ERROR_ILLEGAL_STATE;
ByteArray command;
return ret;
}
- int FileObject::writeRecord(unsigned int sfi, Record record)
+ int FileObject::writeRecord(unsigned int sfi, const Record &record)
{
return 0;
}
- int FileObject::searchRecord(unsigned int sfi, ByteArray searchParam, vector<int> &result)
+ int FileObject::searchRecord(unsigned int sfi, const ByteArray &searchParam, vector<int> &result)
{
return 0;
}
return ret;
}
- int FileObject::writeBinary(unsigned int sfi, ByteArray data, unsigned int offset, unsigned int length)
+ int FileObject::writeBinary(unsigned int sfi, const ByteArray &data, unsigned int offset, unsigned int length)
{
ByteArray command, response;
APDUCommand apdu;
--- /dev/null
+/*
+ * 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 */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "GPACE.h"
+#include "GPARAACL.h"
+#include "GPARFACL.h"
+#include "SessionHelper.h"
+#include "ReaderHelper.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ GPACE::GPACE() : AccessControlList(), acl(NULL)
+ {
+ }
+
+ GPACE::~GPACE()
+ {
+ if (acl != NULL) {
+ delete acl;
+ }
+ }
+
+ int GPACE::loadACL(Channel *channel)
+ {
+ int result = SCARD_ERROR_OK;
+
+ _BEGIN();
+
+ if (channel == NULL)
+ {
+ return SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ if (acl == NULL) {
+ /* first, check ara-m */
+ GPARAACL *araACL = new GPARAACL;
+
+ result = araACL->loadACL(channel);
+ if (result < SCARD_ERROR_OK) {
+ _ERR("ARA not found");
+
+ delete araACL;
+
+ if (true) {
+ _INFO("try to use ARF");
+ /* second, check arf when channel is for SIM */
+ GPARFACL *arfACL = new GPARFACL;
+
+ result = arfACL->loadACL(channel);
+ if (result >= SCARD_ERROR_OK) {
+ acl = arfACL;
+ } else {
+ delete arfACL;
+ }
+ }
+ } else {
+ acl = araACL;
+ }
+ } else {
+ result = acl->loadACL(channel);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ bool GPACE::isAuthorizedAccess(ByteArray &aid,
+ ByteArray &certHash)
+ {
+ return (acl != NULL) ? acl->isAuthorizedAccess(aid, certHash) : false;
+ }
+
+ bool GPACE::isAuthorizedAccess(unsigned char *aidBuffer,
+ unsigned int aidLength, unsigned char *certHashBuffer,
+ unsigned int certHashLength)
+ {
+ return (acl != NULL) ? acl->isAuthorizedAccess(aidBuffer, aidLength, certHashBuffer, certHashLength) : false;
+ }
+
+ bool GPACE::isAuthorizedAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes)
+ {
+ return (acl != NULL) ? acl->isAuthorizedAccess(aid, certHashes) : false;
+ }
+
+ bool GPACE::isAuthorizedAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes, ByteArray &command)
+ {
+ return (acl != NULL) ? acl->isAuthorizedAccess(aid, certHashes, command) : false;
+ }
+
+ bool GPACE::isAuthorizedNFCAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes)
+ {
+ return (acl != NULL) ? acl->isAuthorizedNFCAccess(aid, certHashes) : false;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+ * 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 */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "GPARAACL.h"
+#include "GPARAM.h"
+#include "NumberStream.h"
+#include "SimpleTLV.h"
+#include "ISO7816BERTLV.h"
+#include "AccessCondition.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ static unsigned char aid_aram[] = { 0xA0, 0x00, 0x00, 0x01, 0x51, 0x41, 0x43, 0x4C, 0x00 };
+ static ByteArray AID_ARAM(ARRAY_AND_SIZE(aid_aram));
+
+#define GET_DATA_ALL 0
+#define GET_DATA_SPECIFIC 1
+#define GET_DATA_REFRESH_TAG 2
+#define GET_DATA_NEXT 3
+
+#define ARAM_TAG_ALL_AR 0x0000FF40
+#define ARAM_TAG_AR 0x0000FF50
+#define ARAM_TAG_REFRESH 0x0000DF20
+
+#define DO_TAG_AID_REF 0x0000004F
+#define DO_TAG_AID_REF_DEFAULT 0x000000C0
+#define DO_TAG_HASH_REF 0x000000C1
+#define DO_TAG_APDU_AR 0x000000D0
+#define DO_TAG_NFC_AR 0x000000D1
+#define DO_TAG_REF 0x000000E1
+#define DO_TAG_REF_AR 0x000000E2
+#define DO_TAG_AR 0x000000E3
+
+ GPARAACL::GPARAACL() : AccessControlList()
+ {
+ }
+
+ GPARAACL::~GPARAACL()
+ {
+ }
+
+ static ByteArray getAID(SimpleTLV &tlv)
+ {
+ ByteArray result;
+
+ _BEGIN();
+
+ if (tlv.decodeTLV() == true) {
+ switch (tlv.getTag()) {
+ case DO_TAG_AID_REF :
+ if (tlv.getLength() > 0) {
+ result = tlv.getValue();
+ } else {
+ result = AccessControlList::ALL_SE_APPS;
+ }
+ break;
+
+ case DO_TAG_AID_REF_DEFAULT :
+ result = AccessControlList::DEFAULT_SE_APP;
+ break;
+
+ default :
+ _ERR("decodeTLV failed, %s", tlv.toString());
+ break;
+ }
+ } else {
+ _ERR("decodeTLV failed, %s", tlv.toString());
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static ByteArray getHash(SimpleTLV &tlv)
+ {
+ ByteArray result;
+
+ _BEGIN();
+
+ if (tlv.decodeTLV() == true &&
+ tlv.getTag() == DO_TAG_HASH_REF) {
+ if (tlv.getLength() > 0) {
+ result = tlv.getValue();
+ } else {
+ result = AccessControlList::ALL_DEVICE_APPS;
+ }
+ } else {
+ _ERR("decodeTLV failed, %s", tlv.toString());
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static int parseRefDO(SimpleTLV &tlv, ByteArray &aid, ByteArray &hash)
+ {
+ int result = SCARD_ERROR_OK;
+
+ _BEGIN();
+
+ if (tlv.decodeTLV() == true && tlv.getTag() == DO_TAG_REF) {
+ tlv.enterToValueTLV();
+ aid = getAID(tlv);
+ hash = getHash(tlv);
+ tlv.returnToParentTLV();
+
+ _DBG("aid : %s, hash : %s", aid.toString(), hash.toString());
+ } else {
+ _ERR("unknown tag : %s", tlv.toString());
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static int parseARDO(SimpleTLV &tlv, vector<ByteArray> &apduRule,
+ ByteArray &nfcRule)
+ {
+ int result = SCARD_ERROR_OK;
+
+ _BEGIN();
+
+ if (tlv.decodeTLV() == true && tlv.getTag() == DO_TAG_AR) {
+ tlv.enterToValueTLV();
+ while (tlv.decodeTLV() == true) {
+ int length = tlv.getLength();
+
+ switch (tlv.getTag()) {
+ case DO_TAG_APDU_AR :
+ if (length > 1) {
+ int i;
+ ByteArray temp;
+
+ for (i = 0; i < length; i += 8) {
+ temp.setBuffer(tlv.getValue().getBuffer(i), 8);
+ _DBG("apdu rule[%d] : %s", temp.getLength(), temp.toString());
+ apduRule.push_back(temp);
+ }
+ } else if (length == 1){
+ _DBG("apdu rule : %s", tlv.getValue().toString());
+ apduRule.push_back(tlv.getValue());
+ } else {
+ _ERR("invalid rule, %s", tlv.toString());
+ }
+ break;
+
+ case DO_TAG_NFC_AR :
+ nfcRule = tlv.getValue();
+ _DBG("nfc rule : %s", tlv.getValue().toString());
+ break;
+
+ default :
+ break;
+ }
+ }
+ tlv.returnToParentTLV();
+ } else {
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ _END();
+
+ return result;
+ }
+
+ void GPARAACL::addCondition(const ByteArray &aid, const ByteArray &hash,
+ const vector<ByteArray> &apduRule, const ByteArray &nfcRule)
+ {
+ AccessCondition &condition = getAccessCondition(aid);
+
+ _BEGIN();
+
+ condition.addAccessRule(hash);
+
+ if (apduRule.size() > 0) {
+ if (apduRule.size() == 1 &&
+ apduRule[0].getLength() == 1) {
+ /* apdu grant/deny */
+ if (apduRule[0][0] == 1) {
+ condition.setAPDUAccessRule(hash, true);
+ } else {
+ condition.setAPDUAccessRule(hash, false);
+ }
+ } else {
+ size_t i;
+
+ for (i = 0; i < apduRule.size(); i++) {
+ condition.addAPDUAccessRule(hash, apduRule[i]);
+ }
+ }
+ }
+
+ if (nfcRule.getLength() == 1) {
+ if (nfcRule[0] == 1) {
+ condition.setNFCAccessRule(hash, true);
+ } else {
+ condition.setNFCAccessRule(hash, false);
+ }
+ }
+
+ _END();
+ }
+
+ int GPARAACL::updateRule(ByteArray &data)
+ {
+ int result = SCARD_ERROR_OK;
+ SimpleTLV tlv(data);
+
+ _BEGIN();
+
+ while (tlv.decodeTLV() == true) {
+ if (tlv.getTag() == DO_TAG_REF_AR) {
+ ByteArray aid, hash, nfcRule;
+ vector<ByteArray> apduRule;
+
+ tlv.enterToValueTLV();
+ result = parseRefDO(tlv, aid, hash);
+
+ if (result >= SCARD_ERROR_OK) {
+ result = parseARDO(tlv, apduRule, nfcRule);
+ }
+ tlv.returnToParentTLV();
+
+ addCondition(aid, hash, apduRule, nfcRule);
+ } else {
+ _ERR("unknown tag, [%x]", tlv.getTag());
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ break;
+ }
+ }
+
+ _END();
+
+ return result;
+ }
+
+ int GPARAACL::loadACL(GPARAM &aram)
+ {
+ int result = SCARD_ERROR_OK;
+ ByteArray refreshTag, response;
+
+ _BEGIN();
+
+ if (aram.isClosed() == true) {
+ return SCARD_ERROR_ILLEGAL_STATE;
+ }
+
+ /* get refresh tag */
+ result = aram.getDataRefreshTag(refreshTag);
+ if (result >= SCARD_ERROR_OK) {
+ /* check refresh tag */
+ if (this->refreshTag.isEmpty() == true ||
+ this->refreshTag != refreshTag) {
+ result = aram.getDataAll(response);
+ if (result >= SCARD_ERROR_OK) {
+ result = updateRule(response);
+
+ /* update refresh tag */
+ this->refreshTag = refreshTag;
+ } else {
+ _ERR("getDataAll failed, [%x]", result);
+ }
+ }
+ else
+ {
+ _INFO("access rules are not changed. skip update");
+ }
+
+ printAccessControlList();
+ } else {
+ _ERR("transmitSync failed, %x", result);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ int GPARAACL::loadACL(Channel *channel)
+ {
+ int result = SCARD_ERROR_OK;
+
+ _BEGIN();
+
+ if (channel == NULL) {
+ return SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ GPARAM aram(channel);
+
+ result = aram.select();
+ if (result >= SCARD_ERROR_OK) {
+ result = loadACL(aram);
+ } else {
+ _ERR("select failed, [%x]", result);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static bool _isAuthorizedAccess(ByteArray &data, ByteArray &command)
+ {
+ vector<ByteArray> apduRule;
+ ByteArray nfcRule;
+ SimpleTLV tlv(data);
+ bool result = false;
+
+ if (parseARDO(tlv, apduRule, nfcRule) >= SCARD_ERROR_OK) {
+ if (apduRule.size() > 0) {
+ if (apduRule.size() > 1 ||
+ apduRule[0].getLength() != 1) {
+ if (command.getLength() > 0) {
+ /* TODO : check apdu rule */
+ } else {
+ /* check hash only */
+ result = true;
+ }
+ } else {
+ result = (apduRule[0][0] == 1 ? true : false);
+ }
+ } else {
+ _ERR("unknown data : %s", tlv.toString());
+ }
+ } else {
+ _ERR("parseARDO failed : %s", tlv.toString());
+ }
+
+ return result;
+ }
+
+ static bool _isAuthorizedNFCAccess(ByteArray &data)
+ {
+ vector<ByteArray> apduRule;
+ ByteArray nfcRule;
+ SimpleTLV tlv(data);
+ bool result = false;
+
+ if (parseARDO(tlv, apduRule, nfcRule) >= SCARD_ERROR_OK) {
+ if (nfcRule.getLength() == 1) {
+ result = (nfcRule[0] == 1 ? true : false);
+ } else {
+ _ERR("unknown data : %s", nfcRule.toString());
+ }
+ } else {
+ _ERR("parseARDO failed : %s", tlv.toString());
+ }
+
+ return result;
+ }
+
+ bool GPARAACL::isAuthorizedAccess(GPARAM &aram, ByteArray &aid,
+ ByteArray &certHash)
+ {
+ vector<ByteArray> hashes;
+
+ hashes.push_back(certHash);
+
+ return isAuthorizedAccess(aram, aid, hashes, ByteArray::EMPTY);
+ }
+
+ bool GPARAACL::isAuthorizedAccess(GPARAM &aram, unsigned char *aidBuffer,
+ unsigned int aidLength, unsigned char *certHashBuffer,
+ unsigned int certHashLength)
+ {
+ ByteArray aid(aidBuffer, aidLength);
+ ByteArray hash(certHashBuffer, certHashLength);
+
+ return isAuthorizedAccess(aram, aid, hash);
+ }
+
+ bool GPARAACL::isAuthorizedAccess(GPARAM &aram, ByteArray &aid,
+ vector<ByteArray> &certHashes)
+ {
+ return isAuthorizedAccess(aram, aid, certHashes, ByteArray::EMPTY);
+ }
+
+ bool GPARAACL::isAuthorizedAccess(GPARAM &aram, ByteArray &aid,
+ vector<ByteArray> &certHashes, ByteArray &command)
+ {
+ bool result = allGranted;
+ ByteArray data;
+ vector<ByteArray>::reverse_iterator item;
+
+ if (aram.isClosed() == true)
+ return result;
+
+ _BEGIN();
+
+ if (result == true) {
+ goto END;
+ }
+ /* Step A, find with aid and cert hashes */
+ for (item = certHashes.rbegin();
+ result == false && item != certHashes.rend();
+ item++) {
+ if (aram.getDataSpecific(aid, *item, data)
+ >= SCARD_ERROR_OK && data.getLength() > 0) {
+ result = _isAuthorizedAccess(data, command);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString(), (*item).toString());
+ goto END;
+ }
+ }
+
+ /* Step B, find with aid and ALL_DEVICES_APPS */
+ if (aram.getDataSpecific(aid, ByteArray::EMPTY, data)
+ >= SCARD_ERROR_OK && data.getLength() > 0) {
+ result = _isAuthorizedAccess(data, command);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString(), "All device applications");
+ goto END;
+ }
+
+ /* Step C, find with ALL_SE_APPS and hashes */
+ for (item = certHashes.rbegin();
+ result == false && item != certHashes.rend();
+ item++) {
+ if (aram.getDataSpecific(ByteArray::EMPTY, *item, data)
+ >= SCARD_ERROR_OK && data.getLength() > 0) {
+ result = _isAuthorizedAccess(data, command);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", (*item).toString());
+ goto END;
+ }
+ }
+
+ /* Step D, find with ALL_SE_APPS and ALL_DEVICES_APPS */
+ if (aram.getDataSpecific(ByteArray::EMPTY, ByteArray::EMPTY, data)
+ >= SCARD_ERROR_OK && data.getLength() > 0) {
+ result = _isAuthorizedAccess(data, command);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", "All device applications");
+ goto END;
+ }
+
+ END :
+ _END();
+
+ return result;
+ }
+
+ bool GPARAACL::isAuthorizedNFCAccess(GPARAM &aram, ByteArray &aid,
+ vector<ByteArray> &certHashes)
+ {
+ bool result = allGranted;
+ ByteArray data;
+ vector<ByteArray>::reverse_iterator item;
+
+ if (aram.isClosed() == true)
+ return result;
+
+ _BEGIN();
+
+ if (result == true) {
+ goto END;
+ }
+ /* Step A, find with aid and cert hashes */
+ for (item = certHashes.rbegin();
+ result == false && item != certHashes.rend();
+ item++) {
+ if (aram.getDataSpecific(aid, *item, data)
+ >= SCARD_ERROR_OK && data.getLength() > 0) {
+ result = _isAuthorizedNFCAccess(data);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString(), (*item).toString());
+ goto END;
+ }
+ }
+
+ /* Step B, find with aid and ALL_DEVICES_APPS */
+ if (aram.getDataSpecific(aid, ByteArray::EMPTY, data)
+ >= SCARD_ERROR_OK && data.getLength() > 0) {
+ result = _isAuthorizedNFCAccess(data);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString(), "All device applications");
+ goto END;
+ }
+
+ /* Step C, find with ALL_SE_APPS and hashes */
+ for (item = certHashes.rbegin();
+ result == false && item != certHashes.rend();
+ item++) {
+ if (aram.getDataSpecific(ByteArray::EMPTY, *item, data)
+ >= SCARD_ERROR_OK && data.getLength() > 0) {
+ result = _isAuthorizedNFCAccess(data);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", (*item).toString());
+ goto END;
+ }
+ }
+
+ /* Step D, find with ALL_SE_APPS and ALL_DEVICES_APPS */
+ if (aram.getDataSpecific(ByteArray::EMPTY, ByteArray::EMPTY, data)
+ >= SCARD_ERROR_OK && data.getLength() > 0) {
+ result = _isAuthorizedNFCAccess(data);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", "All device applications");
+ goto END;
+ }
+
+ END :
+ _END();
+
+ return result;
+ }
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+ * 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 */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "GPARAM.h"
+#include "APDUHelper.h"
+#include "FileObject.h"
+#include "NumberStream.h"
+#include "SimpleTLV.h"
+#include "ISO7816BERTLV.h"
+#include "AccessCondition.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ static unsigned char aid_aram[] = { 0xA0, 0x00, 0x00, 0x01, 0x51, 0x41, 0x43, 0x4C, 00 };
+ static ByteArray AID_ARAM(ARRAY_AND_SIZE(aid_aram));
+
+#define GET_DATA_ALL 0
+#define GET_DATA_SPECIFIC 1
+#define GET_DATA_REFRESH_TAG 2
+#define GET_DATA_NEXT 3
+
+#define ARAM_TAG_ALL_AR 0x0000FF40
+#define ARAM_TAG_AR 0x0000FF50
+#define ARAM_TAG_REFRESH 0x0000DF20
+
+#define DO_TAG_AID_REF 0x0000004F
+#define DO_TAG_AID_REF_DEFAULT 0x000000C0
+#define DO_TAG_HASH_REF 0x000000C1
+#define DO_TAG_APDU_AR 0x000000D0
+#define DO_TAG_NFC_AR 0x000000D1
+#define DO_TAG_REF 0x000000E1
+#define DO_TAG_REF_AR 0x000000E2
+#define DO_TAG_AR 0x000000E3
+
+ GPARAM::GPARAM(Channel *channel)
+ : FileObject(channel)
+ {
+ }
+
+ int GPARAM::select()
+ {
+ return FileObject::select(AID_ARAM);
+ }
+
+ static int doTransmit(Channel *channel, const ByteArray &command, ByteArray &response)
+ {
+ int result;
+ ByteArray resp;
+
+ _BEGIN();
+
+ result = channel->transmitSync(command, resp);
+ if (result == SCARD_ERROR_OK) {
+ result = ResponseHelper::getStatus(resp);
+ if (result >= SCARD_ERROR_OK) {
+ response = ResponseHelper::getDataField(resp);
+ _DBG("response[%d] : %s", response.getLength(), response.toString());
+ } else {
+ _ERR("transmit returns error, [%d]", result);
+ }
+ } else {
+ _ERR("transmitSync failed, [%d]", result);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static int doCommand(Channel *channel, int command, ByteArray &response)
+ {
+ int result;
+ APDUCommand helper;
+ ByteArray cmd, resp;
+
+ _BEGIN();
+
+ switch (command) {
+ case GET_DATA_ALL :
+ helper.setCommand(0x80, 0xCA, 0xFF, 0x40, ByteArray::EMPTY, 0);
+ break;
+
+ case GET_DATA_REFRESH_TAG :
+ helper.setCommand(0x80, 0xCA, 0xDF, 0x20, ByteArray::EMPTY, 0);
+ break;
+
+ case GET_DATA_NEXT :
+ helper.setCommand(0x80, 0xCA, 0xFF, 0x60, ByteArray::EMPTY, 0);
+ break;
+ }
+
+ helper.getBuffer(cmd);
+
+ _DBG("command[%d] : %s", cmd.getLength(), cmd.toString());
+
+ result = doTransmit(channel, cmd, response);
+
+ _END();
+
+ return result;
+ }
+
+ static int doCommand(Channel *channel, ByteArray &data, ByteArray &response)
+ {
+ int result;
+ APDUCommand helper;
+ ByteArray cmd;
+
+ helper.setCommand(0x80, 0xCA, 0xFF, 0x50, data, 0);
+ helper.getBuffer(cmd);
+
+ result = doTransmit(channel, cmd, response);
+
+ return result;
+ }
+
+ int GPARAM::getDataAll(ByteArray &data)
+ {
+ int result;
+ ByteArray response;
+
+ _BEGIN();
+
+ result = doCommand(channel, GET_DATA_ALL, response);
+ if (result >= SCARD_ERROR_OK) {
+ ISO7816BERTLV tlv(response);
+
+ if (tlv.decodeTLV() == true &&
+ tlv.getTag() == ARAM_TAG_ALL_AR) {
+ unsigned int length = tlv.getLength();
+
+ if (length > 0){
+ data = tlv.getValue();
+
+ while (length > data.getLength()) {
+ result = doCommand(channel, GET_DATA_NEXT, response);
+ if (result >= SCARD_ERROR_OK) {
+ data += response;
+ } else {
+ _ERR("generateCommand failed, [%d]", result);
+ data.releaseBuffer();
+ break;
+ }
+ }
+
+ _DBG("data[%d] : %s", data.getLength(), data.toString());
+ } else {
+ _INFO("Response-ALL-AR-DO is empty");
+ data.releaseBuffer();
+ }
+ } else {
+ _ERR("decodeTLV failed, %s", response.toString());
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ }
+ } else {
+ _ERR("generateCommand failed, [%d]", result);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static int createRefDo(const ByteArray &aid, const ByteArray &hash, ByteArray &refDo)
+ {
+ ByteArray temp;
+
+ temp = SimpleTLV::encode(DO_TAG_AID_REF, aid);
+ temp += SimpleTLV::encode(DO_TAG_HASH_REF, hash);
+
+ refDo = SimpleTLV::encode(DO_TAG_REF, temp);
+ _DBG("encoded Ref DO : %s", refDo.toString());
+
+ return SCARD_ERROR_OK;
+ }
+
+ int GPARAM::getDataSpecific(const ByteArray &aid, const ByteArray &hash,
+ ByteArray &data)
+ {
+ int result;
+ ByteArray refDo, response;
+
+ _BEGIN();
+
+ createRefDo(aid, hash, refDo);
+
+ result = doCommand(channel, refDo, response);
+ if (result >= SCARD_ERROR_OK) {
+ ISO7816BERTLV tlv(response);
+
+ if (tlv.decodeTLV() == true &&
+ tlv.getTag() == ARAM_TAG_AR) {
+ unsigned int length = tlv.getLength();
+
+ if (length > 0){
+ data = tlv.getValue();
+
+ while (length > data.getLength()) {
+ result = doCommand(channel, GET_DATA_NEXT, response);
+ if (result >= SCARD_ERROR_OK) {
+ data += response;
+ } else {
+ _ERR("generateCommand failed, [%d]", result);
+ data.releaseBuffer();
+ break;
+ }
+ }
+ _DBG("data[%d] : %s", data.getLength(), data.toString());
+ } else {
+ _INFO("Response-ALL-AR-DO is empty");
+ data.releaseBuffer();
+ }
+ } else {
+ _ERR("decodeTLV failed, %s", response.toString());
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ }
+ } else {
+ _ERR("doCommand failed, [%d]", result);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ int GPARAM::getDataRefreshTag(ByteArray &tag)
+ {
+ int result;
+ ByteArray response;
+
+ _BEGIN();
+
+ result = doCommand(channel, GET_DATA_REFRESH_TAG, response);
+ if (result >= SCARD_ERROR_OK) {
+ ISO7816BERTLV tlv(response);
+
+ if (tlv.decodeTLV() == true &&
+ tlv.getTag() == ARAM_TAG_REFRESH &&
+ tlv.getLength() == 8) {
+ tag = tlv.getValue();
+ result = SCARD_ERROR_OK;
+ _DBG("refreshTag[%d] : %s", tag.getLength(), tag.toString());
+ } else {
+ _ERR("decodeTLV failed, %s", response.toString());
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ }
+ } else {
+ _ERR("generateCommand failed, [%d]", result);
+ }
+
+ _END();
+
+ return result;
+ }
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+ * 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 */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "GPARFACL.h"
+#include "PKCS15ODF.h"
+#include "PKCS15DODF.h"
+#include "NumberStream.h"
+#include "SimpleTLV.h"
+#include "AccessCondition.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ static unsigned char oid_globalplatform[] = { 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x81, 0x48, 0x01, 0x01 };
+ static ByteArray OID_GLOBALPLATFORM(ARRAY_AND_SIZE(oid_globalplatform));
+
+ GPARFACL::GPARFACL() : AccessControlList()
+ {
+ }
+
+ GPARFACL::~GPARFACL()
+ {
+ }
+
+ int GPARFACL::loadACL(Channel *channel)
+ {
+ int result = SCARD_ERROR_OK;
+
+ _BEGIN();
+
+ if (channel == NULL)
+ {
+ return SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ PKCS15 pkcs15(channel);
+
+ /* basically, all requests will be accepted when PKCS #15 doesn't exist or global platform OID is not placed */
+ allGranted = false;
+
+ result = pkcs15.select();
+ if (result >= SCARD_ERROR_OK)
+ {
+ PKCS15ODF *odf;
+
+ result = SCARD_ERROR_OK;
+ allGranted = true;
+
+ if ((odf = pkcs15.getODF()) != NULL)
+ {
+ PKCS15DODF *dodf;
+
+ if ((dodf = odf->getDODF()) != NULL)
+ {
+ result = loadAccessControl(channel, dodf);
+ if (result == SCARD_ERROR_OK)
+ {
+ printAccessControlList();
+ }
+ else
+ {
+ _INFO("loadAccessControl failed, every request will be accepted.");
+ result = SCARD_ERROR_OK;
+ }
+ }
+ else
+ {
+ _INFO("dodf null, every request will be accepted.");
+ }
+ }
+ else
+ {
+ _INFO("odf null, every request will be accepted.");
+ }
+ }
+ else
+ {
+ _ERR("failed to open PKCS15, every request will be denied.");
+ }
+
+ _END();
+
+ return result;
+ }
+
+ int GPARFACL::loadAccessControl(Channel *channel, PKCS15DODF *dodf)
+ {
+ int result = -1;
+ ByteArray path;
+
+ if ((result = dodf->searchOID(OID_GLOBALPLATFORM, path)) == 0)
+ {
+ ByteArray data;
+ FileObject file(channel);
+
+ _DBG("oid path : %s", path.toString());
+
+ file.select(NumberStream::getLittleEndianNumber(path));
+ file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
+
+ _DBG("data : %s", data.toString());
+
+ /* PKCS #15 and DODF OID exists. apply access control rule!! */
+ allGranted = false;
+
+ SimpleTLV tlv(data);
+
+ if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : AccessControlMainFile */
+ {
+ tlv.enterToValueTLV();
+
+ /* refresh Tag */
+ ByteArray refreshTag;
+
+ refreshTag = SimpleTLV::getOctetString(tlv);
+ _DBG("current refresh tag : %s", refreshTag.toString());
+
+ if (this->refreshTag != refreshTag) /* need to update access control list */
+ {
+ this->refreshTag = refreshTag;
+
+ releaseACL();
+
+ /* access control rule path */
+ if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
+ {
+ /* TODO : parse path */
+ ByteArray path;
+
+ /* OCTET STRING */
+ path = SimpleTLV::getOctetString(tlv.getValue());
+ _DBG("access control rule path : %s", path.toString());
+
+ if (loadRules(channel, path) == 0)
+ {
+ _DBG("loadRules success");
+ }
+ else
+ {
+ _ERR("loadRules failed");
+ }
+ }
+ }
+ else
+ {
+ _INFO("access rules are not changed. skip update");
+ }
+ tlv.returnToParentTLV();
+ }
+ else
+ {
+ _ERR("tlv.decodeTLV failed");
+ }
+ }
+ else
+ {
+ _ERR("OID not found");
+ }
+
+ return result;
+ }
+
+ int GPARFACL::loadRules(Channel *channel, const ByteArray &path)
+ {
+ FileObject file(channel);
+ ByteArray data, aid;
+
+ file.select(NumberStream::getLittleEndianNumber(path));
+ file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
+
+ _DBG("data : %s", data.toString());
+
+ SimpleTLV tlv(data);
+
+ while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Rule */
+ {
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV() == true)
+ {
+ /* target */
+ switch (tlv.getTag())
+ {
+ case 0xA0 : /* CHOICE 0 : EXPLICIT AID */
+ /* OCTET STRING */
+ aid = SimpleTLV::getOctetString(tlv.getValue());
+ break;
+
+ case 0x81 : /* CHOICE 1?? : default */
+ aid = AccessControlList::DEFAULT_SE_APP;
+ break;
+
+ case 0x82 : /* CHOICE 2?? : any application */
+ aid = AccessControlList::ALL_SE_APPS;
+ break;
+ }
+
+ _DBG("aid : %s", aid.toString());
+
+ /* access condition path */
+ if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
+ {
+ ByteArray path;
+
+ /* OCTET STRING */
+ path = SimpleTLV::getOctetString(tlv.getValue());
+ _DBG("path : %s", path.toString());
+
+ if (loadAccessConditions(channel, aid, path) == 0)
+ {
+ _DBG("loadCertHashes success");
+ }
+ else
+ {
+ _ERR("loadCertHashes failed");
+ }
+ }
+ else
+ {
+ _ERR("decodeTLV failed");
+ }
+ }
+ else
+ {
+ _ERR("decodeTLV failed");
+ }
+ tlv.returnToParentTLV();
+ }
+
+ return 0;
+ }
+
+ static void loadAPDUAccessRule(AccessRule *rule, const ByteArray &data)
+ {
+ SimpleTLV tlv(data);
+
+ if (tlv.decodeTLV() == true)
+ {
+ switch (tlv.getTag())
+ {
+ case 0xA0 : /* CHOICE 0 : APDUPermission */
+ rule->setAPDUAccessRule(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();
+
+ _DBG("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);
+
+ rule->addAPDUAccessRule(apdu, mask);
+ }
+ else
+ {
+ _ERR("Invalid APDU rule : %s", value.toString());
+ }
+ }
+ else
+ {
+ _ERR("Unknown tag : 0x%02X", tlv.getTag());
+ }
+ }
+ tlv.returnToParentTLV();
+ break;
+
+ default :
+ _ERR("Unknown tag : 0x%02X", tlv.getTag());
+ break;
+ }
+ }
+ }
+
+ static void loadNFCAccessRule(AccessRule *rule, const ByteArray &data)
+ {
+ rule->setNFCAccessRule(SimpleTLV::getBoolean(data));
+ }
+
+ static void loadAccessCondition(AccessCondition &condition, const ByteArray &data)
+ {
+ if (data.getLength() > 0)
+ {
+ SimpleTLV tlv(data);
+ ByteArray hash;
+
+ 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 */
+ _DBG("aid : %s, hash : %s", condition.getAID().toString(), tlv.getValue().toString());
+
+ hash = tlv.getValue();
+ condition.addAccessRule(tlv.getValue());
+ break;
+
+ case 0xA0 : /* CHOICE 0 : AccessRules */
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV())
+ {
+ AccessRule *rule = condition.getAccessRule(hash);
+ if (rule == NULL) {
+ condition.addAccessRule(hash);
+ rule = condition.getAccessRule(hash);
+ }
+
+ switch (tlv.getTag())
+ {
+ case 0xA0 : /* CHOICE 0 : APDUAccessRule */
+ loadAPDUAccessRule(rule, tlv.getValue());
+ break;
+
+ case 0xA1 : /* CHOICE 1 : NFCAccessRule */
+ loadNFCAccessRule(rule, tlv.getValue());
+ break;
+
+ default :
+ _ERR("Unknown tag : 0x%02X", tlv.getTag());
+ break;
+ }
+ }
+ else
+ {
+ _ERR("tlv.decodeTLV failed");
+ }
+ tlv.returnToParentTLV();
+ break;
+
+ default :
+ _ERR("Unknown tag : 0x%02X", tlv.getTag());
+ break;
+ }
+ }
+ else
+ {
+ _ERR("tlv.decodeTLV failed");
+ }
+ tlv.returnToParentTLV();
+ }
+ else
+ {
+ _INFO("access denied for all applications, aid : %s", condition.getAID().toString());
+
+ condition.setAccessCondition(false);
+ break;
+ }
+ }
+ }
+ else
+ {
+ _INFO("access denied for all applications, aid : %s", condition.getAID().toString());
+
+ condition.setAccessCondition(false);
+ }
+ }
+
+ int GPARFACL::loadAccessConditions(Channel *channel, const ByteArray &aid, const ByteArray &path)
+ {
+ FileObject file(channel);
+ ByteArray data;
+
+ file.select(NumberStream::getLittleEndianNumber(path));
+ file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
+
+ _DBG("data : %s", data.toString());
+
+ AccessCondition condition;
+
+ condition.setAID(aid);
+ loadAccessCondition(condition, data);
+
+ pair<ByteArray, AccessCondition> newItem(aid, condition);
+
+ mapConditions.insert(newItem);
+
+ return 0;
+ }
+
+} /* namespace smartcard_service_api */
+++ /dev/null
-/*
- * 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 */
-
-/* SLP library header */
-
-/* local header */
-#include "Debug.h"
-#include "GPSEACL.h"
-#include "PKCS15ODF.h"
-#include "PKCS15DODF.h"
-#include "NumberStream.h"
-#include "SimpleTLV.h"
-#include "AccessCondition.h"
-
-#ifndef EXTERN_API
-#define EXTERN_API __attribute__((visibility("default")))
-#endif
-
-namespace smartcard_service_api
-{
- static unsigned char oid_globalplatform[] = { 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x81, 0x48, 0x01, 0x01 };
- ByteArray GPSEACL::OID_GLOBALPLATFORM(ARRAY_AND_SIZE(oid_globalplatform));
-
- GPSEACL::GPSEACL():AccessControlList()
- {
- }
-
- GPSEACL::~GPSEACL()
- {
- }
-
- int GPSEACL::loadACL(Channel *channel)
- {
- int result = 0;
- PKCS15 *pkcs15;
-
- if (channel == NULL)
- {
- return -1;
- }
-
- pkcs15 = new PKCS15(channel, channel->getSelectResponse());
- if (pkcs15 != NULL)
- {
- /* basically, all requests will be accepted when PKCS #15 doesn't exist or global platform OID is not placed */
- allGranted = true;
-
- if (pkcs15->isClosed() == false)
- {
- PKCS15ODF *odf;
-
- if ((odf = pkcs15->getODF()) != NULL)
- {
- PKCS15DODF *dodf;
-
- if ((dodf = odf->getDODF()) != NULL)
- {
- if (loadAccessControl(channel, dodf) == 0)
- {
- printAccessControlList();
-
- result = 0;
- }
- else
- {
- _ERR("loadAccessControl failed, every request will be accepted.");
- }
- }
- else
- {
- _ERR("dodf null, every request will be accepted.");
- }
- }
- else
- {
- _ERR("odf null, every request will be accepted.");
- }
- }
- else
- {
- _ERR("failed to open PKCS15, every request will be accepted.");
- }
-
- delete pkcs15;
- }
- else
- {
- return -1;
- }
-
- return result;
- }
-
- int GPSEACL::loadAccessControl(Channel *channel, PKCS15DODF *dodf)
- {
- int result = -1;
- ByteArray path;
-
- if ((result = dodf->searchOID(OID_GLOBALPLATFORM, path)) == 0)
- {
- ByteArray data;
- FileObject file(channel);
-
- _DBG("oid path : %s", path.toString());
-
- file.select(NumberStream::getLittleEndianNumber(path));
- file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
-
- _DBG("data : %s", data.toString());
-
- /* PKCS #15 and DODF OID exists. apply access control rule!! */
- allGranted = false;
-
- SimpleTLV tlv(data);
-
- if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : AccessControlMainFile */
- {
- tlv.enterToValueTLV();
-
- /* refresh Tag */
- ByteArray refreshTag;
-
- refreshTag = SimpleTLV::getOctetString(tlv);
- _DBG("current refresh tag : %s", refreshTag.toString());
-
- if (this->refreshTag != refreshTag) /* need to update access control list */
- {
- this->refreshTag = refreshTag;
-
- releaseACL();
-
- /* access control rule path */
- if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
- {
- /* TODO : parse path */
- ByteArray path;
-
- /* OCTET STRING */
- path = SimpleTLV::getOctetString(tlv.getValue());
- _DBG("access control rule path : %s", path.toString());
-
- if (loadRules(channel, path) == 0)
- {
- _DBG("loadRules success");
- }
- else
- {
- _ERR("loadRules failed");
- }
- }
- }
- tlv.returnToParentTLV();
- }
- else
- {
- _ERR("tlv.decodeTLV failed");
- }
- }
- else
- {
- _ERR("OID not found");
- }
-
- return result;
- }
-
- int GPSEACL::loadRules(Channel *channel, ByteArray path)
- {
- FileObject file(channel);
- ByteArray data, aid;
-
- file.select(NumberStream::getLittleEndianNumber(path));
- file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
-
- _DBG("data : %s", data.toString());
-
- SimpleTLV tlv(data);
-
- while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Rule */
- {
- tlv.enterToValueTLV();
- if (tlv.decodeTLV() == true)
- {
- /* target */
- switch (tlv.getTag())
- {
- case 0xA0 : /* CHOICE 0 : EXPLICIT AID */
- /* OCTET STRING */
- aid = SimpleTLV::getOctetString(tlv.getValue());
- break;
-
- case 0x81 : /* CHOICE 1?? : default */
- aid = AccessControlList::AID_DEFAULT;
- break;
-
- case 0x82 : /* CHOICE 2?? : any application */
- aid = AccessControlList::AID_ALL;
- break;
- }
-
- _DBG("aid : %s", aid.toString());
-
- /* access condition path */
- if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
- {
- ByteArray path;
-
- /* OCTET STRING */
- path = SimpleTLV::getOctetString(tlv.getValue());
- _DBG("path : %s", path.toString());
-
- if (loadAccessConditions(channel, aid, path) == 0)
- {
- _DBG("loadCertHashes success");
- }
- else
- {
- _ERR("loadCertHashes failed");
- }
- }
- else
- {
- _ERR("decodeTLV failed");
- }
- }
- else
- {
- _ERR("decodeTLV failed");
- }
- tlv.returnToParentTLV();
- }
-
- return 0;
- }
-
- int GPSEACL::loadAccessConditions(Channel *channel, ByteArray aid, ByteArray path)
- {
- FileObject file(channel);
- ByteArray data;
-
- file.select(NumberStream::getLittleEndianNumber(path));
- file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
-
- _DBG("data : %s", data.toString());
-
- AccessCondition condition;
-
- condition.loadAccessCondition(aid, data);
-
- pair<ByteArray, AccessCondition> newItem(aid, condition);
-
- mapConditions.insert(newItem);
-
- return 0;
- }
-
-} /* namespace smartcard_service_api */
-
-/* export C API */
-#define GP_SE_ACL_EXTERN_BEGIN \
- if (handle != NULL) \
- { \
- GPSEACL *acl = (GPSEACL *)handle;
-
-#define GP_SE_ACL_EXTERN_END \
- } \
- else \
- { \
- _ERR("Invalid param"); \
- }
-
-using namespace smartcard_service_api;
-
-EXTERN_API gp_se_acl_h gp_se_acl_create_instance()
-{
- GPSEACL *acl = new GPSEACL();
-
- return (gp_se_acl_h)acl;
-}
-
-EXTERN_API int gp_se_acl_load_acl(gp_se_acl_h handle, channel_h channel)
-{
- int result = -1;
-
- GP_SE_ACL_EXTERN_BEGIN;
- result = acl->loadACL((Channel *)channel);
- GP_SE_ACL_EXTERN_END;
-
- return result;
-}
-
-EXTERN_API int gp_se_acl_update_acl(gp_se_acl_h handle, channel_h channel)
-{
- int result = -1;
-
- GP_SE_ACL_EXTERN_BEGIN;
- acl->updateACL((Channel *)channel);
- GP_SE_ACL_EXTERN_END;
-
- return result;
-}
-
-EXTERN_API void gp_se_acl_release_acl(gp_se_acl_h handle)
-{
- GP_SE_ACL_EXTERN_BEGIN;
- acl->releaseACL();
- GP_SE_ACL_EXTERN_END;
-}
-
-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)
-{
- bool result = false;
-
- GP_SE_ACL_EXTERN_BEGIN;
- result = acl->isAuthorizedAccess(aidBuffer, aidLength, certHashBuffer, certHashLength);
- GP_SE_ACL_EXTERN_END;
-
- return result;
-}
-
-EXTERN_API void gp_se_acl_destroy_instance(gp_se_acl_h handle)
-{
- GP_SE_ACL_EXTERN_BEGIN;
- delete acl;
- GP_SE_ACL_EXTERN_END;
-}
namespace smartcard_service_api
{
- ISO7816BERTLV::ISO7816BERTLV():TLVHelper()
+ ISO7816BERTLV::ISO7816BERTLV()
+ : TLVHelper()
{
tagClass = 0;
encoding = 0;
}
- ISO7816BERTLV::ISO7816BERTLV(TLVHelper *parent):TLVHelper(parent)
+ ISO7816BERTLV::ISO7816BERTLV(TLVHelper *parent)
+ : TLVHelper(parent)
{
parentTLV = parent;
encoding = 0;
}
- ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array):TLVHelper(array)
+ ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array)
+ : TLVHelper(array)
{
tagClass = 0;
encoding = 0;
}
- ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array, TLVHelper *parent):TLVHelper(array, parent)
+ ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array, TLVHelper *parent)
+ : TLVHelper(array, parent)
{
parentTLV = parent;
}
/* first byte */
- tagClass = (buffer[0] & 0xE0) >> 6;
+ tagClass = (buffer[0] & 0xC0) >> 6;
encoding = (buffer[0] & 0x20) >> 5;
currentT = buffer[0];
0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
ByteArray PKCS15::PKCS15_AID(ARRAY_AND_SIZE(aid));
- PKCS15::PKCS15(Channel *channel)
- : PKCS15Object(channel), odf(NULL)
+ PKCS15::PKCS15(Channel *channel) :
+ PKCS15Object(channel), odf(NULL)
+ {
+ }
+
+ PKCS15::PKCS15(Channel *channel, const ByteArray &selectResponse) :
+ PKCS15Object(channel, selectResponse), odf(NULL)
+ {
+ }
+
+ PKCS15::~PKCS15()
+ {
+ if (odf != NULL)
+ {
+ delete odf;
+ odf = NULL;
+ }
+ }
+
+ int PKCS15::select()
{
int ret;
- ret = select(PKCS15::PKCS15_AID);
+ ret = PKCS15Object::select(PKCS15::PKCS15_AID);
if (ret >= SCARD_ERROR_OK)
{
_DBG("response : %s", selectResponse.toString());
{
_ERR("PKCS15 AID not found, search in EF DIR");
- if (selectFromEFDIR() == true)
+ ret = selectFromEFDIR();
+ if (ret >= SCARD_ERROR_OK)
{
_DBG("response : %s", selectResponse.toString());
}
{
_ERR("PKCS15 select failed, [%d]", ret);
}
- }
- PKCS15::PKCS15(Channel *channel, ByteArray selectResponse)
- : PKCS15Object(channel, selectResponse), odf(NULL)
- {
+ return ret;
}
- PKCS15::~PKCS15()
+ int PKCS15::selectFromEFDIR()
{
- if (odf != NULL)
- {
- delete odf;
- odf = NULL;
- }
- }
-
- bool PKCS15::selectFromEFDIR()
- {
- bool result = false;
+ int ret;
ByteArray path;
EFDIR dir(channel);
- path = dir.getPathByAID(PKCS15_AID);
- if (path.getLength() > 0)
+ ret = dir.select();
+ if (ret >= SCARD_ERROR_OK)
{
- int ret;
-
- ret = select(path, false);
- if (ret >= SCARD_ERROR_OK)
+ path = dir.getPathByAID(PKCS15_AID);
+ if (path.getLength() > 0)
{
- result = true;
+ ret = PKCS15Object::select(path, false);
+ if (ret < SCARD_ERROR_OK)
+ {
+ _ERR("PKCS15 select failed, [%d]", ret);
+ }
}
else
{
- _ERR("path select failed, [%d]", ret);
+ _ERR("PKCS15 path is not found");
+ ret = SCARD_ERROR_NOT_SUPPORTED;
}
}
else
{
- _ERR("PKCS15 not found");
+ _ERR("select EFDIR failed, [%x]", -ret);
}
- return result;
+ return ret;
}
PKCS15ODF *PKCS15::getODF()
namespace smartcard_service_api
{
-// PKCS15DODF::PKCS15DODF():PKCS15Object()
-// {
-//
-// }
-
- PKCS15DODF::PKCS15DODF(unsigned int fid, Channel *channel):PKCS15Object(channel)
+ PKCS15DODF::PKCS15DODF(unsigned int fid, Channel *channel) :
+ PKCS15Object(channel)
{
int ret = 0;
}
}
- PKCS15DODF::PKCS15DODF(ByteArray path, Channel *channel):PKCS15Object(channel)
+ PKCS15DODF::PKCS15DODF(ByteArray path, Channel *channel) :
+ PKCS15Object(channel)
{
int ret = 0;
namespace smartcard_service_api
{
- PKCS15ODF::PKCS15ODF(Channel *channel)
- : PKCS15Object(channel), dodf(NULL)
+ PKCS15ODF::PKCS15ODF(Channel *channel) :
+ PKCS15Object(channel), dodf(NULL)
{
int ret = 0;
}
}
- PKCS15ODF::PKCS15ODF(Channel *channel, ByteArray selectResponse)
- : PKCS15Object(channel, selectResponse), dodf(NULL)
+ PKCS15ODF::PKCS15ODF(Channel *channel, ByteArray selectResponse) :
+ PKCS15Object(channel, selectResponse), dodf(NULL)
{
int ret = 0;
ByteArray odfData;
}
pkgmgrinfo_appinfo_destroy_appinfo(handle_appinfo);
- SCARD_DEBUG("package name : %s", pkgid);
-
if ((ret = pkgmgr_pkginfo_create_certinfo(&handle)) == 0)
{
if ((ret = pkgmgr_pkginfo_load_certinfo(pkgid, handle)) == 0)
return result;
}
- SCARD_DEBUG("package name : %s", pkgid);
-
if ((ret = pkgmgr_pkginfo_create_certinfo(&handle)) == 0)
{
if ((ret = pkgmgr_pkginfo_load_certinfo(pkgid, handle)) == 0)
#define ACCESSCONDITION_H_
/* standard library header */
-#include <vector>
#include <map>
+#include <vector>
/* SLP library header */
namespace smartcard_service_api
{
- class APDUAccessRule
+ class AccessRule
{
private :
- bool permission;
- map<ByteArray, ByteArray> mapApduFilters;
+ bool apduRule;
+ bool nfcRule;
+ vector<pair<ByteArray, ByteArray> > listFilters;
+
+ void printAccessRules();
public :
- APDUAccessRule()
+ AccessRule() : apduRule(true), nfcRule(true)
{
- permission = true;
}
- void loadAPDUAccessRule(const ByteArray &data);
- bool isAuthorizedAccess(const ByteArray &command);
+ inline void setAPDUAccessRule(bool rule) { apduRule = rule; }
+ inline void setNFCAccessRule(bool rule) { nfcRule = rule; }
- void printAPDUAccessRules();
- };
-
- class NFCAccessRule
- {
- private :
- bool permission;
+ void addAPDUAccessRule(const ByteArray &apdu,
+ const ByteArray &mask);
- public :
- NFCAccessRule()
+ inline bool isAuthorizedAccess(void)
{
- permission = true;
+ return (apduRule || (listFilters.size() > 0));
}
+ bool isAuthorizedAPDUAccess(const ByteArray &command);
+ bool isAuthorizedNFCAccess(void);
- void loadNFCAccessRule(const ByteArray &data);
- bool isAuthorizedAccess(void);
-
- void printNFCAccessRules();
+ friend class AccessCondition;
};
class AccessCondition
private :
bool permission;
ByteArray aid;
- vector<ByteArray> hashes;
- APDUAccessRule apduRule;
- NFCAccessRule nfcRule;
+ map<ByteArray, AccessRule> mapRules;
+
+ void printAccessConditions();
public :
AccessCondition() : permission(false)
{
}
- void loadAccessCondition(ByteArray &aid, ByteArray &data);
- bool isAuthorizedAccess(ByteArray &certHash);
- bool isAuthorizedAPDUAccess(ByteArray &command);
- bool isAuthorizedNFCAccess();
+ inline void setAID(const ByteArray &aid) { this->aid = aid; }
+ inline ByteArray getAID() { return aid; }
+ inline void setAccessCondition(bool rule) { permission = rule; }
+ void addAccessRule(const ByteArray &hash);
+ AccessCondition *getAccessCondition(const ByteArray &hash);
- void printAccessConditions();
+ void setAPDUAccessRule(const ByteArray &certHash, bool rule);
+ void addAPDUAccessRule(const ByteArray &certHash,
+ const ByteArray &apdu, const ByteArray &mask);
+ void addAPDUAccessRule(const ByteArray &certHash,
+ const ByteArray &rule);
+
+ void setNFCAccessRule(const ByteArray &certHash, bool rule);
+
+ bool isAuthorizedAccess(const ByteArray &certHash);
+ bool isAuthorizedAPDUAccess(const ByteArray &certHash,
+ const ByteArray &command);
+ bool isAuthorizedNFCAccess(const ByteArray &certHash);
+
+ AccessRule *getAccessRule(const ByteArray &certHash);
+
+ friend class AccessControlList;
};
} /* namespace smartcard_service_api */
/* local header */
#include "ByteArray.h"
#include "Channel.h"
+#include "AccessCondition.h"
using namespace std;
namespace smartcard_service_api
{
- class AccessCondition;
-
class AccessControlList
{
protected:
map<ByteArray, AccessCondition> mapConditions;
bool allGranted;
+ AccessRule *findAccessRule(const ByteArray &aid,
+ const ByteArray &hash);
+ AccessCondition &getAccessCondition(const ByteArray &aid);
+
void printAccessControlList();
- bool isAuthorizedAccess(ByteArray aid, ByteArray certHash, bool update);
public:
- static ByteArray AID_ALL;
- static ByteArray AID_DEFAULT;
+ static ByteArray ALL_SE_APPS;
+ static ByteArray DEFAULT_SE_APP;
+ static ByteArray ALL_DEVICE_APPS;
AccessControlList();
virtual ~AccessControlList();
int updateACL(Channel *channel) { return loadACL(channel); }
void releaseACL();
- bool isAuthorizedAccess(ByteArray aid, ByteArray certHash);
- bool isAuthorizedAccess(unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength);
- bool isAuthorizedAccess(ByteArray aid, vector<ByteArray> &certHashes);
+ bool isAuthorizedAccess(ByteArray &aid,
+ ByteArray &certHash);
+ bool isAuthorizedAccess(unsigned char *aidBuffer,
+ unsigned int aidLength, unsigned char *certHashBuffer,
+ unsigned int certHashLength);
+ bool isAuthorizedAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes);
+ bool isAuthorizedAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes, ByteArray &command);
+ bool isAuthorizedNFCAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes);
};
} /* namespace smartcard_service_api */
uint32_t copyFromArray(uint8_t *array, uint32_t bufferLen) const;
+ ByteArray sub(uint32_t offset, uint32_t size) const;
+
/* operator overloading */
ByteArray &operator =(const ByteArray &T);
ByteArray operator +(const ByteArray &T);
bool operator >(const ByteArray &T) const;
uint8_t &operator [](uint32_t index) const;
- inline bool isEmpty() { return (buffer == (void *)0 || length == 0); }
+ inline bool isEmpty() const { return (buffer == (void *)0 || length == 0); }
const char *toString();
};
ByteArray parseRecord(Record &record, ByteArray &aid);
public:
- static const unsigned int EFDIR_FID = 0x002f;
-
EFDIR(Channel *channel);
EFDIR(Channel *channel, ByteArray selectResponse);
~EFDIR();
+ int select();
+
ByteArray getPathByAID(ByteArray &aid);
};
} /* namespace smartcard_service_api */
FCP fcp;
bool opened;
- int _select(ByteArray command);
+ int _select(const ByteArray &command);
protected:
ByteArray selectResponse;
- bool setSelectResponse(ByteArray response);
+ bool setSelectResponse(const ByteArray &response);
public:
static const int SUCCESS = 0;
static const unsigned int MF_FID = 0x003F;
FileObject(Channel *channel);
- FileObject(Channel *channel, ByteArray selectResponse);
+ FileObject(Channel *channel, const ByteArray &selectResponse);
~FileObject();
void close();
inline bool isClosed() { return (opened == false); }
- int select(ByteArray aid);
- int select(ByteArray path, bool fromCurrentDF);
+ int select(const ByteArray &aid);
+ int select(const ByteArray &path, bool fromCurrentDF);
int select(unsigned int fid);
int selectParent();
FCP *getFCP();
int readRecord(unsigned int sfi, unsigned int recordId, Record &result);
- int writeRecord(unsigned int sfi, Record record);
+ int writeRecord(unsigned int sfi, const Record &record);
- int searchRecord(unsigned int sfi, ByteArray searchParam, vector<int> &result);
+ int searchRecord(unsigned int sfi, const ByteArray &searchParam, vector<int> &result);
int readBinary(unsigned int sfi, unsigned int offset, unsigned int length, ByteArray &result);
- int writeBinary(unsigned int sfi, ByteArray data, unsigned int offset, unsigned int length);
+ int writeBinary(unsigned int sfi, const ByteArray &data, unsigned int offset, unsigned int length);
};
} /* namespace smartcard_service_api */
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifndef GPACE_H_
+#define GPACE_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "AccessControlList.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+ class GPACE : public AccessControlList
+ {
+ private :
+ AccessControlList *acl;
+
+ public :
+ GPACE();
+ ~GPACE();
+
+ int loadACL(Channel *channel);
+
+ bool isAuthorizedAccess(ByteArray &aid,
+ ByteArray &certHash);
+ bool isAuthorizedAccess(unsigned char *aidBuffer,
+ unsigned int aidLength, unsigned char *certHashBuffer,
+ unsigned int certHashLength);
+ bool isAuthorizedAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes);
+ bool isAuthorizedAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes, ByteArray &command);
+ bool isAuthorizedNFCAccess(ByteArray &aid,
+ vector<ByteArray> &certHashes);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+#endif /* GPACE_H_ */
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifndef GPARAACL_H_
+#define GPARAACL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "AccessControlList.h"
+#include "GPARAM.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+ class GPARAACL : public AccessControlList
+ {
+ private:
+ ByteArray refreshTag;
+
+ void addCondition(const ByteArray &aid, const ByteArray &hash,
+ const vector<ByteArray> &apduRule, const ByteArray &nfcRule);
+
+ int updateRule(ByteArray &data);
+
+ public:
+ GPARAACL();
+ ~GPARAACL();
+
+ int loadACL(Channel *channel);
+ int loadACL(GPARAM &aram);
+
+ bool isAuthorizedAccess(GPARAM &aram, ByteArray &aid,
+ ByteArray &certHash);
+ bool isAuthorizedAccess(GPARAM &aram, ByteArray &aid,
+ ByteArray &certHash, ByteArray &command);
+ bool isAuthorizedAccess(GPARAM &aram, unsigned char *aidBuffer,
+ unsigned int aidLength, unsigned char *certHashBuffer,
+ unsigned int certHashLength);
+ bool isAuthorizedAccess(GPARAM &aram, ByteArray &aid,
+ vector<ByteArray> &certHashes);
+ bool isAuthorizedAccess(GPARAM &aram, ByteArray &aid,
+ vector<ByteArray> &certHashes, ByteArray &command);
+ bool isAuthorizedNFCAccess(GPARAM &aram, ByteArray &aid,
+ vector<ByteArray> &certHashes);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+#endif /* GPARAACL_H_ */
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifndef GPARAM_H_
+#define GPARAM_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "FileObject.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class GPARAM : public FileObject
+ {
+ public:
+ GPARAM(Channel *channel);
+ GPARAM(Channel *channel, const ByteArray &selectResponse);
+ ~GPARAM() {}
+
+ int select();
+
+ int getDataAll(ByteArray &data);
+ int getDataSpecific(const ByteArray &aid, const ByteArray &hash, ByteArray &data);
+ int getDataRefreshTag(ByteArray &tag);
+
+ /* override not supported functions */
+ int select(const ByteArray &aid) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int select(const ByteArray &path, bool fromCurrentDF) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int select(unsigned int fid) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int selectParent() { return SCARD_ERROR_NOT_SUPPORTED; }
+ int readRecord(unsigned int sfi, unsigned int recordId, Record &result) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int writeRecord(unsigned int sfi, const Record &record) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int searchRecord(unsigned int sfi, const ByteArray &searchParam, vector<int> &result) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int readBinary(unsigned int sfi, unsigned int offset, unsigned int length, ByteArray &result) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int writeBinary(unsigned int sfi, const ByteArray &data, unsigned int offset, unsigned int length) { return SCARD_ERROR_NOT_SUPPORTED; }
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* GPARAM_H_ */
* limitations under the License.
*/
-#ifndef GPSEACL_H_
-#define GPSEACL_H_
+#ifndef GPARFACL_H_
+#define GPARFACL_H_
/* standard library header */
#ifdef __cplusplus
namespace smartcard_service_api
{
- class GPSEACL: public AccessControlList
+ class GPARFACL : public AccessControlList
{
private:
ByteArray refreshTag;
- static ByteArray OID_GLOBALPLATFORM;
-
int loadAccessControl(Channel *channel, PKCS15DODF *dodf);
- int loadRules(Channel *channel, ByteArray path);
- int loadAccessConditions(Channel *channel, ByteArray aid, ByteArray path);
+ int loadRules(Channel *channel, const ByteArray &path);
+ int loadAccessConditions(Channel *channel, const ByteArray &aid, const ByteArray &path);
public:
- GPSEACL();
- ~GPSEACL();
+ GPARFACL();
+ ~GPARFACL();
int loadACL(Channel *channel);
-
};
} /* namespace smartcard_service_api */
#endif /* __cplusplus */
-
-/* export C API */
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-typedef void *gp_se_acl_h;
-
-gp_se_acl_h gp_se_acl_create_instance();
-int gp_se_acl_load_acl(gp_se_acl_h handle, channel_h channel);
-int gp_se_acl_update_acl(gp_se_acl_h handle, channel_h channel);
-void gp_se_acl_release_acl(gp_se_acl_h handle);
-bool gp_se_acl_is_authorized_access(gp_se_acl_h handle, unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength);
-void gp_se_acl_destroy_instance(gp_se_acl_h handle);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* GPSEACL_H_ */
+#endif /* GPARFACL_H_ */
map<unsigned int, ByteArray> recordElement;
PKCS15ODF *odf;
- bool selectFromEFDIR();
+ int selectFromEFDIR();
public:
static ByteArray PKCS15_AID;
PKCS15(Channel *channel);
- PKCS15(Channel *channel, ByteArray selectResponse);
+ PKCS15(Channel *channel, const ByteArray &selectResponse);
~PKCS15();
+ int select();
+
PKCS15ODF *getODF();
int getTokenInfo(ByteArray &path);
};
namespace smartcard_service_api
{
- class PKCS15DODF: public PKCS15Object
+ class PKCS15DODF : public PKCS15Object
{
private:
map<ByteArray, PKCS15OID> mapOID;
bool parseData(ByteArray data);
public:
- PKCS15DODF();
PKCS15DODF(unsigned int fid, Channel *channel);
PKCS15DODF(ByteArray path, Channel *channel);
~PKCS15DODF();
namespace smartcard_service_api
{
- class PKCS15ODF: public PKCS15Object
+ class PKCS15ODF : public PKCS15Object
{
private:
bool parseData(ByteArray data);
namespace smartcard_service_api
{
ServerChannel::ServerChannel(ServerSession *session, void *caller,
- int channelNum, Terminal *terminal)
- : Channel(session)
+ int channelNum, Terminal *terminal) :
+ Channel(session), terminal(terminal), caller(caller),
+ privilege(true)
{
- this->terminal = terminal;
- this->caller = caller;
this->channelNum = channelNum;
- this->privilege = true;
}
ServerChannel::~ServerChannel()
#include "Debug.h"
#include "ServerSEService.h"
#include "ServerReader.h"
-#include "GPSEACL.h"
+#include "GPACE.h"
namespace smartcard_service_api
{
if (acList == NULL)
{
/* load access control */
- acList = new GPSEACL();
+ acList = new GPACE();
if (acList != NULL)
{
acList->loadACL(adminChannel);
#include "TerminalInterface.h"
#include "APDUHelper.h"
#include "SignatureHelper.h"
-#include "GPSEACL.h"
+#include "GPACE.h"
+#include "PKCS15.h"
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
AccessControlList *acList = NULL;
/* request open channel sequence */
- if ((acList = getAccessControlList(channel)) != NULL)
+ if ((acList = getAccessControlList(channel)) == NULL)
{
- PKCS15 pkcs15(channel);
-
- channel->setSelectResponse(pkcs15.getSelectResponse());
+ /* load access control defined by Global Platform */
+ GPACE *acl = new GPACE();
+ if (acl != NULL)
+ {
+ int ret;
- acList->loadACL(channel);
- result = acList->isAuthorizedAccess(aid, hashes);
+ ret = acl->loadACL(channel);
+ if (ret >= SCARD_ERROR_OK)
+ {
+ acList = acl;
+ addAccessControlList(channel, acList);
+ }
+ else
+ {
+ _ERR("unknown error, 0x%x", -ret);
+ delete acl;
+ }
+ }
+ else
+ {
+ _ERR("alloc failed");
+ }
}
else
{
result = false;
}
+ if (acList != NULL)
+ {
+ result = acList->isAuthorizedAccess(aid, hashes);
+ }
+
return result;
}
{
PKCS15 pkcs15(channel);
- if (pkcs15.isClosed() == false)
+ rv = pkcs15.select();
+ if (rv >= SCARD_ERROR_OK)
{
/* remove privilege mode */
channel->unsetPrivilegeMode();
}
else
{
- _ERR("select failed");
+ _ERR("select failed, [%x]", -rv);
service->closeChannel(result);
throw ExceptionBase(SCARD_ERROR_IO_FAILED);
}
else
{
- _ERR("select failed [%d]", rv);
+ _ERR("select failed [%x]", -rv);
service->closeChannel(result);
throw ExceptionBase(SCARD_ERROR_IO_FAILED);
}
}
- AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
+ void ServerResource::addAccessControlList(Terminal *terminal, AccessControlList *acl)
{
- AccessControlList *result = NULL;
map<Terminal *, AccessControlList *>::iterator item;
if ((item = mapACL.find(terminal)) == mapACL.end())
{
- /* load access control */
- result = new GPSEACL();
- if (result != NULL)
- {
- mapACL.insert(make_pair(terminal, result));
- }
- else
- {
- _ERR("alloc failed");
- }
+ mapACL.insert(make_pair(terminal, acl));
+ }
+ else
+ {
+ item->second = acl;
+ }
+ }
+
+ void ServerResource::addAccessControlList(ServerChannel *channel, AccessControlList *acl)
+ {
+ map<Terminal *, AccessControlList *>::iterator item;
+
+ if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
+ {
+ mapACL.insert(make_pair(channel->getTerminal(), acl));
}
else
{
+ item->second = acl;
+ }
+ }
+
+ AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
+ {
+ AccessControlList *result = NULL;
+ map<Terminal *, AccessControlList *>::iterator item;
+
+ if ((item = mapACL.find(terminal)) != mapACL.end())
+ {
result = item->second;
}
AccessControlList *result = NULL;
map<Terminal *, AccessControlList *>::iterator item;
- if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
- {
- /* load access control */
- result = new GPSEACL();
- if (result != NULL)
- {
- mapACL.insert(make_pair(channel->getTerminal(), result));
- }
- else
- {
- _ERR("alloc failed");
- }
- }
- else
+ if ((item = mapACL.find(channel->getTerminal())) != mapACL.end())
{
result = item->second;
}
}
}
+ bool ServerResource::isAuthorizedNFCAccess(Terminal *terminal, ByteArray &aid, vector<ByteArray> &hashes)
+ {
+ bool result = false;
+
+ if (terminal == NULL) {
+ return result;
+ }
+
+ int num = _openLogicalChannel(terminal);
+ if (num > 0) {
+ /* create channel instance */
+ ServerChannel *channel = new ServerChannel(NULL, NULL, num, terminal);
+ if (channel != NULL) {
+ AccessControlList *acl = getAccessControlList(channel);
+ if (acl == NULL) {
+
+ /* load access control defined by Global Platform */
+ GPACE *acl = new GPACE();
+ if (acl != NULL) {
+ int ret;
+
+ ret = acl->loadACL(channel);
+ if (ret >= SCARD_ERROR_OK) {
+ addAccessControlList(channel, acl);
+ } else {
+ _ERR("unknown error, 0x%x", -ret);
+ delete acl;
+ }
+ } else {
+ _ERR("alloc failed");
+ }
+ } else {
+ acl->updateACL(channel);
+ }
+
+ delete channel;
+
+ if (acl != NULL) {
+ result = acl->isAuthorizedNFCAccess(aid, hashes);
+ }
+ }
+ }
+
+ return result;
+ }
} /* namespace smartcard_service_api */
using namespace smartcard_service_api;
#include "ServerReader.h"
#include "ServerChannel.h"
#include "APDUHelper.h"
-#include "GPSEACL.h"
+#include "GPACE.h"
namespace smartcard_service_api
{
Channel *getChannel(int socket, unsigned int context, unsigned int channelID);
void removeChannel(int socket, unsigned int context, unsigned int channelID);
+ void addAccessControlList(Terminal *terminal, AccessControlList *acl);
+ void addAccessControlList(ServerChannel *channel, AccessControlList *acl);
AccessControlList *getAccessControlList(Terminal *terminal);
AccessControlList *getAccessControlList(ServerChannel *channel);
bool sendMessageToAllClients(Message &msg);
+ bool isAuthorizedNFCAccess(Terminal *terminal, ByteArray &aid,
+ vector<ByteArray> &hashes);
+
friend void terminalCallback(void *terminal, int event, int error, void *user_param);
};