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"
35 #define EXTERN_API __attribute__((visibility("default")))
38 namespace smartcard_service_api
40 unsigned int IntegerHandle::newHandle = 0;
41 set<unsigned int> IntegerHandle::setHandles;
42 PMutex IntegerHandle::mutexLock;
44 unsigned int IntegerHandle::assignHandle()
48 pair<set<unsigned int>::iterator, bool> result;
53 if (newHandle == (unsigned int)-1)
58 result = setHandles.insert(newHandle);
61 while (!result.second);
64 SCARD_DEBUG("assign handle : newHandle [%d]", newHandle);
69 void IntegerHandle::releaseHandle(unsigned int handle)
71 SCARD_DEBUG("will be released : Handle [%d]", handle);
75 setHandles.erase(handle);
79 #define OMAPI_SE_PATH "/usr/lib/se"
81 ServerResource::ServerResource()
82 : mainLoop(NULL), seLoaded(false)
86 serverIPC = ServerIPC::getInstance();
87 serverDispatcher = ServerDispatcher::getInstance();
92 ServerResource::~ServerResource()
94 unloadSecureElements();
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 SCARD_DEBUG_ERR("alloc failed");
123 SCARD_DEBUG_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 SCARD_DEBUG("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 bool ServerResource::createService(int socket, unsigned int context)
192 ClientInstance *instance = NULL;
194 if ((instance = getClient(socket)) != NULL)
196 if ((result = instance->createService(context)) == false)
198 SCARD_DEBUG_ERR("ClientInstance::createService failed [%d] [%d]", socket, context);
203 SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
209 ServiceInstance *ServerResource::getService(int socket, unsigned int context)
211 ServiceInstance *result = NULL;
212 ClientInstance *instance = NULL;
214 if ((instance = getClient(socket)) != NULL)
216 result = instance->getService(context);
220 SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
226 void ServerResource::removeService(int socket, unsigned int context)
228 ClientInstance *instance = NULL;
230 if ((instance = getClient(socket)) != NULL)
232 instance->removeService(context);
236 SCARD_DEBUG_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 SCARD_DEBUG_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 SCARD_DEBUG_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 SCARD_DEBUG_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 context, 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, context)) != NULL)
330 if ((temp = getTerminalByReaderID(readerID)) != NULL)
332 result = instance->openSession(temp, certHashes, caller);
337 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
343 ServerSession *ServerResource::getSession(int socket, unsigned int context, unsigned int sessionID)
345 ServerSession *result = NULL;
346 ServiceInstance *instance = NULL;
348 if ((instance = getService(socket, context)) != NULL)
350 result = instance->getSession(sessionID);
354 SCARD_DEBUG_ERR("Session doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, sessionID);
360 unsigned int ServerResource::getChannelCount(int socket, unsigned int context, unsigned int sessionID)
362 unsigned int result = -1;
363 ServiceInstance *instance = NULL;
365 if ((instance = getService(socket, context)) != NULL)
367 result = instance->getChannelCountBySession(sessionID);
371 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
377 void ServerResource::removeSession(int socket, unsigned int context, unsigned int sessionID)
379 ServiceInstance *instance = NULL;
381 if ((instance = getService(socket, context)) != NULL)
383 instance->closeSession(sessionID);
387 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
391 bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes)
395 #if 1 /* disable for temporary */
396 char filename[1024] = { 0, };
397 AccessControlList *acList = NULL;
399 /* check exceptional case */
400 SignatureHelper::getProcessName(pid, filename, sizeof(filename));
401 if (strncmp(filename, "ozD3Dw1MZruTDKHWGgYaDib2B2LV4/nfT+8b/g1Vsk8=", sizeof(filename)) != 0)
403 /* request open channel sequence */
404 if ((acList = getAccessControlList(channel)) != NULL)
407 PKCS15 pkcs15(channel);
409 acList->loadACL(channel);
410 result = acList->isAuthorizedAccess(aid, hashes);
412 result = acList->isAuthorizedAccess(aid, session->packageCert);
417 SCARD_DEBUG_ERR("acList is null");
427 unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
429 unsigned int result = IntegerHandle::INVALID_HANDLE;
435 if (channelType == 1)
438 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
439 rv = terminal->transmitSync(command, response);
441 if (rv == 0 && response.getLength() >= 2)
443 ResponseHelper resp(response);
445 if (resp.getStatus() == 0)
447 channelNum = resp.getDataField()[0];
449 SCARD_DEBUG("channelNum [%d]", channelNum);
453 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
460 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
468 apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_DF_NAME, APDUCommand::P2_SELECT_GET_FCP, aid, 0);
469 apdu.setChannel(1, channelNum);
470 apdu.getBuffer(command);
472 rv = terminal->transmitSync(command, response);
473 if (rv == 0 && response.getLength() >= 2)
475 ResponseHelper resp(response);
477 if (resp.getStatus() == 0)
479 result = service->openChannel(sessionID, channelNum, response);
480 if (result == IntegerHandle::INVALID_HANDLE)
482 SCARD_DEBUG_ERR("channel is null.");
487 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
492 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
498 int ServerResource::_openLogicalChannel(Terminal *terminal)
506 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
507 rv = terminal->transmitSync(command, response);
508 if (rv == 0 && response.getLength() >= 2)
510 ResponseHelper resp(response);
512 if (resp.getStatus() == 0)
514 result = resp.getDataField()[0];
518 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
521 /* TODO : if there is no more channel, return error code */
522 SCARD_DEBUG_ERR("no more logical channel");
529 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
535 int ServerResource::_closeLogicalChannel(Terminal *terminal, int channelNum)
543 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
544 rv = terminal->transmitSync(command, response);
545 if (rv == 0 && response.getLength() >= 2)
547 ResponseHelper resp(response);
549 if (resp.getStatus() == 0)
551 SCARD_DEBUG("channel closed [%d]", channelNum);
556 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
561 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
567 unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
569 unsigned int result = IntegerHandle::INVALID_HANDLE;
571 ServerChannel *channel = NULL;
573 /* open logical channel */
574 if (channelType == 1)
576 channelNum = _openLogicalChannel(terminal);
579 SCARD_DEBUG("channelNum [%d]", channelNum);
583 SCARD_DEBUG_ERR("_openLogicalChannel failed [%d]", channelNum);
588 /* create channel instance */
589 result = service->openChannel(sessionID, channelNum, ByteArray::EMPTY);
590 if (result == IntegerHandle::INVALID_HANDLE)
592 SCARD_DEBUG_ERR("channel is null.");
594 /* close logical channel */
597 _closeLogicalChannel(terminal, channelNum);
602 channel = service->getChannel(result);
605 if (_isAuthorizedAccess(channel, service->getParent()->getPID(),
606 aid, service->getParent()->getCertificationHashes()) == true)
611 if (aid == PKCS15::PKCS15_AID)
613 PKCS15 pkcs15(channel);
615 if (pkcs15.isClosed() == false)
617 /* remove privilege mode */
618 channel->unsetPrivilegeMode();
622 SCARD_DEBUG_ERR("select failed");
624 service->closeChannel(result);
625 result = IntegerHandle::INVALID_HANDLE;
630 FileObject file(channel);
632 rv = file.select(aid);
633 if (rv == FileObject::SUCCESS)
635 /* remove privilege mode */
636 channel->unsetPrivilegeMode();
640 SCARD_DEBUG_ERR("select failed [%d]", rv);
642 service->closeChannel(result);
643 result = IntegerHandle::INVALID_HANDLE;
649 SCARD_DEBUG_ERR("unauthorized access");
651 service->closeChannel(result);
652 result = IntegerHandle::INVALID_HANDLE;
659 unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
661 unsigned int result = -1;
662 ServiceInstance *service = NULL;
664 if ((service = getService(socket, context)) != NULL)
666 if (service->isVaildSessionHandle(sessionID) == true)
668 ServerSession *session = NULL;
669 Terminal *terminal = NULL;
671 terminal = service->getTerminal(sessionID);
672 session = service->getSession(sessionID);
673 if (terminal != NULL && session != NULL)
675 result = _createChannel(terminal, service, channelType, sessionID, aid);
676 if (result == IntegerHandle::INVALID_HANDLE)
678 SCARD_DEBUG_ERR("create channel failed [%d]", sessionID);
683 SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
688 SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
693 SCARD_DEBUG_ERR("getService is failed [%d] [%d]", socket, context);
699 Channel *ServerResource::getChannel(int socket, unsigned int context, unsigned int channelID)
701 Channel *result = NULL;
702 ServiceInstance *instance = NULL;
704 if ((instance = getService(socket, context)) != NULL)
706 result = instance->getChannel(channelID);
710 SCARD_DEBUG_ERR("Channel doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, channelID);
716 void ServerResource::removeChannel(int socket, unsigned int context, unsigned int channelID)
718 ServiceInstance *instance = NULL;
720 if ((instance = getService(socket, context)) != NULL)
722 instance->closeChannel(channelID);
726 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
730 AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
732 AccessControlList *result = NULL;
733 map<Terminal *, AccessControlList *>::iterator item;
735 if ((item = mapACL.find(terminal)) == mapACL.end())
737 /* load access control */
738 result = new GPSEACL();
741 mapACL.insert(make_pair(terminal, result));
745 SCARD_DEBUG_ERR("alloc failed");
750 result = item->second;
756 AccessControlList *ServerResource::getAccessControlList(ServerChannel *channel)
758 AccessControlList *result = NULL;
759 map<Terminal *, AccessControlList *>::iterator item;
761 if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
763 /* load access control */
764 result = new GPSEACL();
767 mapACL.insert(make_pair(channel->getTerminal(), result));
771 SCARD_DEBUG_ERR("alloc failed");
776 result = item->second;
782 Terminal *ServerResource::createInstance(void *library)
784 Terminal *terminal = NULL;
785 terminal_create_instance_fn createInstance = NULL;
787 /* create se instance */
788 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
789 if (createInstance != NULL)
791 terminal = (Terminal *)createInstance();
792 if (terminal != NULL)
794 SCARD_DEBUG("terminal [%p]", terminal);
798 SCARD_DEBUG_ERR("terminal is null");
803 SCARD_DEBUG_ERR("create_instance is null [%d]", errno);
809 bool ServerResource::appendSELibrary(char *library)
811 void *libHandle = NULL;
814 libHandle = dlopen(library, RTLD_LAZY);
815 if (libHandle != NULL)
817 Terminal *terminal = NULL;
819 terminal = createInstance(libHandle);
820 if (terminal != NULL)
822 unsigned int handle = IntegerHandle::assignHandle();
824 mapTerminals.insert(make_pair(handle, terminal));
825 libraries.push_back(libHandle);
827 terminal->setStatusCallback(&ServerResource::terminalCallback);
829 SCARD_DEBUG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
831 if (terminal->isSecureElementPresence() == true)
833 createReader(handle);
840 SCARD_DEBUG_ERR("terminal is null [%s]", library);
847 SCARD_DEBUG_ERR("it is not se file [%s] [%d]", library, errno);
853 int ServerResource::loadSecureElements()
857 if (seLoaded == false)
860 struct dirent *entry;
862 if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
864 while ((entry = readdir(dir)) != NULL)
866 if (strncmp(entry->d_name, ".", 1) != 0 &&
867 strncmp(entry->d_name, "..", 2) != 0)
871 /* TODO : need additional name rule :) */
873 /* append each files */
874 snprintf(fullPath, sizeof(fullPath),
875 "%s/%s", OMAPI_SE_PATH, entry->d_name);
877 SCARD_DEBUG("se name [%s]", fullPath);
879 result = appendSELibrary(fullPath);
896 void ServerResource::unloadSecureElements()
899 map<unsigned int, Terminal *>::iterator item;
901 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
903 item->second->finalize();
905 IntegerHandle::releaseHandle(item->first);
908 mapTerminals.clear();
910 for (i = 0; i < libraries.size(); i++)
912 if (libraries[i] != NULL)
913 dlclose(libraries[i]);
921 bool ServerResource::isValidReaderHandle(unsigned int reader)
923 return (getTerminalByReaderID(reader) != NULL);
926 bool ServerResource::isValidSessionHandle(int socket, unsigned int context, unsigned int session)
928 ServiceInstance *instance = NULL;
930 return (((instance = getService(socket, context)) != NULL) && (instance->isVaildSessionHandle(session)));
933 int ServerResource::getReadersInformation(ByteArray &info)
936 unsigned char *buffer = NULL;
937 unsigned int length = 0;
938 unsigned int offset = 0;
939 unsigned int nameLen = 0;
941 if (mapReaders.size() > 0)
943 Terminal *terminal = NULL;
944 map<unsigned int, unsigned int>::iterator item;
946 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
948 if (item->second != IntegerHandle::INVALID_HANDLE)
950 terminal = getTerminal(item->second);
951 if (terminal != NULL)
953 if (terminal->isSecureElementPresence())
955 length += sizeof(nameLen) + strlen(terminal->getName()) + sizeof(unsigned int);
962 buffer = new unsigned char[length];
965 memset(buffer, 0, length);
967 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
969 if (item->second != IntegerHandle::INVALID_HANDLE)
971 terminal = getTerminal(item->second);
972 if (terminal != NULL)
974 if (terminal->isSecureElementPresence())
976 nameLen = strlen(terminal->getName());
978 memcpy(buffer + offset, &nameLen, sizeof(nameLen));
979 offset += sizeof(nameLen);
981 memcpy(buffer + offset, terminal->getName(), nameLen);
984 memcpy(buffer + offset, &item->first, sizeof(unsigned int));
985 offset += sizeof(unsigned int);
991 info.setBuffer(buffer, length);
996 SCARD_DEBUG_ERR("alloc failed");
1002 SCARD_DEBUG("no secure element");
1008 bool ServerResource::sendMessageToAllClients(Message &msg)
1011 map<int, ClientInstance *>::iterator item;
1013 for (item = mapClients.begin(); item != mapClients.end(); item++)
1015 if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
1022 void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
1024 SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1028 case Terminal::NOTIFY_SE_AVAILABLE :
1030 ServerResource &instance = ServerResource::getInstance();
1031 unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
1034 SCARD_DEBUG("[NOTIFY_SE_AVAILABLE]");
1036 terminalID = instance.getTerminalID((char *)terminal);
1037 if (terminalID != IntegerHandle::INVALID_HANDLE)
1039 /* send all client to refresh reader */
1040 msg.message = msg.MSG_NOTIFY_SE_INSERTED;
1041 msg.param1 = instance.createReader(terminalID);
1042 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
1044 instance.sendMessageToAllClients(msg);
1049 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
1051 ServerResource &instance = ServerResource::getInstance();
1052 unsigned int readerID = IntegerHandle::INVALID_HANDLE;
1055 SCARD_DEBUG("[NOTIFY_SE_NOT_AVAILABLE]");
1057 readerID = instance.getReaderID((char *)terminal);
1059 /* send all client to refresh reader */
1060 msg.message = msg.MSG_NOTIFY_SE_REMOVED;
1061 msg.param1 = readerID;
1062 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
1064 instance.sendMessageToAllClients(msg);
1065 instance.removeReader(readerID);
1070 SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1075 unsigned int ServerResource::createReader(unsigned int terminalID)
1077 unsigned int result = -1;
1079 result = IntegerHandle::assignHandle();
1081 mapReaders.insert(make_pair(result, terminalID));
1086 unsigned int ServerResource::getReaderID(const char *name)
1088 unsigned int result = IntegerHandle::INVALID_HANDLE, terminalID = IntegerHandle::INVALID_HANDLE;
1090 terminalID = getTerminalID(name);
1091 if (terminalID != IntegerHandle::INVALID_HANDLE)
1093 map<unsigned int, unsigned int>::iterator item;
1095 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
1097 if (item->second == terminalID)
1099 result = item->first;
1108 void ServerResource::removeReader(unsigned int readerID)
1110 map<unsigned int, unsigned int>::iterator item;
1112 if ((item = mapReaders.find(readerID)) != mapReaders.end())
1114 item->second = IntegerHandle::INVALID_HANDLE;
1118 } /* namespace smartcard_service_api */
1120 using namespace smartcard_service_api;
1122 EXTERN_API void server_resource_set_main_loop_instance(void *instance)
1124 ServerResource::getInstance().setMainLoopInstance(instance);