Implement Access Control Enforcer using ARA
authorWonkyu Kwon <wonkyu.kwon@samsung.com>
Wed, 24 Jul 2013 08:26:34 +0000 (17:26 +0900)
committerWonkyu Kwon <wonkyu.kwon@samsung.com>
Wed, 24 Jul 2013 08:56:37 +0000 (17:56 +0900)
Change-Id: Ieb085b3125f682a7e6c6292c9074a28dd75dc7a6

34 files changed:
common/APDUHelper.cpp
common/AccessCondition.cpp
common/AccessControlList.cpp
common/ByteArray.cpp
common/CMakeLists.txt
common/EFDIR.cpp
common/FileObject.cpp
common/GPACE.cpp [new file with mode: 0644]
common/GPARAACL.cpp [new file with mode: 0644]
common/GPARAM.cpp [new file with mode: 0644]
common/GPARFACL.cpp [new file with mode: 0644]
common/GPSEACL.cpp [deleted file]
common/ISO7816BERTLV.cpp
common/PKCS15.cpp
common/PKCS15DODF.cpp
common/PKCS15ODF.cpp
common/SignatureHelper.cpp
common/include/AccessCondition.h
common/include/AccessControlList.h
common/include/ByteArray.h
common/include/EFDIR.h
common/include/FileObject.h
common/include/GPACE.h [new file with mode: 0644]
common/include/GPARAACL.h [new file with mode: 0644]
common/include/GPARAM.h [new file with mode: 0644]
common/include/GPARFACL.h [moved from common/include/GPSEACL.h with 55% similarity]
common/include/PKCS15.h
common/include/PKCS15DODF.h
common/include/PKCS15ODF.h
server/ServerChannel.cpp
server/ServerReader.cpp
server/ServerResource.cpp
server/ServerSession.cpp
server/include/ServerResource.h

index f37af2c..f864111 100644 (file)
@@ -21,6 +21,7 @@
 /* SLP library header */
 
 /* local header */
+#include "smartcard-types.h"
 #include "Debug.h"
 #include "APDUHelper.h"
 
@@ -44,7 +45,7 @@ namespace smartcard_service_api
        bool ResponseHelper::setResponse(const ByteArray &response)
        {
                bool result = false;
-               status = 0;
+               status = SCARD_ERROR_UNKNOWN;
                dataField.releaseBuffer();
 
                this->response = response;
index 964b4cf..865e5c0 100644 (file)
 /* 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 */
index 47c4982..3bc9f53 100644 (file)
 #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()
@@ -49,78 +49,190 @@ namespace smartcard_service_api
                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();
                }
index d68e47b..c62c775 100644 (file)
@@ -156,6 +156,22 @@ namespace smartcard_service_api
                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)
index ddd165c..3e07a78 100644 (file)
@@ -66,7 +66,6 @@ SET(EXPORT_HEADER
        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)
index 32b9e55..26022ba 100644 (file)
 
 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)
        {
        }
 
@@ -53,6 +43,19 @@ namespace smartcard_service_api
        {
        }
 
+       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;
index ce00b80..41c07ad 100644 (file)
@@ -32,7 +32,7 @@ namespace smartcard_service_api
                opened = false;
        }
 
-       FileObject::FileObject(Channel *channel, ByteArray selectResponse)
+       FileObject::FileObject(Channel *channel, const ByteArray &selectResponse)
                : ProviderHelper(channel)
        {
                opened = false;
@@ -50,7 +50,7 @@ namespace smartcard_service_api
                selectResponse.releaseBuffer();
        }
 
-       bool FileObject::setSelectResponse(ByteArray response)
+       bool FileObject::setSelectResponse(const ByteArray &response)
        {
                bool result = false;
 
@@ -78,13 +78,13 @@ namespace smartcard_service_api
                }
                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;
@@ -121,7 +121,7 @@ namespace smartcard_service_api
                return ret;
        }
 
-       int FileObject::select(ByteArray aid)
+       int FileObject::select(const ByteArray &aid)
        {
                int ret = ERROR_ILLEGAL_STATE;
                ByteArray command;
@@ -134,7 +134,7 @@ namespace smartcard_service_api
                return ret;
        }
 
-       int FileObject::select(ByteArray path, bool fromCurrentDF)
+       int FileObject::select(const ByteArray &path, bool fromCurrentDF)
        {
                int ret = ERROR_ILLEGAL_STATE;
                ByteArray command;
@@ -232,12 +232,12 @@ namespace smartcard_service_api
                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;
        }
@@ -277,7 +277,7 @@ namespace smartcard_service_api
                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;
diff --git a/common/GPACE.cpp b/common/GPACE.cpp
new file mode 100644 (file)
index 0000000..5f4cec2
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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 */
diff --git a/common/GPARAACL.cpp b/common/GPARAACL.cpp
new file mode 100644 (file)
index 0000000..4a93c33
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+ * 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 */
diff --git a/common/GPARAM.cpp b/common/GPARAM.cpp
new file mode 100644 (file)
index 0000000..ff7f12c
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * 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 */
diff --git a/common/GPARFACL.cpp b/common/GPARFACL.cpp
new file mode 100644 (file)
index 0000000..4cad060
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * 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 */
diff --git a/common/GPSEACL.cpp b/common/GPSEACL.cpp
deleted file mode 100644 (file)
index d5ecc11..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * 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;
-}
index eb0719d..2633526 100644 (file)
 
 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;
 
@@ -39,13 +41,15 @@ namespace smartcard_service_api
                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;
 
@@ -71,7 +75,7 @@ namespace smartcard_service_api
                }
 
                /* first byte */
-               tagClass = (buffer[0] & 0xE0) >> 6;
+               tagClass = (buffer[0] & 0xC0) >> 6;
                encoding = (buffer[0] & 0x20) >> 5;
 
                currentT = buffer[0];
index 6b4d0c7..dc195fa 100644 (file)
@@ -30,12 +30,30 @@ namespace smartcard_service_api
                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());
@@ -44,7 +62,8 @@ namespace smartcard_service_api
                {
                        _ERR("PKCS15 AID not found, search in EF DIR");
 
-                       if (selectFromEFDIR() == true)
+                       ret = selectFromEFDIR();
+                       if (ret >= SCARD_ERROR_OK)
                        {
                                _DBG("response : %s", selectResponse.toString());
                        }
@@ -57,49 +76,40 @@ namespace smartcard_service_api
                {
                        _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()
index e3d504f..2c5c6d2 100644 (file)
 
 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;
 
@@ -57,7 +53,8 @@ namespace smartcard_service_api
                }
        }
 
-       PKCS15DODF::PKCS15DODF(ByteArray path, Channel *channel):PKCS15Object(channel)
+       PKCS15DODF::PKCS15DODF(ByteArray path, Channel *channel) :
+               PKCS15Object(channel)
        {
                int ret = 0;
 
index 84c9590..aa37499 100644 (file)
@@ -26,8 +26,8 @@
 
 namespace smartcard_service_api
 {
-       PKCS15ODF::PKCS15ODF(Channel *channel)
-               PKCS15Object(channel), dodf(NULL)
+       PKCS15ODF::PKCS15ODF(Channel *channel) :
+               PKCS15Object(channel), dodf(NULL)
        {
                int ret = 0;
 
@@ -54,8 +54,8 @@ namespace smartcard_service_api
                }
        }
 
-       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;
index 6619975..9db34a1 100644 (file)
@@ -61,8 +61,6 @@ namespace smartcard_service_api
                }
                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)
@@ -159,8 +157,6 @@ namespace smartcard_service_api
                        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)
index 20ca90a..f9aac60 100644 (file)
@@ -18,8 +18,8 @@
 #define ACCESSCONDITION_H_
 
 /* standard library header */
-#include <vector>
 #include <map>
+#include <vector>
 
 /* SLP library header */
 
@@ -30,39 +30,34 @@ using namespace std;
 
 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
@@ -70,21 +65,37 @@ namespace smartcard_service_api
        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 */
index 1bbbb76..b2af0d4 100644 (file)
 /* 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();
@@ -54,9 +57,17 @@ namespace smartcard_service_api
                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 */
index cc08c5b..ee1edf9 100644 (file)
@@ -62,6 +62,8 @@ 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);
@@ -72,7 +74,7 @@ namespace smartcard_service_api
                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();
        };
 
index c2fd9f1..556cdf6 100644 (file)
@@ -35,12 +35,12 @@ namespace smartcard_service_api
                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 */
index 55bd2f7..d38105a 100644 (file)
@@ -39,11 +39,11 @@ 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;
@@ -58,13 +58,13 @@ namespace smartcard_service_api
                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();
 
@@ -74,12 +74,12 @@ namespace smartcard_service_api
                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 */
diff --git a/common/include/GPACE.h b/common/include/GPACE.h
new file mode 100644 (file)
index 0000000..4754d31
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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_ */
diff --git a/common/include/GPARAACL.h b/common/include/GPARAACL.h
new file mode 100644 (file)
index 0000000..305f7f9
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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_ */
diff --git a/common/include/GPARAM.h b/common/include/GPARAM.h
new file mode 100644 (file)
index 0000000..d4b3116
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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_ */
similarity index 55%
rename from common/include/GPSEACL.h
rename to common/include/GPARFACL.h
index 4e1bb8e..396adbe 100644 (file)
@@ -14,8 +14,8 @@
  * 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_ */
index b761eba..5d6f265 100644 (file)
@@ -36,15 +36,17 @@ namespace smartcard_service_api
                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);
        };
index 3860b54..24660fe 100644 (file)
@@ -27,7 +27,7 @@
 
 namespace smartcard_service_api
 {
-       class PKCS15DODF: public PKCS15Object
+       class PKCS15DODF : public PKCS15Object
        {
        private:
                map<ByteArray, PKCS15OID> mapOID;
@@ -35,7 +35,6 @@ namespace smartcard_service_api
                bool parseData(ByteArray data);
 
        public:
-               PKCS15DODF();
                PKCS15DODF(unsigned int fid, Channel *channel);
                PKCS15DODF(ByteArray path, Channel *channel);
                ~PKCS15DODF();
index 3139959..409ffde 100644 (file)
@@ -30,7 +30,7 @@ using namespace std;
 
 namespace smartcard_service_api
 {
-       class PKCS15ODF: public PKCS15Object
+       class PKCS15ODF : public PKCS15Object
        {
        private:
                bool parseData(ByteArray data);
index 8d13597..9765541 100644 (file)
 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()
index 8f0d614..43cd288 100644 (file)
@@ -26,7 +26,7 @@
 #include "Debug.h"
 #include "ServerSEService.h"
 #include "ServerReader.h"
-#include "GPSEACL.h"
+#include "GPACE.h"
 
 namespace smartcard_service_api
 {
@@ -95,7 +95,7 @@ namespace smartcard_service_api
                if (acList == NULL)
                {
                        /* load access control */
-                       acList = new GPSEACL();
+                       acList = new GPACE();
                        if (acList != NULL)
                        {
                                acList->loadACL(adminChannel);
index 2843fa7..4f70519 100644 (file)
@@ -29,7 +29,8 @@
 #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")))
@@ -396,14 +397,30 @@ namespace smartcard_service_api
                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
                {
@@ -411,6 +428,11 @@ namespace smartcard_service_api
                        result = false;
                }
 
+               if (acList != NULL)
+               {
+                       result = acList->isAuthorizedAccess(aid, hashes);
+               }
+
                return result;
        }
 
@@ -526,7 +548,8 @@ namespace smartcard_service_api
                        {
                                PKCS15 pkcs15(channel);
 
-                               if (pkcs15.isClosed() == false)
+                               rv = pkcs15.select();
+                               if (rv >= SCARD_ERROR_OK)
                                {
                                        /* remove privilege mode */
                                        channel->unsetPrivilegeMode();
@@ -534,7 +557,7 @@ namespace smartcard_service_api
                                }
                                else
                                {
-                                       _ERR("select failed");
+                                       _ERR("select failed, [%x]", -rv);
 
                                        service->closeChannel(result);
                                        throw ExceptionBase(SCARD_ERROR_IO_FAILED);
@@ -553,7 +576,7 @@ namespace smartcard_service_api
                                }
                                else
                                {
-                                       _ERR("select failed [%d]", rv);
+                                       _ERR("select failed [%x]", -rv);
 
                                        service->closeChannel(result);
                                        throw ExceptionBase(SCARD_ERROR_IO_FAILED);
@@ -646,26 +669,41 @@ namespace smartcard_service_api
                }
        }
 
-       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;
                }
 
@@ -677,20 +715,7 @@ namespace smartcard_service_api
                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;
                }
@@ -1037,6 +1062,51 @@ namespace smartcard_service_api
                }
        }
 
+       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;
index 7dc80fc..ff272f6 100644 (file)
@@ -26,7 +26,7 @@
 #include "ServerReader.h"
 #include "ServerChannel.h"
 #include "APDUHelper.h"
-#include "GPSEACL.h"
+#include "GPACE.h"
 
 namespace smartcard_service_api
 {
index ea544d8..337a9f0 100644 (file)
@@ -138,11 +138,16 @@ 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);
        };