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.
18 /* standard library header */
25 /* SLP library header */
29 #include "ServerResource.h"
30 #include "TerminalInterface.h"
31 #include "APDUHelper.h"
32 #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 SCARD_DEBUG("assign handle : newHandle [%d]", newHandle);
70 void IntegerHandle::releaseHandle(unsigned int handle)
72 SCARD_DEBUG("will be released : Handle [%d]", handle);
76 setHandles.erase(handle);
80 #define OMAPI_SE_PATH "/usr/lib/se"
82 ServerResource::ServerResource() : mainLoop(NULL)
86 serverIPC = ServerIPC::getInstance();
87 serverDispatcher = ServerDispatcher::getInstance();
95 ServerResource::~ServerResource()
99 ServerResource &ServerResource::getInstance()
101 static ServerResource serverResource;
103 return serverResource;
106 bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
110 if (getClient(socket) == NULL)
112 ClientInstance *instance = new ClientInstance(ioChannel, socket, watchID, state, pid);
113 if (instance != NULL)
115 mapClients.insert(make_pair(socket, instance));
120 SCARD_DEBUG_ERR("alloc failed");
125 SCARD_DEBUG_ERR("client already exist [%d]", socket);
131 ClientInstance *ServerResource::getClient(int socket)
133 ClientInstance *result = NULL;
134 map<int, ClientInstance *>::iterator item;
136 if ((item = mapClients.find(socket)) != mapClients.end())
138 result = item->second;
144 void ServerResource::setPID(int socket, int pid)
146 map<int, ClientInstance *>::iterator item;
148 if ((item = mapClients.find(socket)) != mapClients.end())
150 if (item->second->getPID() < 0)
151 item->second->setPID(pid);
155 int ServerResource::getClientCount()
157 return (int)mapClients.size();
160 void ServerResource::removeClient(int socket)
162 map<int, ClientInstance *>::iterator item;
164 if ((item = mapClients.find(socket)) != mapClients.end())
166 ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
169 mapClients.erase(item);
173 SCARD_DEBUG("client removed already [%d]", socket);
177 void ServerResource::removeClients()
179 map<int, ClientInstance *>::iterator item;
181 for (item = mapClients.begin(); item != mapClients.end(); item++)
183 ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
191 bool ServerResource::createService(int socket, unsigned int context)
194 ClientInstance *instance = NULL;
196 if ((instance = getClient(socket)) != NULL)
198 if ((result = instance->createService(context)) == false)
200 SCARD_DEBUG_ERR("ClientInstance::createService failed [%d] [%d]", socket, context);
205 SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
211 ServiceInstance *ServerResource::getService(int socket, unsigned int context)
213 ServiceInstance *result = NULL;
214 ClientInstance *instance = NULL;
216 if ((instance = getClient(socket)) != NULL)
218 result = instance->getService(context);
222 SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
228 void ServerResource::removeService(int socket, unsigned int context)
230 ClientInstance *instance = NULL;
232 if ((instance = getClient(socket)) != NULL)
234 instance->removeService(context);
238 SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
242 void ServerResource::removeServices(int socket)
244 ClientInstance *instance = NULL;
246 if ((instance = getClient(socket)) != NULL)
248 instance->removeServices();
252 SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
256 Terminal *ServerResource::getTerminal(unsigned int terminalID)
258 Terminal *result = NULL;
259 map<unsigned int, Terminal *>::iterator item;
261 if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
263 result = item->second;
267 SCARD_DEBUG_ERR("Terminal doesn't exist [%d]", terminalID);
273 Terminal *ServerResource::getTerminal(const char *name)
275 Terminal *result = NULL;
276 map<unsigned int, Terminal *>::iterator item;
278 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
280 if (strncmp(name, item->second->getName(), strlen(name)) == 0)
282 result = item->second;
290 Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID)
292 Terminal *result = NULL;
293 map<unsigned int, unsigned int>::iterator item;
295 if ((item = mapReaders.find(readerID)) != mapReaders.end())
297 result = getTerminal(item->second);
301 SCARD_DEBUG_ERR("Terminal doesn't exist, reader ID [%d]", readerID);
307 unsigned int ServerResource::getTerminalID(const char *name)
309 unsigned int result = IntegerHandle::INVALID_HANDLE;
310 map<unsigned int, Terminal *>::iterator item;
312 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
314 if (strncmp(name, item->second->getName(), strlen(name)) == 0)
316 result = item->first;
324 unsigned int ServerResource::createSession(int socket, unsigned int context, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
326 unsigned int result = -1;
327 Terminal *temp = NULL;
328 ServiceInstance *instance = NULL;
330 if ((instance = getService(socket, context)) != NULL)
332 if ((temp = getTerminalByReaderID(readerID)) != NULL)
334 result = instance->openSession(temp, certHashes, caller);
339 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
345 ServerSession *ServerResource::getSession(int socket, unsigned int context, unsigned int sessionID)
347 ServerSession *result = NULL;
348 ServiceInstance *instance = NULL;
350 if ((instance = getService(socket, context)) != NULL)
352 result = instance->getSession(sessionID);
356 SCARD_DEBUG_ERR("Session doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, sessionID);
362 unsigned int ServerResource::getChannelCount(int socket, unsigned int context, unsigned int sessionID)
364 unsigned int result = -1;
365 ServiceInstance *instance = NULL;
367 if ((instance = getService(socket, context)) != NULL)
369 result = instance->getChannelCountBySession(sessionID);
373 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
379 void ServerResource::removeSession(int socket, unsigned int context, unsigned int sessionID)
381 ServiceInstance *instance = NULL;
383 if ((instance = getService(socket, context)) != NULL)
385 instance->closeSession(sessionID);
389 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
393 bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes)
397 #if 1 /* disable for temporary */
398 char filename[1024] = { 0, };
399 AccessControlList *acList = NULL;
401 /* check exceptional case */
402 SignatureHelper::getProcessName(pid, filename, sizeof(filename));
403 if (strncmp(filename, "ozD3Dw1MZruTDKHWGgYaDib2B2LV4/nfT+8b/g1Vsk8=", sizeof(filename)) != 0)
405 /* request open channel sequence */
406 if ((acList = getAccessControlList(channel)) != NULL)
409 PKCS15 pkcs15(channel);
411 acList->loadACL(channel);
412 result = acList->isAuthorizedAccess(aid, hashes);
414 result = acList->isAuthorizedAccess(aid, session->packageCert);
419 SCARD_DEBUG_ERR("acList is null");
429 unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
431 unsigned int result = IntegerHandle::INVALID_HANDLE;
437 if (channelType == 1)
440 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
441 rv = terminal->transmitSync(command, response);
443 if (rv == 0 && response.getLength() >= 2)
445 ResponseHelper resp(response);
447 if (resp.getStatus() == 0)
449 channelNum = resp.getDataField()[0];
451 SCARD_DEBUG("channelNum [%d]", channelNum);
455 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
462 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
470 apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_DF_NAME, APDUCommand::P2_SELECT_GET_FCP, aid, 0);
471 apdu.setChannel(1, channelNum);
472 apdu.getBuffer(command);
474 rv = terminal->transmitSync(command, response);
475 if (rv == 0 && response.getLength() >= 2)
477 ResponseHelper resp(response);
479 if (resp.getStatus() == 0)
481 result = service->openChannel(sessionID, channelNum, response);
482 if (result == IntegerHandle::INVALID_HANDLE)
484 SCARD_DEBUG_ERR("channel is null.");
489 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
494 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
500 int ServerResource::_openLogicalChannel(Terminal *terminal)
508 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
509 rv = terminal->transmitSync(command, response);
510 if (rv == 0 && response.getLength() >= 2)
512 ResponseHelper resp(response);
514 if (resp.getStatus() == 0)
516 result = resp.getDataField()[0];
520 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
523 /* TODO : if there is no more channel, return error code */
524 SCARD_DEBUG_ERR("no more logical channel");
531 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
537 int ServerResource::_closeLogicalChannel(Terminal *terminal, int channelNum)
545 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
546 rv = terminal->transmitSync(command, response);
547 if (rv == 0 && response.getLength() >= 2)
549 ResponseHelper resp(response);
551 if (resp.getStatus() == 0)
553 SCARD_DEBUG("channel closed [%d]", channelNum);
558 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
563 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
569 unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
571 unsigned int result = IntegerHandle::INVALID_HANDLE;
573 ServerChannel *channel = NULL;
575 /* open logical channel */
576 if (channelType == 1)
578 channelNum = _openLogicalChannel(terminal);
581 SCARD_DEBUG("channelNum [%d]", result);
585 SCARD_DEBUG_ERR("_openLogicalChannel failed [%d]", channelNum);
590 /* create channel instance */
591 result = service->openChannel(sessionID, channelNum, ByteArray::EMPTY);
592 if (result == IntegerHandle::INVALID_HANDLE)
594 SCARD_DEBUG_ERR("channel is null.");
596 /* close logical channel */
599 _closeLogicalChannel(terminal, channelNum);
604 channel = service->getChannel(result);
607 if (_isAuthorizedAccess(channel, service->getParent()->getPID(),
608 aid, service->getParent()->getCertificationHashes()) == true)
615 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelNum, aid);
616 rv = channel->transmitSync(command, response);
617 if (rv == 0 && response.getLength() >= 2)
619 ResponseHelper resp(response);
621 if (resp.getStatus() == 0)
623 channel->selectResponse = response;
624 /* remove privilege mode */
625 channel->unsetPrivilegeMode();
629 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
634 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
639 SCARD_DEBUG_ERR("unauthorized access");
641 service->closeChannel(result);
642 result = IntegerHandle::INVALID_HANDLE;
650 unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
652 unsigned int result = -1;
653 ServiceInstance *service = NULL;
655 if ((service = getService(socket, context)) != NULL)
657 if (service->isVaildSessionHandle(sessionID) == true)
659 ServerSession *session = NULL;
660 Terminal *terminal = NULL;
662 terminal = service->getTerminal(sessionID);
663 session = service->getSession(sessionID);
664 if (terminal != NULL && session != NULL)
666 result = _createChannel(terminal, service, channelType, sessionID, aid);
667 if (result == IntegerHandle::INVALID_HANDLE)
669 SCARD_DEBUG_ERR("create channel failed [%d]", sessionID);
674 SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
679 SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
684 SCARD_DEBUG_ERR("getService is failed [%d] [%d]", socket, context);
690 Channel *ServerResource::getChannel(int socket, unsigned int context, unsigned int channelID)
692 Channel *result = NULL;
693 ServiceInstance *instance = NULL;
695 if ((instance = getService(socket, context)) != NULL)
697 result = instance->getChannel(channelID);
701 SCARD_DEBUG_ERR("Channel doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, channelID);
707 void ServerResource::removeChannel(int socket, unsigned int context, unsigned int channelID)
709 ServiceInstance *instance = NULL;
711 if ((instance = getService(socket, context)) != NULL)
713 instance->closeChannel(channelID);
717 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
721 AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
723 AccessControlList *result = NULL;
724 map<Terminal *, AccessControlList *>::iterator item;
726 if ((item = mapACL.find(terminal)) == mapACL.end())
728 /* load access control */
729 result = new GPSEACL();
732 mapACL.insert(make_pair(terminal, result));
736 SCARD_DEBUG_ERR("alloc failed");
741 result = item->second;
747 AccessControlList *ServerResource::getAccessControlList(ServerChannel *channel)
749 AccessControlList *result = NULL;
750 map<Terminal *, AccessControlList *>::iterator item;
752 if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
754 /* load access control */
755 result = new GPSEACL();
758 mapACL.insert(make_pair(channel->getTerminal(), result));
762 SCARD_DEBUG_ERR("alloc failed");
767 result = item->second;
773 Terminal *ServerResource::createInstance(void *library)
775 Terminal *terminal = NULL;
776 terminal_create_instance_fn createInstance = NULL;
778 /* create se instance */
779 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
780 if (createInstance != NULL)
782 terminal = (Terminal *)createInstance();
783 if (terminal != NULL)
785 SCARD_DEBUG("terminal [%p]", terminal);
789 SCARD_DEBUG_ERR("terminal is null");
794 SCARD_DEBUG_ERR("create_instance is null [%d]", errno);
800 bool ServerResource::appendSELibrary(char *library)
802 void *libHandle = NULL;
805 libHandle = dlopen(library, RTLD_LAZY);
806 if (libHandle != NULL)
808 Terminal *terminal = NULL;
810 terminal = createInstance(libHandle);
811 if (terminal != NULL)
813 unsigned int handle = IntegerHandle::assignHandle();
815 mapTerminals.insert(make_pair(handle, terminal));
816 libraries.push_back(libHandle);
818 terminal->setStatusCallback(&ServerResource::terminalCallback);
820 SCARD_DEBUG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
822 if (terminal->isSecureElementPresence() == true)
824 createReader(handle);
831 SCARD_DEBUG_ERR("terminal is null [%s]", library);
838 SCARD_DEBUG_ERR("it is not se file [%s] [%d]", library, errno);
844 int ServerResource::loadSecureElements()
849 struct dirent *entry = NULL;
851 if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
853 while ((entry = readdir(dir)) != NULL)
855 if (strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0)
857 char fullPath[1024] = { 0, };
859 /* TODO : need additional name rule :) */
861 /* open each files */
864 snprintf(fullPath, sizeof(fullPath), "%s/%s", OMAPI_SE_PATH, entry->d_name);
866 SCARD_DEBUG("se name [%s]", fullPath);
868 result = appendSELibrary(fullPath);
884 void ServerResource::unloadSecureElements()
887 map<unsigned int, Terminal *>::iterator item;
889 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
891 item->second->finalize();
893 IntegerHandle::releaseHandle(item->first);
896 mapTerminals.clear();
898 for (i = 0; i < libraries.size(); i++)
900 if (libraries[i] != NULL)
901 dlclose(libraries[i]);
907 bool ServerResource::isValidReaderHandle(unsigned int reader)
909 return (getTerminalByReaderID(reader) != NULL);
912 bool ServerResource::isValidSessionHandle(int socket, unsigned int context, unsigned int session)
914 ServiceInstance *instance = NULL;
916 return (((instance = getService(socket, context)) != NULL) && (instance->isVaildSessionHandle(session)));
919 int ServerResource::getReadersInformation(ByteArray &info)
922 unsigned char *buffer = NULL;
923 unsigned int length = 0;
924 unsigned int offset = 0;
925 unsigned int nameLen = 0;
927 if (mapReaders.size() > 0)
929 Terminal *terminal = NULL;
930 map<unsigned int, unsigned int>::iterator item;
932 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
934 if (item->second != IntegerHandle::INVALID_HANDLE)
936 terminal = getTerminal(item->second);
937 if (terminal != NULL)
939 if (terminal->isSecureElementPresence())
941 length += sizeof(nameLen) + strlen(terminal->getName()) + sizeof(unsigned int);
948 buffer = new unsigned char[length];
951 memset(buffer, 0, length);
953 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
955 if (item->second != IntegerHandle::INVALID_HANDLE)
957 terminal = getTerminal(item->second);
958 if (terminal != NULL)
960 if (terminal->isSecureElementPresence())
962 nameLen = strlen(terminal->getName());
964 memcpy(buffer + offset, &nameLen, sizeof(nameLen));
965 offset += sizeof(nameLen);
967 memcpy(buffer + offset, terminal->getName(), nameLen);
970 memcpy(buffer + offset, &item->first, sizeof(unsigned int));
971 offset += sizeof(unsigned int);
977 info.setBuffer(buffer, length);
982 SCARD_DEBUG_ERR("alloc failed");
988 SCARD_DEBUG("no secure element");
994 bool ServerResource::sendMessageToAllClients(Message &msg)
997 map<int, ClientInstance *>::iterator item;
999 for (item = mapClients.begin(); item != mapClients.end(); item++)
1001 if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
1008 void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
1010 SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1014 case Terminal::NOTIFY_SE_AVAILABLE :
1016 ServerResource &instance = ServerResource::getInstance();
1017 unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
1020 SCARD_DEBUG("[NOTIFY_SE_AVAILABLE]");
1022 terminalID = instance.getTerminalID((char *)terminal);
1023 if (terminalID != IntegerHandle::INVALID_HANDLE)
1025 /* send all client to refresh reader */
1026 msg.message = msg.MSG_NOTIFY_SE_INSERTED;
1027 msg.param1 = instance.createReader(terminalID);
1028 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
1030 instance.sendMessageToAllClients(msg);
1035 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
1037 ServerResource &instance = ServerResource::getInstance();
1038 unsigned int readerID = IntegerHandle::INVALID_HANDLE;
1041 SCARD_DEBUG("[NOTIFY_SE_NOT_AVAILABLE]");
1043 readerID = instance.getReaderID((char *)terminal);
1045 /* send all client to refresh reader */
1046 msg.message = msg.MSG_NOTIFY_SE_REMOVED;
1047 msg.param1 = readerID;
1048 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
1050 instance.sendMessageToAllClients(msg);
1051 instance.removeReader(readerID);
1056 SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1061 unsigned int ServerResource::createReader(unsigned int terminalID)
1063 unsigned int result = -1;
1065 result = IntegerHandle::assignHandle();
1067 mapReaders.insert(make_pair(result, terminalID));
1072 unsigned int ServerResource::getReaderID(const char *name)
1074 unsigned int result = IntegerHandle::INVALID_HANDLE, terminalID = IntegerHandle::INVALID_HANDLE;
1076 terminalID = getTerminalID(name);
1077 if (terminalID != IntegerHandle::INVALID_HANDLE)
1079 map<unsigned int, unsigned int>::iterator item;
1081 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
1083 if (item->second == terminalID)
1085 result = item->first;
1094 void ServerResource::removeReader(unsigned int readerID)
1096 map<unsigned int, unsigned int>::iterator item;
1098 if ((item = mapReaders.find(readerID)) != mapReaders.end())
1100 item->second = IntegerHandle::INVALID_HANDLE;
1104 } /* namespace smartcard_service_api */
1106 using namespace smartcard_service_api;
1108 EXTERN_API void server_resource_set_main_loop_instance(void *instance)
1110 ServerResource::getInstance().setMainLoopInstance(instance);