2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 /* standard library header */
24 /* SLP library header */
28 #include "ServerResource.h"
29 #include "TerminalInterface.h"
30 #include "APDUHelper.h"
31 #include "SignatureHelper.h"
36 #define EXTERN_API __attribute__((visibility("default")))
39 namespace smartcard_service_api
41 unsigned int IntegerHandle::newHandle = 0;
42 set<unsigned int> IntegerHandle::setHandles;
43 PMutex IntegerHandle::mutexLock;
45 unsigned int IntegerHandle::assignHandle()
49 pair<set<unsigned int>::iterator, bool> result;
54 if (newHandle == (unsigned int)-1)
59 result = setHandles.insert(newHandle);
62 while (!result.second);
65 _DBG("assign handle : newHandle [%d]", newHandle);
70 void IntegerHandle::releaseHandle(unsigned int handle)
72 _DBG("will be released : Handle [%d]", handle);
76 setHandles.erase(handle);
80 #define OMAPI_SE_PATH "/usr/lib/se"
82 ServerResource::ServerResource()
83 : mainLoop(NULL), seLoaded(false)
87 serverIPC = ServerIPC::getInstance();
88 serverDispatcher = ServerDispatcher::getInstance();
93 ServerResource::~ServerResource()
97 ServerResource &ServerResource::getInstance()
99 static ServerResource serverResource;
101 return serverResource;
104 bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
108 if (getClient(socket) == NULL)
110 ClientInstance *instance = new ClientInstance(ioChannel, socket, watchID, state, pid);
111 if (instance != NULL)
113 mapClients.insert(make_pair(socket, instance));
118 _ERR("alloc failed");
123 _ERR("client already exist [%d]", socket);
129 ClientInstance *ServerResource::getClient(int socket)
131 ClientInstance *result = NULL;
132 map<int, ClientInstance *>::iterator item;
134 if ((item = mapClients.find(socket)) != mapClients.end())
136 result = item->second;
142 void ServerResource::setPID(int socket, int pid)
144 map<int, ClientInstance *>::iterator item;
146 if ((item = mapClients.find(socket)) != mapClients.end())
148 if (item->second->getPID() < 0)
149 item->second->setPID(pid);
153 int ServerResource::getClientCount()
155 return (int)mapClients.size();
158 void ServerResource::removeClient(int socket)
160 map<int, ClientInstance *>::iterator item;
162 if ((item = mapClients.find(socket)) != mapClients.end())
164 ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
167 mapClients.erase(item);
171 _DBG("client removed already [%d]", socket);
175 void ServerResource::removeClients()
177 map<int, ClientInstance *>::iterator item;
179 for (item = mapClients.begin(); item != mapClients.end(); item++)
181 ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
189 ServiceInstance *ServerResource::createService(int socket)
191 ServiceInstance *result = NULL;
192 ClientInstance *instance = NULL;
194 if ((instance = getClient(socket)) != NULL)
196 if ((result = instance->createService()) == NULL)
198 _ERR("ClientInstance::createService failed [%d]", socket);
203 _ERR("client doesn't exist [%d]", socket);
209 ServiceInstance *ServerResource::getService(int socket, unsigned int handle)
211 ServiceInstance *result = NULL;
212 ClientInstance *instance = NULL;
214 if ((instance = getClient(socket)) != NULL)
216 result = instance->getService(handle);
220 _ERR("client doesn't exist [%d]", socket);
226 void ServerResource::removeService(int socket, unsigned int handle)
228 ClientInstance *instance = NULL;
230 if ((instance = getClient(socket)) != NULL)
232 instance->removeService(handle);
236 _ERR("client doesn't exist [%d]", socket);
240 void ServerResource::removeServices(int socket)
242 ClientInstance *instance = NULL;
244 if ((instance = getClient(socket)) != NULL)
246 instance->removeServices();
250 _ERR("client doesn't exist [%d]", socket);
254 Terminal *ServerResource::getTerminal(unsigned int terminalID)
256 Terminal *result = NULL;
257 map<unsigned int, Terminal *>::iterator item;
259 if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
261 result = item->second;
265 _ERR("Terminal doesn't exist [%d]", terminalID);
271 Terminal *ServerResource::getTerminal(const char *name)
273 Terminal *result = NULL;
274 map<unsigned int, Terminal *>::iterator item;
276 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
278 if (strncmp(name, item->second->getName(), strlen(name)) == 0)
280 result = item->second;
288 Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID)
290 Terminal *result = NULL;
291 map<unsigned int, unsigned int>::iterator item;
293 if ((item = mapReaders.find(readerID)) != mapReaders.end())
295 result = getTerminal(item->second);
299 _ERR("Terminal doesn't exist, reader ID [%d]", readerID);
305 unsigned int ServerResource::getTerminalID(const char *name)
307 unsigned int result = IntegerHandle::INVALID_HANDLE;
308 map<unsigned int, Terminal *>::iterator item;
310 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
312 if (strncmp(name, item->second->getName(), strlen(name)) == 0)
314 result = item->first;
322 unsigned int ServerResource::createSession(int socket, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
324 unsigned int result = -1;
325 Terminal *temp = NULL;
326 ServiceInstance *instance = NULL;
328 if ((instance = getService(socket, handle)) != NULL)
330 if ((temp = getTerminalByReaderID(readerID)) != NULL)
332 result = instance->openSession(temp, certHashes, caller);
337 _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
343 ServerSession *ServerResource::getSession(int socket, unsigned int handle, unsigned int sessionID)
345 ServerSession *result = NULL;
346 ServiceInstance *instance = NULL;
348 if ((instance = getService(socket, handle)) != NULL)
350 result = instance->getSession(sessionID);
354 _ERR("Session doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, sessionID);
360 unsigned int ServerResource::getChannelCount(int socket, unsigned int handle, unsigned int sessionID)
362 unsigned int result = -1;
363 ServiceInstance *instance = NULL;
365 if ((instance = getService(socket, handle)) != NULL)
367 result = instance->getChannelCountBySession(sessionID);
371 _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
377 void ServerResource::removeSession(int socket, unsigned int handle, unsigned int sessionID)
379 ServiceInstance *instance = NULL;
381 if ((instance = getService(socket, handle)) != NULL)
383 instance->closeSession(sessionID);
387 _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
391 bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes)
394 AccessControlList *acList = NULL;
396 /* request open channel sequence */
397 if ((acList = getAccessControlList(channel)) == NULL)
399 /* load access control defined by Global Platform */
400 GPACE *acl = new GPACE();
405 ret = acl->loadACL(channel);
406 if (ret >= SCARD_ERROR_OK)
409 addAccessControlList(channel, acList);
413 _ERR("unknown error, 0x%x", -ret);
419 _ERR("alloc failed");
424 _ERR("acList is null");
430 result = acList->isAuthorizedAccess(aid, hashes);
436 int ServerResource::_openLogicalChannel(Terminal *terminal)
444 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
445 rv = terminal->transmitSync(command, response);
446 if (rv == 0 && response.getLength() >= 2)
448 ResponseHelper resp(response);
450 if (resp.getStatus() >= 0)
452 result = resp.getDataField()[0];
456 result = resp.getStatus();
461 _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
467 int ServerResource::_closeLogicalChannel(Terminal *terminal, int channelNum)
469 int result = SCARD_ERROR_UNKNOWN;
475 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
476 rv = terminal->transmitSync(command, response);
477 if (rv == 0 && response.getLength() >= 2)
479 ResponseHelper resp(response);
481 if (resp.getStatus() >= 0)
483 _DBG("channel closed [%d]", channelNum);
484 result = SCARD_ERROR_OK;
488 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
493 _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
499 unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
500 throw(ExceptionBase &)
502 unsigned int result = IntegerHandle::INVALID_HANDLE;
504 ServerChannel *channel = NULL;
506 /* open logical channel */
507 if (channelType == 1)
509 channelNum = _openLogicalChannel(terminal);
512 _DBG("channelNum [%d]", channelNum);
516 _ERR("_openLogicalChannel failed [%d]", channelNum);
517 throw ExceptionBase(SCARD_ERROR_NOT_ENOUGH_RESOURCE);
521 /* create channel instance */
522 result = service->openChannel(sessionID, channelNum, ByteArray::EMPTY);
523 if (result == IntegerHandle::INVALID_HANDLE)
525 _ERR("channel is null.");
527 /* close logical channel */
530 _closeLogicalChannel(terminal, channelNum);
532 throw ExceptionBase(SCARD_ERROR_OUT_OF_MEMORY);
535 channel = service->getChannel(result);
538 if (_isAuthorizedAccess(channel, service->getParent()->getPID(),
539 aid, service->getParent()->getCertificationHashes()) == true)
544 if (aid == PKCS15::PKCS15_AID)
546 PKCS15 pkcs15(channel);
548 rv = pkcs15.select();
549 if (rv >= SCARD_ERROR_OK)
551 /* remove privilege mode */
552 channel->unsetPrivilegeMode();
553 channel->setSelectResponse(pkcs15.getSelectResponse());
557 _ERR("select failed, [%x]", -rv);
559 service->closeChannel(result);
560 throw ExceptionBase(SCARD_ERROR_IO_FAILED);
565 FileObject file(channel);
567 rv = file.select(aid);
568 if (rv >= SCARD_ERROR_OK)
570 /* remove privilege mode */
571 channel->unsetPrivilegeMode();
572 channel->setSelectResponse(file.getSelectResponse());
576 _ERR("select failed [%x]", -rv);
578 service->closeChannel(result);
579 throw ExceptionBase(SCARD_ERROR_IO_FAILED);
585 _ERR("unauthorized access");
587 service->closeChannel(result);
588 throw ExceptionBase(SCARD_ERROR_SECURITY_NOT_ALLOWED);
594 unsigned int ServerResource::createChannel(int socket, unsigned int handle, unsigned int sessionID, int channelType, ByteArray aid)
595 throw(ExceptionBase &)
597 unsigned int result = -1;
598 ServiceInstance *service = NULL;
600 if ((service = getService(socket, handle)) != NULL)
602 if (service->isVaildSessionHandle(sessionID) == true)
604 ServerSession *session = NULL;
605 Terminal *terminal = NULL;
607 terminal = service->getTerminal(sessionID);
608 session = service->getSession(sessionID);
609 if (terminal != NULL && session != NULL)
611 result = _createChannel(terminal, service, channelType, sessionID, aid);
612 if (result == IntegerHandle::INVALID_HANDLE)
614 _ERR("create channel failed [%d]", sessionID);
619 _ERR("session is invalid [%d]", sessionID);
620 throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
625 _ERR("session is invalid [%d]", sessionID);
626 throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
631 _ERR("getService is failed [%d] [%d]", socket, handle);
632 throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
638 Channel *ServerResource::getChannel(int socket, unsigned int handle, unsigned int channelID)
640 Channel *result = NULL;
641 ServiceInstance *instance = NULL;
643 if ((instance = getService(socket, handle)) != NULL)
645 result = instance->getChannel(channelID);
649 _ERR("Channel doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, channelID);
655 void ServerResource::removeChannel(int socket, unsigned int handle, unsigned int channelID)
657 ServiceInstance *instance = NULL;
659 if ((instance = getService(socket, handle)) != NULL)
661 instance->closeChannel(channelID);
665 _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
669 void ServerResource::addAccessControlList(Terminal *terminal, AccessControlList *acl)
671 map<Terminal *, AccessControlList *>::iterator item;
673 if ((item = mapACL.find(terminal)) == mapACL.end())
675 mapACL.insert(make_pair(terminal, acl));
683 void ServerResource::addAccessControlList(ServerChannel *channel, AccessControlList *acl)
685 map<Terminal *, AccessControlList *>::iterator item;
687 if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
689 mapACL.insert(make_pair(channel->getTerminal(), acl));
697 AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
699 AccessControlList *result = NULL;
700 map<Terminal *, AccessControlList *>::iterator item;
702 if ((item = mapACL.find(terminal)) != mapACL.end())
704 result = item->second;
710 AccessControlList *ServerResource::getAccessControlList(ServerChannel *channel)
712 AccessControlList *result = NULL;
713 map<Terminal *, AccessControlList *>::iterator item;
715 if ((item = mapACL.find(channel->getTerminal())) != mapACL.end())
717 result = item->second;
723 Terminal *ServerResource::createInstance(void *library)
725 Terminal *terminal = NULL;
726 terminal_create_instance_fn createInstance = NULL;
728 /* create se instance */
729 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
730 if (createInstance != NULL)
732 terminal = (Terminal *)createInstance();
733 if (terminal != NULL)
735 _DBG("terminal [%p]", terminal);
739 _ERR("terminal is null");
744 _ERR("create_instance is null [%d]", errno);
750 bool ServerResource::appendSELibrary(char *library)
752 void *libHandle = NULL;
755 libHandle = dlopen(library, RTLD_LAZY);
756 if (libHandle != NULL)
758 Terminal *terminal = NULL;
760 terminal = createInstance(libHandle);
761 if (terminal != NULL)
763 unsigned int handle = IntegerHandle::assignHandle();
765 mapTerminals.insert(make_pair(handle, terminal));
766 libraries.push_back(libHandle);
768 terminal->setStatusCallback(&ServerResource::terminalCallback);
770 _DBG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
772 if (terminal->isSecureElementPresence() == true)
774 createReader(handle);
781 _ERR("terminal is null [%s]", library);
788 _ERR("it is not se file [%s] [%d]", library, errno);
794 int ServerResource::loadSecureElements()
798 if (seLoaded == false)
801 struct dirent *entry;
803 if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
805 while ((entry = readdir(dir)) != NULL)
807 if (strncmp(entry->d_name, ".", 1) != 0 &&
808 strncmp(entry->d_name, "..", 2) != 0)
812 /* TODO : need additional name rule :) */
814 /* append each files */
815 snprintf(fullPath, sizeof(fullPath),
816 "%s/%s", OMAPI_SE_PATH, entry->d_name);
818 SCARD_DEBUG("se name [%s]", fullPath);
820 result = appendSELibrary(fullPath);
837 void ServerResource::unloadSecureElements()
839 if (seLoaded == true)
842 map<unsigned int, Terminal *>::iterator item;
844 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
846 item->second->finalize();
848 IntegerHandle::releaseHandle(item->first);
851 mapTerminals.clear();
853 for (i = 0; i < libraries.size(); i++)
855 if (libraries[i] != NULL)
856 dlclose(libraries[i]);
865 bool ServerResource::isValidReaderHandle(unsigned int reader)
867 return (getTerminalByReaderID(reader) != NULL);
870 bool ServerResource::isValidSessionHandle(int socket, unsigned int handle, unsigned int session)
872 ServiceInstance *instance = NULL;
874 return (((instance = getService(socket, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
877 int ServerResource::getReadersInformation(ByteArray &info)
880 unsigned char *buffer = NULL;
881 unsigned int length = 0;
882 unsigned int offset = 0;
883 unsigned int nameLen = 0;
885 if (mapReaders.size() > 0)
887 Terminal *terminal = NULL;
888 map<unsigned int, unsigned int>::iterator item;
890 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
892 if (item->second != IntegerHandle::INVALID_HANDLE)
894 terminal = getTerminal(item->second);
895 if (terminal != NULL)
897 if (terminal->isSecureElementPresence())
899 length += sizeof(nameLen) + strlen(terminal->getName()) + sizeof(unsigned int);
906 buffer = new unsigned char[length];
909 memset(buffer, 0, length);
911 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
913 if (item->second != IntegerHandle::INVALID_HANDLE)
915 terminal = getTerminal(item->second);
916 if (terminal != NULL)
918 if (terminal->isSecureElementPresence())
920 nameLen = strlen(terminal->getName());
922 memcpy(buffer + offset, &nameLen, sizeof(nameLen));
923 offset += sizeof(nameLen);
925 memcpy(buffer + offset, terminal->getName(), nameLen);
928 memcpy(buffer + offset, &item->first, sizeof(unsigned int));
929 offset += sizeof(unsigned int);
935 info.setBuffer(buffer, length);
940 _ERR("alloc failed");
946 _INFO("no secure element");
952 bool ServerResource::sendMessageToAllClients(Message &msg)
955 map<int, ClientInstance *>::iterator item;
957 for (item = mapClients.begin(); item != mapClients.end(); item++)
959 if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
966 void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
968 _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
972 case Terminal::NOTIFY_SE_AVAILABLE :
974 ServerResource &instance = ServerResource::getInstance();
975 unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
978 _INFO("[NOTIFY_SE_AVAILABLE]");
980 terminalID = instance.getTerminalID((char *)terminal);
981 if (terminalID != IntegerHandle::INVALID_HANDLE)
983 /* send all client to refresh reader */
984 msg.message = msg.MSG_NOTIFY_SE_INSERTED;
985 msg.param1 = instance.createReader(terminalID);
986 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
988 instance.sendMessageToAllClients(msg);
993 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
995 ServerResource &instance = ServerResource::getInstance();
996 unsigned int readerID = IntegerHandle::INVALID_HANDLE;
999 _INFO("[NOTIFY_SE_NOT_AVAILABLE]");
1001 readerID = instance.getReaderID((char *)terminal);
1003 /* send all client to refresh reader */
1004 msg.message = msg.MSG_NOTIFY_SE_REMOVED;
1005 msg.param1 = readerID;
1006 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
1008 instance.sendMessageToAllClients(msg);
1009 instance.removeReader(readerID);
1014 _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1019 unsigned int ServerResource::createReader(unsigned int terminalID)
1021 unsigned int result = -1;
1023 result = IntegerHandle::assignHandle();
1025 mapReaders.insert(make_pair(result, terminalID));
1030 unsigned int ServerResource::getReaderID(const char *name)
1032 unsigned int result = IntegerHandle::INVALID_HANDLE, terminalID = IntegerHandle::INVALID_HANDLE;
1034 terminalID = getTerminalID(name);
1035 if (terminalID != IntegerHandle::INVALID_HANDLE)
1037 map<unsigned int, unsigned int>::iterator item;
1039 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
1041 if (item->second == terminalID)
1043 result = item->first;
1052 void ServerResource::removeReader(unsigned int readerID)
1054 map<unsigned int, unsigned int>::iterator item;
1056 if ((item = mapReaders.find(readerID)) != mapReaders.end())
1058 item->second = IntegerHandle::INVALID_HANDLE;
1062 bool ServerResource::isAuthorizedNFCAccess(Terminal *terminal, ByteArray &aid, vector<ByteArray> &hashes)
1064 bool result = false;
1066 if (terminal == NULL) {
1070 int num = _openLogicalChannel(terminal);
1072 /* create channel instance */
1073 ServerChannel *channel = new ServerChannel(NULL, NULL, num, terminal);
1074 if (channel != NULL) {
1075 AccessControlList *acl = getAccessControlList(channel);
1078 /* load access control defined by Global Platform */
1079 GPACE *acl = new GPACE();
1083 ret = acl->loadACL(channel);
1084 if (ret >= SCARD_ERROR_OK) {
1085 addAccessControlList(channel, acl);
1087 _ERR("unknown error, 0x%x", -ret);
1091 _ERR("alloc failed");
1094 acl->updateACL(channel);
1100 result = acl->isAuthorizedNFCAccess(aid, hashes);
1107 } /* namespace smartcard_service_api */
1109 using namespace smartcard_service_api;
1111 EXTERN_API void server_resource_set_main_loop_instance(void *instance)
1113 ServerResource::getInstance().setMainLoopInstance(instance);