--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+MESSAGE("build smartcard-service")
+
+SET(CMAKE_VERBOSE_MAKEFILE OFF)
+
+ADD_SUBDIRECTORY(common)
+ADD_SUBDIRECTORY(server)
+ADD_SUBDIRECTORY(client)
+ADD_SUBDIRECTORY(test-client)
+
--- /dev/null
+Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+ Apache License\r
+ Version 2.0, January 2004\r
+ http://www.apache.org/licenses/\r
+\r
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+ 1. Definitions.\r
+\r
+ "License" shall mean the terms and conditions for use, reproduction,\r
+ and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+ "Licensor" shall mean the copyright owner or entity authorized by\r
+ the copyright owner that is granting the License.\r
+\r
+ "Legal Entity" shall mean the union of the acting entity and all\r
+ other entities that control, are controlled by, or are under common\r
+ control with that entity. For the purposes of this definition,\r
+ "control" means (i) the power, direct or indirect, to cause the\r
+ direction or management of such entity, whether by contract or\r
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+ outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+ "You" (or "Your") shall mean an individual or Legal Entity\r
+ exercising permissions granted by this License.\r
+\r
+ "Source" form shall mean the preferred form for making modifications,\r
+ including but not limited to software source code, documentation\r
+ source, and configuration files.\r
+\r
+ "Object" form shall mean any form resulting from mechanical\r
+ transformation or translation of a Source form, including but\r
+ not limited to compiled object code, generated documentation,\r
+ and conversions to other media types.\r
+\r
+ "Work" shall mean the work of authorship, whether in Source or\r
+ Object form, made available under the License, as indicated by a\r
+ copyright notice that is included in or attached to the work\r
+ (an example is provided in the Appendix below).\r
+\r
+ "Derivative Works" shall mean any work, whether in Source or Object\r
+ form, that is based on (or derived from) the Work and for which the\r
+ editorial revisions, annotations, elaborations, or other modifications\r
+ represent, as a whole, an original work of authorship. For the purposes\r
+ of this License, Derivative Works shall not include works that remain\r
+ separable from, or merely link (or bind by name) to the interfaces of,\r
+ the Work and Derivative Works thereof.\r
+\r
+ "Contribution" shall mean any work of authorship, including\r
+ the original version of the Work and any modifications or additions\r
+ to that Work or Derivative Works thereof, that is intentionally\r
+ submitted to Licensor for inclusion in the Work by the copyright owner\r
+ or by an individual or Legal Entity authorized to submit on behalf of\r
+ the copyright owner. For the purposes of this definition, "submitted"\r
+ means any form of electronic, verbal, or written communication sent\r
+ to the Licensor or its representatives, including but not limited to\r
+ communication on electronic mailing lists, source code control systems,\r
+ and issue tracking systems that are managed by, or on behalf of, the\r
+ Licensor for the purpose of discussing and improving the Work, but\r
+ excluding communication that is conspicuously marked or otherwise\r
+ designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+ "Contributor" shall mean Licensor and any individual or Legal Entity\r
+ on behalf of whom a Contribution has been received by Licensor and\r
+ subsequently incorporated within the Work.\r
+\r
+ 2. Grant of Copyright License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ copyright license to reproduce, prepare Derivative Works of,\r
+ publicly display, publicly perform, sublicense, and distribute the\r
+ Work and such Derivative Works in Source or Object form.\r
+\r
+ 3. Grant of Patent License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ (except as stated in this section) patent license to make, have made,\r
+ use, offer to sell, sell, import, and otherwise transfer the Work,\r
+ where such license applies only to those patent claims licensable\r
+ by such Contributor that are necessarily infringed by their\r
+ Contribution(s) alone or by combination of their Contribution(s)\r
+ with the Work to which such Contribution(s) was submitted. If You\r
+ institute patent litigation against any entity (including a\r
+ cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+ or a Contribution incorporated within the Work constitutes direct\r
+ or contributory patent infringement, then any patent licenses\r
+ granted to You under this License for that Work shall terminate\r
+ as of the date such litigation is filed.\r
+\r
+ 4. Redistribution. You may reproduce and distribute copies of the\r
+ Work or Derivative Works thereof in any medium, with or without\r
+ modifications, and in Source or Object form, provided that You\r
+ meet the following conditions:\r
+\r
+ (a) You must give any other recipients of the Work or\r
+ Derivative Works a copy of this License; and\r
+\r
+ (b) You must cause any modified files to carry prominent notices\r
+ stating that You changed the files; and\r
+\r
+ (c) You must retain, in the Source form of any Derivative Works\r
+ that You distribute, all copyright, patent, trademark, and\r
+ attribution notices from the Source form of the Work,\r
+ excluding those notices that do not pertain to any part of\r
+ the Derivative Works; and\r
+\r
+ (d) If the Work includes a "NOTICE" text file as part of its\r
+ distribution, then any Derivative Works that You distribute must\r
+ include a readable copy of the attribution notices contained\r
+ within such NOTICE file, excluding those notices that do not\r
+ pertain to any part of the Derivative Works, in at least one\r
+ of the following places: within a NOTICE text file distributed\r
+ as part of the Derivative Works; within the Source form or\r
+ documentation, if provided along with the Derivative Works; or,\r
+ within a display generated by the Derivative Works, if and\r
+ wherever such third-party notices normally appear. The contents\r
+ of the NOTICE file are for informational purposes only and\r
+ do not modify the License. You may add Your own attribution\r
+ notices within Derivative Works that You distribute, alongside\r
+ or as an addendum to the NOTICE text from the Work, provided\r
+ that such additional attribution notices cannot be construed\r
+ as modifying the License.\r
+\r
+ You may add Your own copyright statement to Your modifications and\r
+ may provide additional or different license terms and conditions\r
+ for use, reproduction, or distribution of Your modifications, or\r
+ for any such Derivative Works as a whole, provided Your use,\r
+ reproduction, and distribution of the Work otherwise complies with\r
+ the conditions stated in this License.\r
+\r
+ 5. Submission of Contributions. Unless You explicitly state otherwise,\r
+ any Contribution intentionally submitted for inclusion in the Work\r
+ by You to the Licensor shall be under the terms and conditions of\r
+ this License, without any additional terms or conditions.\r
+ Notwithstanding the above, nothing herein shall supersede or modify\r
+ the terms of any separate license agreement you may have executed\r
+ with Licensor regarding such Contributions.\r
+\r
+ 6. Trademarks. This License does not grant permission to use the trade\r
+ names, trademarks, service marks, or product names of the Licensor,\r
+ except as required for reasonable and customary use in describing the\r
+ origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+ 7. Disclaimer of Warranty. Unless required by applicable law or\r
+ agreed to in writing, Licensor provides the Work (and each\r
+ Contributor provides its Contributions) on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+ implied, including, without limitation, any warranties or conditions\r
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+ PARTICULAR PURPOSE. You are solely responsible for determining the\r
+ appropriateness of using or redistributing the Work and assume any\r
+ risks associated with Your exercise of permissions under this License.\r
+\r
+ 8. Limitation of Liability. In no event and under no legal theory,\r
+ whether in tort (including negligence), contract, or otherwise,\r
+ unless required by applicable law (such as deliberate and grossly\r
+ negligent acts) or agreed to in writing, shall any Contributor be\r
+ liable to You for damages, including any direct, indirect, special,\r
+ incidental, or consequential damages of any character arising as a\r
+ result of this License or out of the use or inability to use the\r
+ Work (including but not limited to damages for loss of goodwill,\r
+ work stoppage, computer failure or malfunction, or any and all\r
+ other commercial damages or losses), even if such Contributor\r
+ has been advised of the possibility of such damages.\r
+\r
+ 9. Accepting Warranty or Additional Liability. While redistributing\r
+ the Work or Derivative Works thereof, You may choose to offer,\r
+ and charge a fee for, acceptance of support, warranty, indemnity,\r
+ or other liability obligations and/or rights consistent with this\r
+ License. However, in accepting such obligations, You may act only\r
+ on Your own behalf and on Your sole responsibility, not on behalf\r
+ of any other Contributor, and only if You agree to indemnify,\r
+ defend, and hold each Contributor harmless for any liability\r
+ incurred by, or claims asserted against, such Contributor by reason\r
+ of your accepting any such warranty or additional liability.\r
+\r
+ END OF TERMS AND CONDITIONS\r
+\r
+ APPENDIX: How to apply the Apache License to your work.\r
+\r
+ To apply the Apache License to your work, attach the following\r
+ boilerplate notice, with the fields enclosed by brackets "[]"\r
+ replaced with your own identifying information. (Don't include\r
+ the brackets!) The text should be enclosed in the appropriate\r
+ comment syntax for the file format. We also recommend that a\r
+ file or class name and description of purpose be included on the\r
+ same "printed page" as the copyright notice for easier\r
+ identification within third-party archives.\r
+\r
+ Copyright [yyyy] [name of copyright owner]\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+\r
+\r
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(smartcard-service CXX)
+
+SET(LIB_NAME "smartcard-service")
+SET(VERSION_MAJOR 1)
+SET(VERSION ${VERSION_MAJOR}.0.0)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SRCS)
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+ SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_client REQUIRED gthread-2.0 dlog)
+
+MESSAGE("${LIB_NAME} ld flag : ${pkgs_client_LDFLAGS}")
+
+FOREACH(flag ${pkgs_client_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${pkgs_client_CFLAGS})
+ SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+
+#SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -finstrument-functions")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+#SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+#SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+#SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -finstrument-functions")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+#SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+#SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+ ADD_DEFINITIONS("-DTARGET")
+ MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+MESSAGE("CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DSLP_DEBUG")
+
+ADD_DEFINITIONS("-DLOG_TAG=\"SCARD_CLIENT\"")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES VERSION ${VERSION})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_client_LDFLAGS})
+
+SET(EXPORT_HEADER
+ ../common/include/smartcard-types.h
+ ../common/include/ByteArray.h
+ ../common/include/Debug.h
+ ../common/include/Synchronous.h
+ ../common/include/APDUHelper.h
+ ../common/include/Channel.h
+ ../common/include/Serializable.h
+ ../common/include/SEServiceHelper.h
+ ../common/include/ReaderHelper.h
+ ../common/include/SessionHelper.h
+# ../common/include/FCI.h
+# ../common/include/
+ include/SEServiceListener.h
+ include/SEService.h
+ include/Reader.h
+ include/Session.h
+ include/ClientChannel.h
+# include/
+)
+
+#CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc DESTINATION lib/pkgconfig)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib)
+FOREACH(hfile ${EXPORT_HEADER})
+ INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
+ENDFOREACH(hfile)
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <unistd.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Message.h"
+#include "ClientIPC.h"
+#include "ClientChannel.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ ClientChannel::ClientChannel(void *context, Session *session, int channelNum, ByteArray selectResponse, void *handle):Channel(session)
+ {
+ this->channelNum = -1;
+ this->handle = NULL;
+ this->context = NULL;
+
+ if (handle == NULL)
+ {
+ SCARD_DEBUG_ERR("ClientIPC::getInstance() failed");
+
+ return;
+ }
+
+ this->channelNum = channelNum;
+ this->handle = handle;
+ this->selectResponse = selectResponse;
+ this->context = context;
+ }
+
+ ClientChannel::~ClientChannel()
+ {
+ close(NULL, this);
+ }
+
+ void ClientChannel::closeSync()
+ {
+ Message msg;
+ int rv;
+
+ if (isClosed() == false)
+ {
+ /* send message to server */
+ msg.message = Message::MSG_REQUEST_CLOSE_CHANNEL;
+ msg.param1 = (int)handle;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ syncLock();
+ rv = waitTimedCondition(0);
+ syncUnlock();
+
+ if (rv < 0)
+ {
+ SCARD_DEBUG_ERR("closeSync failed [%d]", rv);
+ }
+
+ channelNum = -1;
+ }
+ }
+
+ int ClientChannel::close(closeCallback callback, void *userParam)
+ {
+ Message msg;
+
+ if (isClosed() == false)
+ {
+ channelNum = -1;
+
+ /* send message to server */
+ msg.message = Message::MSG_REQUEST_CLOSE_CHANNEL;
+ msg.param1 = (int)handle;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)callback;
+ msg.userParam = userParam;
+
+ ClientIPC::getInstance().sendMessage(&msg);
+ }
+
+ return 0;
+ }
+
+ int ClientChannel::transmitSync(ByteArray command, ByteArray &result)
+ {
+ Message msg;
+ int rv;
+
+ /* send message to server */
+ msg.message = Message::MSG_REQUEST_TRANSMIT;
+ msg.param1 = (int)handle;
+ msg.param2 = 0;
+ msg.data = command;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ syncLock();
+ rv = waitTimedCondition(0);
+ syncUnlock();
+
+ if (rv < 0)
+ {
+ SCARD_DEBUG_ERR("clientIPC is null");
+
+ return -1;
+ }
+
+ result = response;
+
+ return 0;
+ }
+
+ int ClientChannel::transmit(ByteArray command, transmitCallback callback, void *userParam)
+ {
+ Message msg;
+
+ /* send message to server */
+ msg.message = Message::MSG_REQUEST_TRANSMIT;
+ msg.param1 = (int)handle;
+ msg.param2 = 0;
+ msg.data = command;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)callback;
+ msg.userParam = userParam;
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ return 0;
+ }
+
+ bool ClientChannel::dispatcherCallback(void *message)
+ {
+ Message *msg = (Message *)message;
+ ClientChannel *channel = NULL;
+ bool result = false;
+
+ if (msg == NULL)
+ {
+ SCARD_DEBUG_ERR("message is null");
+ return result;
+ }
+
+ channel = (ClientChannel *)msg->caller;
+
+ switch (msg->message)
+ {
+ case Message::MSG_REQUEST_TRANSMIT :
+ {
+ /* transmit result */
+ SCARD_DEBUG("MSG_REQUEST_TRANSMIT");
+
+ if (msg->callback == (void *)channel) /* synchronized call */
+ {
+ /* sync call */
+ channel->syncLock();
+
+ /* copy result */
+ channel->error = msg->error;
+ channel->response = msg->data;
+
+ channel->signalCondition();
+ channel->syncUnlock();
+ }
+ else if (msg->callback != NULL)
+ {
+ transmitCallback cb = (transmitCallback)msg->callback;
+
+ /* async call */
+ cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
+ }
+ }
+ break;
+
+ case Message::MSG_REQUEST_CLOSE_CHANNEL :
+ {
+ SCARD_DEBUG("MSG_REQUEST_CLOSE_CHANNEL");
+
+ if (msg->callback == (void *)channel) /* synchronized call */
+ {
+ /* sync call */
+ channel->syncLock();
+
+ channel->error = msg->error;
+
+ channel->signalCondition();
+ channel->syncUnlock();
+ }
+ else if (msg->callback != NULL)
+ {
+ closeCallback cb = (closeCallback)msg->callback;
+
+ /* async call */
+ cb(msg->error, msg->userParam);
+ }
+ }
+ break;
+
+ default:
+ SCARD_DEBUG("unknwon message : %s", msg->toString());
+ break;
+ }
+
+ delete msg;
+
+ return result;
+ }
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define CHANNEL_EXTERN_BEGIN \
+ if (handle != NULL) \
+ { \
+ ClientChannel *channel = (ClientChannel *)handle;
+
+#define CHANNEL_EXTERN_END \
+ } \
+ else \
+ { \
+ SCARD_DEBUG_ERR("Invalid param"); \
+ }
+
+using namespace smartcard_service_api;
+
+EXTERN_API int channel_close(channel_h handle, channel_close_cb callback, void *userParam)
+{
+ int result = -1;
+
+ CHANNEL_EXTERN_BEGIN;
+ result = channel->close((closeCallback)callback, userParam);
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_transmit(channel_h handle, unsigned char *command, unsigned int length, channel_transmit_cb callback, void *userParam)
+{
+ int result = -1;
+
+ CHANNEL_EXTERN_BEGIN;
+ ByteArray temp;
+
+ temp.setBuffer(command, length);
+ result = channel->transmit(temp, (transmitCallback)callback, userParam);
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API bool channel_is_basic_channel(channel_h handle)
+{
+ bool result = false;
+
+ CHANNEL_EXTERN_BEGIN;
+ result = channel->isBasicChannel();
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API bool channel_is_closed(channel_h handle)
+{
+ bool result = false;
+
+ CHANNEL_EXTERN_BEGIN;
+ result = channel->isClosed();
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API unsigned int channel_get_select_response_length(channel_h handle)
+{
+ unsigned int result = 0;
+
+ CHANNEL_EXTERN_BEGIN;
+ result = channel->getSelectResponse().getLength();
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API bool channel_get_select_response(channel_h handle, unsigned char *buffer, unsigned int length)
+{
+ bool result = false;
+
+ if (buffer == NULL || length == 0)
+ {
+ return result;
+ }
+
+ CHANNEL_EXTERN_BEGIN;
+ ByteArray response;
+
+ response = channel->getSelectResponse();
+ if (response.getLength() > 0)
+ {
+ memcpy(buffer, response.getBuffer(), MIN(length, response.getLength()));
+ result = true;
+ }
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API session_h channel_get_session(channel_h handle)
+{
+ session_h session = NULL;
+
+ CHANNEL_EXTERN_BEGIN;
+ session = channel->getSession();
+ CHANNEL_EXTERN_END;
+
+ return session;
+}
+
+EXTERN_API void channel_destroy_instance(channel_h handle)
+{
+ CHANNEL_EXTERN_BEGIN;
+ delete channel;
+ CHANNEL_EXTERN_END;
+}
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <glib.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ClientDispatcher.h"
+#include "SEService.h"
+#include "Reader.h"
+#include "Session.h"
+#include "ClientChannel.h"
+
+namespace smartcard_service_api
+{
+ ClientDispatcher::ClientDispatcher()
+ {
+ }
+
+ ClientDispatcher::~ClientDispatcher()
+ {
+ mapSESerivces.clear();
+ }
+
+ ClientDispatcher &ClientDispatcher::getInstance()
+ {
+ static ClientDispatcher clientDispatcher;
+
+ return clientDispatcher;
+ }
+
+ bool ClientDispatcher::addSEService(void *context, SEService *service)
+ {
+ bool result = true;
+ map<void *, SEService *>::iterator item;
+
+ SCARD_BEGIN();
+
+ if ((item = mapSESerivces.find(context)) == mapSESerivces.end())
+ {
+ mapSESerivces.insert(make_pair(context, service));
+ }
+ else
+ {
+ SCARD_DEBUG("SEService [%p] exists", context);
+ }
+
+ SCARD_END();
+
+ return result;
+ }
+
+ void ClientDispatcher::removeSEService(void *context)
+ {
+ map<void *, SEService *>::iterator item;
+
+ SCARD_BEGIN();
+
+ if ((item = mapSESerivces.find(context)) != mapSESerivces.end())
+ {
+ mapSESerivces.erase(item);
+ }
+ else
+ {
+ SCARD_DEBUG("SEService doesn't exist");
+ }
+
+ SCARD_END();
+ }
+
+ void *ClientDispatcher::dispatcherThreadFunc(DispatcherMsg *msg, void *data)
+ {
+ SCARD_BEGIN();
+
+ if (msg == NULL)
+ return NULL;
+
+ /* this messages are response from server */
+ switch (msg->message)
+ {
+ /* SE Service requests */
+ case Message::MSG_REQUEST_READERS :
+ {
+ DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+ g_idle_add((GSourceFunc)&SEService::dispatcherCallback, (gpointer)tempMsg);
+ }
+ break;
+
+ /* Reader requests */
+ case Message::MSG_REQUEST_OPEN_SESSION :
+ {
+ DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+ g_idle_add((GSourceFunc)&Reader::dispatcherCallback, (gpointer)tempMsg);
+ }
+ break;
+
+ /* Session requests */
+ case Message::MSG_REQUEST_OPEN_CHANNEL :
+ case Message::MSG_REQUEST_GET_ATR :
+ case Message::MSG_REQUEST_CLOSE_SESSION :
+ case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
+ {
+ DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+ g_idle_add((GSourceFunc)&Session::dispatcherCallback, (gpointer)tempMsg);
+ }
+ break;
+
+ /* ClientChannel requests */
+ case Message::MSG_REQUEST_TRANSMIT :
+ case Message::MSG_REQUEST_CLOSE_CHANNEL :
+ {
+ DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+ g_idle_add((GSourceFunc)&ClientChannel::dispatcherCallback, (gpointer)tempMsg);
+ }
+ break;
+
+ case Message::MSG_NOTIFY_SE_INSERTED :
+ case Message::MSG_NOTIFY_SE_REMOVED :
+ {
+ map<void *, SEService *>::iterator item;
+
+ for (item = mapSESerivces.begin(); item != mapSESerivces.end(); item++)
+ {
+ DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+ tempMsg->caller = item->second;
+
+ g_idle_add((GSourceFunc)&SEService::dispatcherCallback, (gpointer)tempMsg);
+ }
+ }
+ break;
+
+ case Message::MSG_OPERATION_RELEASE_CLIENT :
+ {
+ map<void *, SEService *>::iterator item;
+
+ for (item = mapSESerivces.begin(); item != mapSESerivces.end(); item++)
+ {
+ DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+ tempMsg->caller = item->second;
+ tempMsg->error = -1;
+
+ g_idle_add((GSourceFunc)&SEService::dispatcherCallback, (gpointer)tempMsg);
+ }
+ }
+ break;
+
+ default :
+ break;
+ }
+
+ SCARD_END();
+
+ return NULL;
+ }
+
+} /* namespace open_mobile_api */
+
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <sys/socket.h>
+#include <unistd.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ClientIPC.h"
+#include "DispatcherMsg.h"
+
+namespace smartcard_service_api
+{
+ ClientIPC::ClientIPC():IPCHelper()
+ {
+ }
+
+ ClientIPC::~ClientIPC()
+ {
+ }
+
+ ClientIPC &ClientIPC::getInstance()
+ {
+ static ClientIPC clientIPC;
+
+ return clientIPC;
+ }
+
+ int ClientIPC::handleIOErrorCondition(void *channel, GIOCondition condition)
+ {
+ SCARD_BEGIN();
+
+ /* finalize context */
+ if (watchId != 0)
+ {
+ g_source_remove(watchId);
+ watchId = 0;
+ }
+
+ if (ioChannel != NULL)
+ {
+ g_io_channel_unref(ioChannel);
+ ioChannel = NULL;
+ }
+
+ if (ipcSocket != -1)
+ {
+ shutdown(ipcSocket, SHUT_RDWR);
+ close(ipcSocket);
+
+ ipcSocket = -1;
+ }
+
+ /* push disconnect message */
+ DispatcherMsg *dispMsg = new DispatcherMsg();
+
+ dispMsg->message = Message::MSG_OPERATION_RELEASE_CLIENT;
+ dispMsg->error = -1;
+
+ if (dispatcher != NULL)
+ dispatcher->pushMessage(dispMsg);
+
+ SCARD_END();
+
+ return FALSE;
+ }
+
+ int ClientIPC::handleInvalidSocketCondition(void *channel, GIOCondition condition)
+ {
+ SCARD_BEGIN();
+
+ /* finalize context */
+
+ SCARD_END();
+
+ return FALSE;
+ }
+
+ int ClientIPC::handleIncomingCondition(void *channel, GIOCondition condition)
+ {
+ int result = FALSE;
+
+ SCARD_BEGIN();
+
+ if (channel == ioChannel)
+ {
+ Message *msg = NULL;
+
+ SCARD_DEBUG("message from server to client socket");
+
+ /* read message */
+ msg = retrieveMessage();
+ if (msg != NULL)
+ {
+ DispatcherMsg *dispMsg = new DispatcherMsg(msg);
+
+ /* set peer socket */
+ dispMsg->setPeerSocket(ipcSocket);
+
+ /* push to dispatcher */
+ if (dispatcher != NULL)
+ dispatcher->pushMessage(dispMsg);
+
+ result = TRUE;
+ }
+ else
+ {
+ /* clear client connection */
+ }
+
+ delete msg;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("Unknown channel event [%p]", channel);
+ }
+
+ SCARD_END();
+
+ return result;
+ }
+
+} /* namespace open_mobile_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Message.h"
+#include "ClientIPC.h"
+#include "Reader.h"
+#include "Session.h"
+#include "SignatureHelper.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ Reader::Reader(void *context, char *name, void *handle):ReaderHelper()
+ {
+ unsigned int length = 0;
+
+ SCARD_BEGIN();
+
+ this->context = NULL;
+ this->handle = NULL;
+
+ if (context == NULL || name == NULL || strlen(name) == 0 || handle == NULL)
+ {
+ SCARD_DEBUG_ERR("invalid param");
+
+ return;
+ }
+
+ this->handle = handle;
+ this->context = context;
+
+ length = strlen(name);
+ length = (length < sizeof(this->name)) ? length : sizeof(this->name);
+ memcpy(this->name, name, length);
+
+ getPackageCert();
+
+ SCARD_END();
+ }
+
+ Reader::~Reader()
+ {
+ closeSessions();
+ }
+
+ void Reader::closeSessions()
+ {
+ size_t i;
+
+ for (i = 0; i < sessions.size(); i++)
+ {
+ sessions[i]->close(NULL, this);
+ }
+
+ sessions.clear();
+ }
+
+ void Reader::getPackageCert()
+ {
+ packageCert = SignatureHelper::getCertificationHash(getpid());
+ }
+
+ SessionHelper *Reader::openSessionSync()
+ {
+ Message msg;
+ int rv;
+
+ /* request channel handle from server */
+ msg.message = Message::MSG_REQUEST_OPEN_SESSION;
+ msg.param1 = (unsigned int)handle;
+ msg.data = packageCert;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ syncLock();
+ rv = waitTimedCondition(0);
+ syncUnlock();
+
+ if (rv != 0)
+ {
+ SCARD_DEBUG_ERR("time over");
+
+ return NULL;
+ }
+
+ return (Session *)openedSession;
+ }
+
+ int Reader::openSession(openSessionCallback callback, void *userData)
+ {
+ Message msg;
+
+ /* request channel handle from server */
+ msg.message = Message::MSG_REQUEST_OPEN_SESSION;
+ msg.param1 = (unsigned int)handle;
+ msg.data = packageCert;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)callback;
+ msg.userParam = userData;
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ return 0;
+ }
+
+ bool Reader::dispatcherCallback(void *message)
+ {
+ Message *msg = (Message *)message;
+ Reader *reader = NULL;
+ bool result = false;
+
+ SCARD_BEGIN();
+
+ if (msg == NULL)
+ {
+ SCARD_DEBUG_ERR("message is null");
+ return result;
+ }
+
+ reader = (Reader *)msg->caller;
+
+ switch (msg->message)
+ {
+ case Message::MSG_REQUEST_OPEN_SESSION :
+ {
+ Session *session = NULL;
+
+ SCARD_DEBUG("MSG_REQUEST_OPEN_SESSION");
+
+ if (msg->param1 != 0)
+ {
+ /* create new instance of channel */
+ session = new Session(reader->context, reader, (void *)msg->param1);
+ if (session == NULL)
+ {
+ SCARD_DEBUG_ERR("Session creating instance failed");
+
+ return session;
+ }
+
+ reader->sessions.push_back(session);
+ }
+
+ if (msg->callback == (void *)reader) /* synchronized call */
+ {
+ /* sync call */
+ reader->syncLock();
+
+ /* copy result */
+ reader->error = msg->error;
+ reader->openedSession = session;
+ reader->signalCondition();
+
+ reader->syncUnlock();
+ }
+ else if (msg->callback != NULL)
+ {
+ openSessionCallback cb = (openSessionCallback)msg->callback;
+
+ /* async call */
+ cb(session, msg->error, msg->userParam);
+ }
+ }
+ break;
+
+ default:
+ SCARD_DEBUG("unknown [%s]", msg->toString());
+ break;
+ }
+
+ delete msg;
+
+ SCARD_END();
+
+ return result;
+ }
+
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define READER_EXTERN_BEGIN \
+ if (handle != NULL) \
+ { \
+ Reader *reader = (Reader *)handle;
+
+#define READER_EXTERN_END \
+ } \
+ else \
+ { \
+ SCARD_DEBUG_ERR("Invalid param"); \
+ }
+
+using namespace smartcard_service_api;
+
+EXTERN_API const char *reader_get_name(reader_h handle)
+{
+ const char *name = NULL;
+
+ READER_EXTERN_BEGIN;
+ name = reader->getName();
+ READER_EXTERN_END;
+
+ return name;
+}
+
+EXTERN_API se_service_h reader_get_se_service(reader_h handle)
+{
+ se_service_h service = NULL;
+
+ READER_EXTERN_BEGIN;
+ service = (se_service_h)reader->getSEService();
+ READER_EXTERN_END;
+
+ return service;
+}
+
+EXTERN_API bool reader_is_secure_element_present(reader_h handle)
+{
+ bool result = false;
+
+ READER_EXTERN_BEGIN;
+ result = reader->isSecureElementPresent();
+ READER_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int reader_open_session(reader_h handle, reader_open_session_cb callback, void *userData)
+{
+ int result = -1;
+
+ READER_EXTERN_BEGIN;
+ result = reader->openSession((openSessionCallback)callback, userData);
+ READER_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API void reader_close_sessions(reader_h handle)
+{
+ READER_EXTERN_BEGIN;
+ reader->closeSessions();
+ READER_EXTERN_END;
+}
+
+EXTERN_API void reader_destroy_instance(reader_h handle)
+{
+ READER_EXTERN_BEGIN;
+ delete reader;
+ READER_EXTERN_END;
+}
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <unistd.h>
+#include <string.h>
+#include <glib.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ClientIPC.h"
+#include "ClientDispatcher.h"
+#include "SEService.h"
+#include "Reader.h"
+#include "Message.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ SEService::SEService():SEServiceHelper()
+ {
+ pid = -1;
+ this->context = NULL;
+ this->handler = NULL;
+ this->listener = NULL;
+ connected = false;
+
+ pid = getpid();
+ }
+
+ SEService::SEService(void *user_data, serviceConnected handler):SEServiceHelper()
+ {
+ pid = -1;
+ this->context = NULL;
+ this->handler = NULL;
+ this->listener = NULL;
+ connected = false;
+
+ pid = getpid();
+
+ initialize(user_data, handler);
+ }
+
+ SEService::SEService(void *user_data, SEServiceListener *listener):SEServiceHelper()
+ {
+ pid = -1;
+ this->context = NULL;
+ this->handler = NULL;
+ this->listener = NULL;
+ connected = false;
+
+ pid = getpid();
+
+ initialize(user_data, listener);
+ }
+
+ SEService::~SEService()
+ {
+ }
+
+ void SEService::shutdown()
+ {
+ ClientDispatcher::getInstance().removeSEService(context);
+ }
+
+ bool SEService::_initialize()
+ {
+ bool result = false;
+#ifdef SECURITY_SERVER
+ int cookies_size;
+ char *cookies = NULL;
+#endif
+ ClientIPC *clientIPC = NULL;
+ ClientDispatcher *clientDispatcher = NULL;
+
+ SCARD_BEGIN();
+
+ /* initialize client */
+ if (!g_thread_supported())
+ {
+ g_thread_init(NULL);
+ }
+
+#ifdef SECURITY_SERVER
+ if ((cookies_size = security_server_get_cookie_size()) != 0)
+ {
+ _net_nfc_client_util_alloc_mem(cookies, cookies_size);
+ int error = 0;
+ if ((error = security_server_request_cookie(cookies, cookies_size)) != SECURITY_SERVER_API_SUCCESS)
+ {
+ DEBUG_CLIENT_MSG("security server request cookies error = [%d]", error);
+ _net_nfc_client_util_free_mem(cookies);
+ }
+ else
+ {
+ char printf_buff[BUFFER_LENGTH_MAX] = { 0, };
+ int buff_count = BUFFER_LENGTH_MAX;
+ int i = 0;
+
+ for (; i < cookies_size; i++)
+ {
+ buff_count -= snprintf((char *)(printf_buff + BUFFER_LENGTH_MAX - buff_count), buff_count, " %02X", cookies[i]);
+ }
+ DEBUG_CLIENT_MSG("client send cookies >>>> %s \n", printf_buff);
+
+ _net_nfc_client_set_cookies(cookies, cookies_size);
+ }
+ }
+#endif
+
+ clientDispatcher = &ClientDispatcher::getInstance();
+ clientIPC = &ClientIPC::getInstance();
+
+ clientIPC->setDispatcher(clientDispatcher);
+
+ if (clientDispatcher->runDispatcherThread() == false)
+ {
+ SCARD_DEBUG_ERR("clientDispatcher->runDispatcherThread() failed");
+
+ return result;
+ }
+
+ if (clientIPC->createConnectSocket() == false)
+ {
+ SCARD_DEBUG_ERR("clientIPC->createConnectSocket() failed");
+
+ return result;
+ }
+
+ clientDispatcher->addSEService(context, this);
+
+ {
+ /* send message to load se */
+ Message msg;
+
+ msg.message = Message::MSG_REQUEST_READERS;
+ msg.error = pid; /* using error to pid */
+ msg.caller = (void *)this;
+ msg.userParam = context;
+
+ result = clientIPC->sendMessage(&msg);
+ }
+
+ SCARD_END();
+
+ return result;
+ }
+
+ bool SEService::initialize(void *context, serviceConnected handler)
+ {
+ if (context == NULL)
+ {
+ SCARD_DEBUG_ERR("invalid param");
+ return false;
+ }
+
+ this->context = context;
+ this->handler = handler;
+
+ return _initialize();
+ }
+
+ bool SEService::initialize(void *context, SEServiceListener *listener)
+ {
+ if (context == NULL)
+ {
+ SCARD_DEBUG_ERR("invalid param");
+ return false;
+ }
+
+ this->context = context;
+ this->listener = listener;
+
+ return _initialize();
+ }
+
+ bool SEService::parseReaderInformation(unsigned int count, ByteArray data)
+ {
+ size_t i;
+ unsigned int offset = 0;
+ unsigned int len = 0;
+ void *handle = NULL;
+ Reader *reader = NULL;
+ char name[100];
+
+ for (i = 0; i < count && offset < data.getLength(); i++)
+ {
+ memset(name, 0, sizeof(name));
+
+ memcpy(&len, data.getBuffer(offset), sizeof(len));
+ offset += sizeof(len);
+
+ memcpy(name, data.getBuffer(offset), len);
+ offset += len;
+
+ memcpy(&handle, data.getBuffer(offset), sizeof(handle));
+ offset += sizeof(handle);
+
+ SCARD_DEBUG("Reader [%d] : name [%s], handle [%p]", i, name, handle);
+
+ /* add readers */
+ reader = new Reader(context, name, handle);
+ if (reader == NULL)
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ continue;
+ }
+
+ readers.push_back(reader);
+ }
+
+ return true;
+ }
+
+ bool SEService::dispatcherCallback(void *message)
+ {
+ Message *msg = (Message *)message;
+ SEService *service = NULL;
+ bool result = false;
+
+ SCARD_BEGIN();
+
+ if (msg == NULL)
+ {
+ SCARD_DEBUG_ERR("message is null");
+ return result;
+ }
+
+ service = (SEService *)msg->caller;
+
+ switch (msg->message)
+ {
+ case Message::MSG_REQUEST_READERS :
+ SCARD_DEBUG("[MSG_REQUEST_READERS]");
+
+ /* parse message data */
+ service->parseReaderInformation(msg->param1, msg->data);
+
+ /* call callback function */
+ if (service->listener != NULL)
+ {
+ service->listener->serviceConnected(service, service->context);
+ }
+ else if (service->handler != NULL)
+ {
+ service->handler(service, service->context);
+ }
+ break;
+
+ case Message::MSG_NOTIFY_SE_INSERTED :
+ SCARD_DEBUG("[MSG_NOTIFY_SE_INSERTED]");
+
+ if (service->listener != NULL)
+ {
+ service->listener->eventHandler(service, (char *)msg->data.getBuffer(), 1, service->context);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("service->listener is null");
+ }
+ break;
+
+ case Message::MSG_NOTIFY_SE_REMOVED :
+ SCARD_DEBUG("[MSG_NOTIFY_SE_REMOVED]");
+
+ if (service->listener != NULL)
+ {
+ service->listener->eventHandler(service, (char *)msg->data.getBuffer(), 2, service->context);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("service->listener is null");
+ }
+ break;
+
+ case Message::MSG_OPERATION_RELEASE_CLIENT :
+ SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
+
+ if (service->listener != NULL)
+ {
+ service->listener->errorHandler(service, msg->error, service->context);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("service->listener is null");
+ }
+ break;
+
+ default:
+ SCARD_DEBUG("unknown message [%s]", msg->toString());
+ break;
+ }
+
+ delete msg;
+
+ SCARD_END();
+
+ return result;
+ }
+
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define SE_SERVICE_EXTERN_BEGIN \
+ if (handle != NULL) \
+ { \
+ SEService *service = (SEService *)handle;
+
+#define SE_SERVICE_EXTERN_END \
+ } \
+ else \
+ { \
+ SCARD_DEBUG_ERR("Invalid param"); \
+ }
+
+using namespace smartcard_service_api;
+
+EXTERN_API se_service_h se_service_create_instance(void *user_data, se_service_connected_cb callback)
+{
+ SEService *service = new SEService(user_data, (serviceConnected)callback);
+
+ return (se_service_h)service;
+}
+
+EXTERN_API se_service_h se_service_create_instance_with_event_callback(void *user_data, se_service_connected_cb connected, se_service_event_cb event, se_sesrvice_error_cb error)
+{
+ SEService *service = new SEService(user_data, (serviceConnected)connected);
+
+ return (se_service_h)service;
+}
+
+EXTERN_API int se_service_get_readers_count(se_service_h handle)
+{
+ int count = 0;
+
+ SE_SERVICE_EXTERN_BEGIN;
+ vector<ReaderHelper *> temp_readers;
+
+ temp_readers = service->getReaders();
+ count = temp_readers.size();
+ SE_SERVICE_EXTERN_END;
+
+ return count;
+}
+
+EXTERN_API bool se_service_get_readers(se_service_h handle, reader_h *readers, int count)
+{
+ bool result = false;
+
+ SE_SERVICE_EXTERN_BEGIN;
+ vector<ReaderHelper *> temp_readers;
+ size_t i;
+
+ temp_readers = service->getReaders();
+
+ for (i = 0; i < temp_readers.size() && i < (size_t)count; i++)
+ {
+ readers[i] = (reader_h)temp_readers[i];
+ }
+ SE_SERVICE_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API bool se_service_is_connected(se_service_h handle)
+{
+ bool result = false;
+
+ SE_SERVICE_EXTERN_BEGIN;
+ result = service->isConnected();
+ SE_SERVICE_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API void se_service_shutdown(se_service_h handle)
+{
+ SE_SERVICE_EXTERN_BEGIN;
+ service->shutdown();
+ SE_SERVICE_EXTERN_END;
+}
+
+EXTERN_API void se_service_destroy_instance(se_service_h handle)
+{
+ SE_SERVICE_EXTERN_BEGIN;
+ delete service;
+ SE_SERVICE_EXTERN_END;
+}
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <unistd.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Session.h"
+#include "Reader.h"
+#include "ClientChannel.h"
+#include "ClientIPC.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ Session::Session(void *context, Reader *reader, void *handle):SessionHelper(reader)
+ {
+ this->context = NULL;
+
+ if (context == NULL || handle == NULL)
+ {
+ SCARD_DEBUG_ERR("handle is null");
+
+ return;
+ }
+
+ this->context = context;
+ this->handle = handle;
+ closed = false;
+ }
+
+ Session::~Session()
+ {
+ close(NULL, this);
+ }
+
+ void Session::closeChannels()
+ {
+ size_t i;
+
+ for (i = 0; i < channels.size(); i++)
+ {
+ channels[i]->close(NULL, this);
+ }
+
+ channels.clear();
+ }
+
+ ByteArray Session::getATRSync()
+ {
+ Message msg;
+ int rv;
+
+ /* request channel handle from server */
+ msg.message = Message::MSG_REQUEST_GET_ATR;
+ msg.param1 = (unsigned int)handle;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ syncLock();
+ rv = waitTimedCondition(0);
+ syncUnlock();
+
+ if (rv != 0)
+ {
+ SCARD_DEBUG_ERR("time over");
+
+ atr.releaseBuffer();
+ }
+
+ return atr;
+ }
+
+ int Session::getATR(getATRCallback callback, void *userData)
+ {
+ Message msg;
+
+ /* request channel handle from server */
+ msg.message = Message::MSG_REQUEST_GET_ATR;
+ msg.param1 = (unsigned int)handle;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)callback;
+ msg.userParam = userData;
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ return 0;
+ }
+
+ void Session::closeSync()
+ {
+ Message msg;
+ int rv;
+
+ if (isClosed() == false)
+ {
+ closed = true;
+ closeChannels();
+
+ /* request channel handle from server */
+ msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
+ msg.param1 = (unsigned int)handle;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ syncLock();
+ rv = waitTimedCondition(0);
+ syncUnlock();
+
+ if (rv != 0)
+ {
+ SCARD_DEBUG_ERR("time over");
+ }
+ }
+ }
+
+ int Session::close(closeSessionCallback callback, void *userData)
+ {
+ Message msg;
+
+ if (isClosed() == false)
+ {
+ closed = true;
+ closeChannels();
+
+ /* request channel handle from server */
+ msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
+ msg.param1 = (unsigned int)handle;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)callback;
+ msg.userParam = userData;
+
+ ClientIPC::getInstance().sendMessage(&msg);
+ }
+
+ return 0;
+ }
+
+ unsigned int Session::getChannelCount(getChannelCountCallback callback, void *userData)
+ {
+ Message msg;
+
+ msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
+ msg.param1 = (unsigned int)handle;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)callback;
+ msg.userParam = userData;
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ return 0;
+ }
+
+ unsigned int Session::getChannelCountSync()
+ {
+ Message msg;
+ int rv;
+
+ /* request channel handle from server */
+ msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
+ msg.param1 = (unsigned int)handle;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ syncLock();
+ rv = waitTimedCondition(0);
+ syncUnlock();
+
+ if (rv != 0)
+ {
+ SCARD_DEBUG_ERR("time over");
+
+ return -1;
+ }
+
+ return channelCount;
+ }
+
+ Channel *Session::openChannelSync(int id, ByteArray aid)
+ {
+ Message msg;
+ int rv;
+
+ /* request channel handle from server */
+ msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
+ msg.param1 = id;
+ msg.param2 = (unsigned int)handle;
+ msg.data = aid;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ syncLock();
+ rv = waitTimedCondition(0);
+ syncUnlock();
+
+ if (rv != 0)
+ {
+ SCARD_DEBUG_ERR("time over");
+
+ return NULL;
+ }
+
+ return (Channel *)openedChannel;
+ }
+
+ int Session::openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData)
+ {
+ Message msg;
+
+ /* request channel handle from server */
+ msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
+ msg.param1 = id;
+ msg.param2 = (unsigned int)handle;
+ msg.data = aid;
+ msg.error = (unsigned int)context; /* using error to context */
+ msg.caller = (void *)this;
+ msg.callback = (void *)callback;
+ msg.userParam = userData;
+
+ ClientIPC::getInstance().sendMessage(&msg);
+
+ return 0;
+ }
+
+ Channel *Session::openBasicChannelSync(ByteArray aid)
+ {
+ return openChannelSync(0, aid);
+ }
+
+ Channel *Session::openBasicChannelSync(unsigned char *aid, unsigned int length)
+ {
+ return openBasicChannelSync(ByteArray(aid, length));
+ }
+
+ int Session::openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData)
+ {
+ return openChannel(0, aid, callback, userData);
+ }
+
+ int Session::openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
+ {
+ return openBasicChannel(ByteArray(aid, length), callback, userData);
+ }
+
+ Channel *Session::openLogicalChannelSync(ByteArray aid)
+ {
+ return openChannelSync(1, aid);
+ }
+
+ Channel *Session::openLogicalChannelSync(unsigned char *aid, unsigned int length)
+ {
+ return openLogicalChannelSync(ByteArray(aid, length));
+ }
+
+ int Session::openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData)
+ {
+ return openChannel(1, aid, callback, userData);
+ }
+
+ int Session::openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
+ {
+ return openLogicalChannel(ByteArray(aid, length), callback, userData);
+ }
+
+ bool Session::dispatcherCallback(void *message)
+ {
+ Message *msg = (Message *)message;
+ Session *session = NULL;
+ bool result = false;
+
+ if (msg == NULL)
+ {
+ SCARD_DEBUG_ERR("message is null");
+ return result;
+ }
+
+ session = (Session *)msg->caller;
+
+ switch (msg->message)
+ {
+ case Message::MSG_REQUEST_OPEN_CHANNEL :
+ {
+ Channel *channel = NULL;
+
+ SCARD_DEBUG("MSG_REQUEST_OPEN_CHANNEL");
+
+ if (msg->param1 != 0)
+ {
+ /* create new instance of channel */
+ channel = new ClientChannel(session->context, session, msg->param2, msg->data, (void *)msg->param1);
+ if (channel != NULL)
+ {
+ session->channels.push_back(channel);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+
+ msg->error = -1;
+ }
+ }
+
+ if (msg->callback == (void *)session) /* synchronized call */
+ {
+ /* sync call */
+ session->syncLock();
+
+ /* copy result */
+ session->error = msg->error;
+ session->openedChannel = channel;
+
+ session->signalCondition();
+ session->syncUnlock();
+ }
+ else if (msg->callback != NULL)
+ {
+ openChannelCallback cb = (openChannelCallback)msg->callback;
+
+ /* async call */
+ cb(channel, msg->error, msg->userParam);
+ }
+ }
+ break;
+
+ case Message::MSG_REQUEST_GET_ATR :
+ {
+ SCARD_DEBUG("MSG_REQUEST_GET_ATR");
+
+ if (msg->callback == (void *)session) /* synchronized call */
+ {
+ /* sync call */
+ session->syncLock();
+
+ session->error = msg->error;
+ session->atr = msg->data;
+
+ session->signalCondition();
+ session->syncUnlock();
+ }
+ else if (msg->callback != NULL)
+ {
+ getATRCallback cb = (getATRCallback)msg->callback;
+
+ /* async call */
+ cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
+ }
+ }
+ break;
+
+ case Message::MSG_REQUEST_CLOSE_SESSION :
+ {
+ SCARD_DEBUG("MSG_REQUEST_CLOSE_SESSION");
+
+ if (msg->callback == (void *)session) /* synchronized call */
+ {
+ /* sync call */
+ session->syncLock();
+
+ session->error = msg->error;
+
+ session->signalCondition();
+ session->syncUnlock();
+ }
+ else if (msg->callback != NULL)
+ {
+ closeSessionCallback cb = (closeSessionCallback)msg->callback;
+
+ /* async call */
+ cb(msg->error, msg->userParam);
+ }
+ }
+ break;
+
+ case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
+ {
+ SCARD_DEBUG("MSG_REQUEST_GET_CHANNEL_COUNT");
+
+ if (msg->callback == (void *)session) /* synchronized call */
+ {
+ /* sync call */
+ session->syncLock();
+
+ session->error = msg->error;
+ session->channelCount = msg->param1;
+
+ session->signalCondition();
+ session->syncUnlock();
+ }
+ else if (msg->callback != NULL)
+ {
+ getChannelCountCallback cb = (getChannelCountCallback)msg->callback;
+
+ /* async call */
+ cb(msg->param1, msg->error, msg->userParam);
+ }
+ }
+ break;
+
+ default:
+ SCARD_DEBUG("unknown message : %s", msg->toString());
+ break;
+ }
+
+ delete msg;
+
+ return result;
+ }
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define SESSION_EXTERN_BEGIN \
+ if (handle != NULL) \
+ { \
+ Session *session = (Session *)handle;
+
+#define SESSION_EXTERN_END \
+ } \
+ else \
+ { \
+ SCARD_DEBUG_ERR("Invalid param"); \
+ }
+
+using namespace smartcard_service_api;
+
+EXTERN_API reader_h session_get_reader(session_h handle)
+{
+ reader_h reader = NULL;
+
+ SESSION_EXTERN_BEGIN;
+ reader = session->getReader();
+ SESSION_EXTERN_END;
+
+ return reader;
+}
+
+EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
+{
+ int result = -1;
+
+ SESSION_EXTERN_BEGIN;
+ result = session->getATR((getATRCallback)callback, userData);
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
+{
+ int result = -1;
+
+ SESSION_EXTERN_BEGIN;
+ result = session->close((closeSessionCallback)callback, userData);
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API bool session_is_closed(session_h handle)
+{
+ bool result = false;
+
+ SESSION_EXTERN_BEGIN;
+ result = session->isClosed();
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API void session_close_channels(session_h handle)
+{
+ SESSION_EXTERN_BEGIN;
+ session->closeChannels();
+ SESSION_EXTERN_END;
+}
+
+EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
+{
+ int result = -1;
+
+ SESSION_EXTERN_BEGIN;
+ result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
+{
+ int result = -1;
+
+ SESSION_EXTERN_BEGIN;
+ result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API unsigned int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData)
+{
+ unsigned int result = 0;
+
+ SESSION_EXTERN_BEGIN;
+ result = session->getChannelCount((getChannelCountCallback)callback, userData);
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API void session_destroy_instance(session_h handle)
+{
+ SESSION_EXTERN_BEGIN;
+ delete session;
+ SESSION_EXTERN_END;
+}
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 CLIENTCHANNEL_H_
+#define CLIENTCHANNEL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "Channel.h"
+#include "Session.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+ class ClientChannel: public Channel
+ {
+ private:
+ void *context;
+ void *handle;
+ /* temporary data for sync function */
+ int error;
+ ByteArray response;
+
+ ClientChannel(void *context, Session *session, int channelNum, ByteArray selectResponse, void *handle);
+
+ static bool dispatcherCallback(void *message);
+
+ void closeSync();
+ int transmitSync(ByteArray command, ByteArray &result);
+
+ public:
+ ~ClientChannel();
+
+ int close(closeCallback callback, void *userParam);
+ int transmit(ByteArray command, transmitCallback callback, void *userParam);
+
+ friend class ClientDispatcher;
+ friend class Session;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+int channel_close(channel_h handle, channel_close_cb callback, void *userParam);
+int channel_transmit(channel_h handle, unsigned char *command, unsigned int length, channel_transmit_cb callback, void *userParam);
+bool channel_is_basic_channel(channel_h handle);
+bool channel_is_closed(channel_h handle);
+
+unsigned int channel_get_select_response_length(channel_h handle);
+bool channel_get_select_response(channel_h handle, unsigned char *buffer, unsigned int length);
+session_h channel_get_session(channel_h handle);
+void channel_destroy_instance(channel_h handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CLIENTCHANNEL_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 CLIENTDISPATCHER_H_
+#define CLIENTDISPATCHER_H_
+
+/* standard library header */
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "DispatcherHelper.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class SEService;
+
+ class ClientDispatcher: public DispatcherHelper
+ {
+ private:
+ map<void *, SEService *> mapSESerivces;
+
+ ClientDispatcher();
+ ~ClientDispatcher();
+
+ void *dispatcherThreadFunc(DispatcherMsg *msg, void *data);
+
+ public:
+ static ClientDispatcher &getInstance();
+
+ bool addSEService(void *context, SEService *service);
+ void removeSEService(void *context);
+ };
+
+} /* namespace open_mobile_api */
+#endif /* CLIENTDISPATCHER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 CLIENTIPC_H_
+#define CLIENTIPC_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "IPCHelper.h"
+#include "SEServiceListener.h"
+
+namespace smartcard_service_api
+{
+ class ClientIPC: public IPCHelper
+ {
+ private:
+ ClientIPC();
+ ~ClientIPC();
+
+ int handleIOErrorCondition(void *channel, GIOCondition condition);
+ int handleInvalidSocketCondition(void *channel, GIOCondition condition);
+ int handleIncomingCondition(void *channel, GIOCondition condition);
+
+ public:
+ static ClientIPC &getInstance();
+ };
+
+} /* namespace open_mobile_api */
+#endif /* CLIENTIPC_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 READER_H_
+#define READER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "ReaderHelper.h"
+#include "Session.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+ class Reader: public ReaderHelper
+ {
+ private:
+ void *context;
+ void *handle;
+ ByteArray packageCert;
+ /* temporary data for sync function */
+ int error;
+ Session *openedSession;
+
+ Reader(void *context, char *name, void *handle);
+
+ SessionHelper *openSessionSync();
+ static bool dispatcherCallback(void *message);
+ void getPackageCert();
+
+ public:
+ ~Reader();
+
+ int openSession(openSessionCallback callback, void *userData);
+ void closeSessions();
+
+ friend class SEService;
+ friend class ClientDispatcher;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+const char *reader_get_name(reader_h handle);
+se_service_h reader_get_se_service(reader_h handle);
+bool reader_is_secure_element_present(reader_h handle);
+int reader_open_session(reader_h handle, reader_open_session_cb callback, void *userData);
+void reader_close_sessions(reader_h handle);
+void reader_destroy_instance(reader_h handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* READER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SESERVICE_H_
+#define SESERVICE_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "SEServiceListener.h"
+#include "SEServiceHelper.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+using namespace std;
+
+namespace smartcard_service_api
+{
+ typedef void (*serviceConnected)(SEServiceHelper *service, void *context);
+
+ class SEService: public SEServiceHelper
+ {
+ private:
+ int pid;
+ void *context;
+ serviceConnected handler;
+ SEServiceListener *listener;
+
+ SEService();
+
+ static bool dispatcherCallback(void *message);
+ bool parseReaderInformation(unsigned int count, ByteArray data);
+
+ bool _initialize();
+ bool initialize(void *context, serviceConnected handler);
+ bool initialize(void *context, SEServiceListener *listener);
+ SEService *initializeSync(void *context, serviceConnected handler);
+
+ public:
+ SEService(void *user_data, serviceConnected handler);
+ SEService(void *user_data, SEServiceListener *listener);
+ ~SEService();
+
+ void shutdown();
+
+ friend class ClientDispatcher;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+se_service_h se_service_create_instance(void *user_data, se_service_connected_cb callback);
+se_service_h se_service_create_instance_with_event_callback(void *user_data, se_service_connected_cb connected, se_service_event_cb event, se_sesrvice_error_cb error);
+int se_service_get_readers_count(se_service_h handle);
+bool se_service_get_readers(se_service_h handle, reader_h *readers, int count);
+bool se_service_is_connected(se_service_h handle);
+void se_service_shutdown(se_service_h handle);
+void se_service_destroy_instance(se_service_h handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SESERVICE_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SESERVICELISTENER_H_
+#define SESERVICELISTENER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+
+namespace smartcard_service_api
+{
+ class SEServiceHelper;
+
+ class SEServiceListener
+ {
+ public:
+ virtual void serviceConnected(SEServiceHelper *service, void *context) = 0;
+ virtual void eventHandler(SEServiceHelper *service, char *seName, int event, void *context) = 0;
+ virtual void errorHandler(SEServiceHelper *service, int error, void *context) = 0;
+ };
+
+} /* namespace open_mobile_api */
+#endif /* SESERVICELISTENER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SESSION_H_
+#define SESSION_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "SessionHelper.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+ class Reader;
+
+ class Session: public SessionHelper
+ {
+ private:
+ void *context;
+ void *handle;
+ /* temporary data for sync function */
+ int error;
+ Channel *openedChannel;
+ unsigned int channelCount;
+
+ Session(void *context, Reader *reader, void *handle);
+
+ int openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData);
+ static bool dispatcherCallback(void *message);
+
+ Channel *openChannelSync(int id, ByteArray aid);
+
+ ByteArray getATRSync();
+ void closeSync();
+
+ Channel *openBasicChannelSync(ByteArray aid);
+ Channel *openBasicChannelSync(unsigned char *aid, unsigned int length);
+ Channel *openLogicalChannelSync(ByteArray aid);
+ Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length);
+ unsigned int getChannelCountSync();
+
+ public:
+ ~Session();
+
+ int getATR(getATRCallback callback, void *userData);
+ int close(closeSessionCallback callback, void *userData);
+
+ void closeChannels();
+
+ int openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData);
+ int openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData);
+ int openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData);
+ int openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData);
+ unsigned int getChannelCount(getChannelCountCallback callback, void * userData);
+
+ friend class ClientDispatcher;
+ friend class Reader;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+reader_h session_get_reader(session_h handle);
+int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData);
+int session_close(session_h handle, session_close_session_cb callback, void *userData);
+bool session_is_closed(session_h handle);
+void session_close_channels(session_h handle);
+
+int session_open_basic_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData);
+int session_open_logical_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData);
+unsigned int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData);
+void session_destroy_instance(session_h handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SESSION_H_ */
--- /dev/null
+# Package Information for pkg-config
+
+prefix=/usr
+exec_prefix=${prefix}/bin
+includedir=${prefix}/include
+libdir=${prefix}/lib
+
+Name: smartcard-service
+Description: Make flags of Common library of Smartcard service
+Version: 1.0
+Requires:
+Libs: -L${libdir} -lsmartcard-service
+Cflags: -I${includedir}/smartcard-service
\ No newline at end of file
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "APDUHelper.h"
+
+namespace smartcard_service_api
+{
+ /* ResponseHelper class */
+ ResponseHelper::ResponseHelper()
+ {
+ }
+
+ ResponseHelper::ResponseHelper(const ByteArray &response)
+ {
+ setResponse(response);
+ }
+
+ ResponseHelper::~ResponseHelper()
+ {
+ }
+
+ bool ResponseHelper::setResponse(const ByteArray &response)
+ {
+ bool result = false;
+ status = 0;
+ dataField.releaseBuffer();
+
+ this->response = response;
+
+ if (response.getLength() >= 2)
+ {
+ sw[0] = response.getReverseAt(1);
+ sw[1] = response.getReverseAt(0);
+
+ status = parseStatusWord(sw);
+
+ if (response.getLength() > 2)
+ {
+ dataField.setBuffer(response.getBuffer(), response.getLength() - 2);
+ }
+
+ result = true;
+ }
+
+ return result;
+ }
+
+ int ResponseHelper::parseStatusWord(unsigned char *sw)
+ {
+ int result = 0;
+
+ switch (sw[0])
+ {
+ /* Normal processing */
+ case (unsigned char)0x90 : /* SW2:00, No further qulification */
+ break;
+
+ case (unsigned char)0x91 : /* extra information */
+ break;
+
+ case (unsigned char)0x61 : /* SW2 encodes the number of data bytes still available */
+ break;
+
+ /* Warning processing */
+ case (unsigned char)0x62 : /* State of non-volatile memory is unchanged (further qualification in SW2) */
+ break;
+
+ case (unsigned char)0x63 : /* State of non-volatile memory has changed (further qualification in SW2) */
+ break;
+
+ /* Execution error */
+ case (unsigned char)0x64 : /* State of non-volatile memory is unchanged (further qualification in SW2) */
+ result = -1;
+ break;
+
+ case (unsigned char)0x65 : /* State of non-volatile memory has changed (further qualification in SW2) */
+ result = -1;
+ break;
+
+ case (unsigned char)0x66 : /* Security-related issues */
+ result = -1;
+ break;
+
+ /* Checking error */
+ case (unsigned char)0x67 : /* SW2:00, Wrong length; no further indication */
+ result = -1;
+ break;
+
+ case (unsigned char)0x68 : /* Functions in CLA not supported (further qualification in SW2) */
+ result = -1;
+ break;
+
+ case (unsigned char)0x69 : /* Command not allowed (further qualification in SW2) */
+ result = -1;
+ break;
+
+ case (unsigned char)0x6A : /* Wrong parameters P1-P2 (further qualification in SW2) */
+ result = -1;
+ break;
+
+ case (unsigned char)0x6B : /* SW2:00, Wrong parameters P1-P2 */
+ result = -1;
+ break;
+
+ case (unsigned char)0x6C : /* Wrong Le field; SW2 encodes the exact number of available data bytes */
+ result = -1;
+ break;
+
+ case (unsigned char)0x6D : /* SW2:00, Instruction code not supported or invalid */
+ result = -1;
+ break;
+
+ case (unsigned char)0x6E : /* SW2:00, Class not supported */
+ result = -1;
+ break;
+
+ case (unsigned char)0x6F : /* SW2:00, No precise diagnosis */
+ result = -1;
+ break;
+
+ default :
+ result = -1;
+ break;
+ }
+
+ return result;
+ }
+
+ int ResponseHelper::getStatus()
+ {
+ return status;
+ }
+
+ int ResponseHelper::getStatus(const ByteArray &response)
+ {
+ int status = 0;
+
+ if (response.getLength() >= 2)
+ {
+ status = ResponseHelper::parseStatusWord(response.getBuffer((response.getLength() - 2)));
+ }
+
+ return status;
+ }
+
+ ByteArray ResponseHelper::getDataField()
+ {
+ return dataField;
+ }
+
+ ByteArray ResponseHelper::getDataField(const ByteArray &response)
+ {
+ ByteArray result;
+
+ if (response.getLength() > 2)
+ {
+ result.setBuffer(response.getBuffer(), response.getLength() - 2);
+ }
+
+ return result;
+ }
+
+ /* APDUCommand class */
+ APDUCommand::APDUCommand()
+ {
+ maxResponseSize = 0;
+ isExtendedLength = false;
+ memset(&header, 0, sizeof(header));
+ }
+
+ APDUCommand::~APDUCommand()
+ {
+ }
+
+ bool APDUCommand::setCommand(unsigned char cla, unsigned char ins, unsigned char p1, unsigned char p2, ByteArray commandData, unsigned int maxResponseSize)
+ {
+ setCLA(cla);
+ setINS(ins);
+ setP1(p1);
+ setP2(p2);
+ setCommandData(commandData);
+ setMaxResponseSize(maxResponseSize);
+
+ return true;
+ }
+
+ bool APDUCommand::setCommand(const ByteArray &command)
+ {
+ bool result = false;
+ uint32_t offset = 0;
+ uint32_t lengthSize = 1;
+
+ if (command.getLength() < sizeof(header))
+ {
+ return false;
+ }
+
+ memcpy(&header, command.getBuffer(offset), sizeof(header));
+ offset += sizeof(header);
+
+ if (isExtendedLength)
+ {
+ lengthSize = 2;
+ }
+
+ if (command.getLength() - offset > lengthSize)
+ {
+ unsigned int length = 0;
+
+ /* data exist */
+ if (isExtendedLength)
+ {
+ /* TODO */
+ offset += 2;
+ }
+ else
+ {
+ length = command.getAt(offset);
+ offset += 1;
+ }
+
+ setCommandData(ByteArray(command.getBuffer(offset), length));
+ offset += length;
+ }
+
+ if (command.getLength() - offset == lengthSize)
+ {
+ if (isExtendedLength)
+ {
+ /* TODO */
+ offset += 2;
+ }
+ else
+ {
+ setMaxResponseSize(command.getAt(offset));
+ offset += 1;
+ }
+ }
+
+ if (command.getLength() == offset)
+ {
+ result = true;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("command stream is not correct, command.getLength() [%d], offset [%d]", command.getLength(), offset);
+ }
+
+ return result;
+ }
+
+ bool APDUCommand::setChannel(int type, int channelNum)
+ {
+ bool result = false;
+
+ if (channelNum != 0)
+ {
+ switch (type)
+ {
+ case 0 :
+ if (channelNum > 0 && channelNum < 4)
+ {
+ unsigned char temp;
+
+ temp = getCLA();
+ temp &= ~0x03;
+ temp |= (channelNum & 0x03);
+ setCLA(temp);
+
+ result = true;
+ }
+ break;
+
+ default :
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ void APDUCommand::setCLA(unsigned char cla)
+ {
+ /* check criteria */
+ if (cla == 0xFF)
+ return;
+
+ header.cla = cla;
+ }
+
+ unsigned char APDUCommand::getCLA()
+ {
+ return header.cla;
+ }
+
+ void APDUCommand::setINS(unsigned char ins)
+ {
+ /* check criteria */
+ if ((ins & 0xF0) == 0x60 || (ins & 0xF0) == 0x90)
+ return;
+
+ header.ins = ins;
+ }
+
+ unsigned char APDUCommand::getINS()
+ {
+ return header.ins;
+ }
+
+ void APDUCommand::setP1(unsigned char p1)
+ {
+ /* check criteria */
+ header.param[0] = p1;
+ }
+
+ unsigned char APDUCommand::getP1()
+ {
+ return header.param[0];
+ }
+
+ void APDUCommand::setP2(unsigned char p2)
+ {
+ /* check criteria */
+ header.param[1] = p2;
+ }
+
+ unsigned char APDUCommand::getP2()
+ {
+ return header.param[1];
+ }
+
+ void APDUCommand::setCommandData(const ByteArray &data)
+ {
+ commandData = data;
+ }
+
+ ByteArray APDUCommand::getCommandData()
+ {
+ return commandData;
+ }
+
+ void APDUCommand::setMaxResponseSize(unsigned int maxResponseSize)
+ {
+ this->maxResponseSize = maxResponseSize;
+ }
+
+ unsigned int APDUCommand::setMaxResponseSize()
+ {
+ return maxResponseSize;
+ }
+
+ bool APDUCommand::getBuffer(ByteArray &array)
+ {
+ unsigned char *temp_buffer = NULL;
+ unsigned int temp_len = 0;
+ unsigned char lc[3] = { 0, };
+ unsigned int lc_len = 0;
+ unsigned char le[3] = { 0, };
+ unsigned int le_len = 0;
+ unsigned int offset = 0;
+
+ /* */
+ temp_len += sizeof(header);
+
+ /* calculate lc length */
+ if (commandData.getLength() > 0)
+ {
+ if (isExtendedLength/*commandData.getLength() > 255*/)
+ {
+ lc[1] = (commandData.getLength() >> 8) & 0x000000FF;
+ lc[2] = commandData.getLength() & 0x000000FF;
+
+ lc_len = 3;
+ }
+ else
+ {
+ lc[0] = commandData.getLength() & 0x000000FF;
+
+ lc_len = 1;
+ }
+ }
+
+ temp_len += lc_len;
+
+ /* add command data length */
+ temp_len += commandData.getLength();
+
+ /* calculate le length */
+ if (maxResponseSize > 0)
+ {
+ if (isExtendedLength/*commandData.getLength() > 255*/)
+ {
+ if (maxResponseSize < 65536)
+ {
+ le[1] = (maxResponseSize >> 8) & 0x000000FF;
+ le[2] = maxResponseSize & 0x000000FF;
+
+ le_len = 3;
+ }
+ else if (maxResponseSize == 65536)
+ {
+ le_len = 2;
+ }
+ }
+ else
+ {
+ if (maxResponseSize != 256)
+ le[0] = maxResponseSize & 0x000000FF;
+
+ le_len = 1;
+ }
+ }
+
+ temp_len += le_len;
+
+ temp_buffer = new unsigned char[temp_len];
+ if (temp_buffer == NULL)
+ return false;
+
+ /* fill data */
+ offset = 0;
+
+ memcpy(temp_buffer + offset, &header, sizeof(header));
+ offset += sizeof(header);
+
+ if (commandData.getLength() > 0)
+ {
+ memcpy(temp_buffer + offset, &lc, lc_len);
+ offset += lc_len;
+
+ memcpy(temp_buffer + offset, commandData.getBuffer(), commandData.getLength());
+ offset += commandData.getLength();
+ }
+
+ if (maxResponseSize > 0)
+ {
+ memcpy(temp_buffer + offset, &le, le_len);
+ offset += le_len;
+ }
+
+ array.setBuffer(temp_buffer, temp_len);
+ delete []temp_buffer;
+
+ return true;
+ }
+
+ /* APDUHelper class */
+ ByteArray APDUHelper::generateAPDU(int command, int channel, ByteArray data)
+ {
+ ByteArray result;
+ APDUCommand apdu;
+
+ switch (command)
+ {
+ case COMMAND_OPEN_LOGICAL_CHANNEL :
+ apdu.setCommand(0, APDUCommand::INS_MANAGE_CHANNEL, 0, 0, ByteArray::EMPTY, 1);
+ apdu.getBuffer(result);
+ break;
+
+ case COMMAND_CLOSE_LOGICAL_CHANNEL :
+ apdu.setCommand(0, APDUCommand::INS_MANAGE_CHANNEL, 0x80, channel, ByteArray::EMPTY, 0);
+ apdu.getBuffer(result);
+ break;
+
+ case COMMAND_SELECT_BY_ID :
+ apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_ID, APDUCommand::P2_SELECT_GET_FCP, data, 0);
+ apdu.getBuffer(result);
+ break;
+
+ case COMMAND_SELECT_PARENT_DF :
+ apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_PARENT_DF, APDUCommand::P2_SELECT_GET_FCP, data, 0);
+ apdu.getBuffer(result);
+ break;
+
+ case COMMAND_SELECT_BY_DF_NAME :
+ apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_DF_NAME, APDUCommand::P2_SELECT_GET_FCP, data, 0);
+ apdu.getBuffer(result);
+ break;
+
+ case COMMAND_SELECT_BY_PATH :
+ apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_PATH, APDUCommand::P2_SELECT_GET_FCP, data, 0);
+ apdu.getBuffer(result);
+ break;
+
+ case COMMAND_SELECT_BY_PATH_FROM_CURRENT_DF :
+ apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_PATH_FROM_CURRENT_DF, APDUCommand::P2_SELECT_GET_FCP, data, 0);
+ apdu.getBuffer(result);
+ break;
+
+ default :
+ break;
+ }
+
+ return result;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "SimpleTLV.h"
+#include "AccessCondition.h"
+
+namespace smartcard_service_api
+{
+ void APDUAccessRule::loadAPDUAccessRule(const ByteArray &data)
+ {
+ SimpleTLV tlv(data);
+
+ 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();
+
+ SCARD_DEBUG("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
+ {
+ SCARD_DEBUG_ERR("Invalid APDU rule : %s", value.toString());
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
+ }
+ }
+ tlv.returnToParentTLV();
+ break;
+
+ default :
+ SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
+ break;
+ }
+ }
+ }
+
+ bool APDUAccessRule::isAuthorizedAccess(const ByteArray &command)
+ {
+ bool result = false;
+
+ if (mapApduFilters.size() > 0)
+ {
+ /* TODO : search command and check validity */
+ }
+ else
+ {
+ /* no filter entry. if permission is true, all access will be granted, if not, all access will be denied */
+ result = permission;
+ }
+
+ return result;
+ }
+
+ void APDUAccessRule::printAPDUAccessRules()
+ {
+ SCARD_DEBUG(" +-- APDU Access Rule");
+
+ if (mapApduFilters.size() > 0)
+ {
+ map<ByteArray, ByteArray>::iterator iterMap;
+
+ for (iterMap = mapApduFilters.begin(); iterMap != mapApduFilters.end(); iterMap++)
+ {
+ SCARD_DEBUG(" +--- APDU : %s, Mask : %s", ((ByteArray)(iterMap->first)).toString(), iterMap->second.toString());
+ }
+ }
+ else
+ {
+ SCARD_DEBUG(" +--- permission : %s", permission ? "granted all" : "denied all");
+ }
+ }
+
+ void NFCAccessRule::loadNFCAccessRule(const ByteArray &data)
+ {
+ permission = SimpleTLV::getBoolean(data);
+ }
+
+ bool NFCAccessRule::isAuthorizedAccess(void)
+ {
+ bool result = false;
+
+ result = permission;
+
+ return result;
+ }
+
+ void NFCAccessRule::printNFCAccessRules()
+ {
+ SCARD_DEBUG(" +-- NFC Access Rule");
+ SCARD_DEBUG(" +--- permission : %s", permission ? "granted all" : "denied all");
+ }
+
+ void AccessCondition::loadAccessCondition(ByteArray &aid, ByteArray &data)
+ {
+ 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 */
+ SCARD_DEBUG("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 :
+ SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
+ break;
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("tlv.decodeTLV failed");
+ }
+ tlv.returnToParentTLV();
+ break;
+
+ default :
+ SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
+ break;
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("tlv.decodeTLV failed");
+ }
+ tlv.returnToParentTLV();
+ }
+ else
+ {
+ SCARD_DEBUG("access granted for all applications, aid : %s", aid.toString());
+
+ permission = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ SCARD_DEBUG("access denied for all applications, aid : %s", aid.toString());
+
+ permission = false;
+ }
+ }
+
+ bool AccessCondition::isAuthorizedAccess(ByteArray &certHash)
+ {
+ bool result = false;
+
+ if (hashes.size() > 0)
+ {
+ size_t i;
+
+ for (i = 0; i < hashes.size(); i++)
+ {
+ if (certHash == hashes[i])
+ {
+ result = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ result = permission;
+ }
+
+ return result;
+ }
+
+ bool AccessCondition::isAuthorizedAPDUAccess(ByteArray &command)
+ {
+ bool result = false;
+
+ result = apduRule.isAuthorizedAccess(command);
+
+ return result;
+ }
+
+ bool AccessCondition::isAuthorizedNFCAccess()
+ {
+ bool result = false;
+
+ result = nfcRule.isAuthorizedAccess();
+
+ return result;
+ }
+
+ void AccessCondition::printAccessConditions()
+ {
+ SCARD_DEBUG(" +-- Access Condition");
+
+ if (hashes.size() > 0)
+ {
+ size_t i;
+
+ for (i = 0; i < hashes.size(); i++)
+ {
+ SCARD_DEBUG(" +--- hash : %s", hashes[i].toString());
+ }
+ }
+ else
+ {
+ SCARD_DEBUG(" +--- permission : %s", permission ? "granted all" : "denied all");
+ }
+ }
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+
+/* SLP library header */
+
+/* local header */
+#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 };
+
+ ByteArray AccessControlList::AID_ALL(ARRAY_AND_SIZE(aid_all));
+ ByteArray AccessControlList::AID_DEFAULT(ARRAY_AND_SIZE(aid_default));
+
+ AccessControlList::AccessControlList()
+ {
+ channel = NULL;
+ terminal = NULL;
+ }
+
+ AccessControlList::AccessControlList(Channel *channel)
+ {
+ channel = NULL;
+ terminal = NULL;
+
+ setChannel(channel);
+ }
+
+ AccessControlList::AccessControlList(Terminal *terminal)
+ {
+ channel = NULL;
+ terminal = NULL;
+
+ setTerminal(terminal);
+ }
+
+ AccessControlList::~AccessControlList()
+ {
+ releaseACL();
+
+ if (terminal != NULL && channel != NULL)
+ {
+ delete channel;
+ }
+ }
+
+ int AccessControlList::setChannel(Channel *channel)
+ {
+ this->channel = channel;
+
+ return 0;
+ }
+
+ int AccessControlList::updateACL()
+ {
+ releaseACL();
+
+ return loadACL();
+ }
+
+ void AccessControlList::releaseACL()
+ {
+ mapConditions.clear();
+ }
+
+ bool AccessControlList::isAuthorizedAccess(ByteArray aid, ByteArray certHash)
+ {
+ bool result = false;
+ map<ByteArray, AccessCondition>::iterator iterMap;
+
+ SCARD_DEBUG("aid : %s", aid.toString());
+ SCARD_DEBUG("hash : %s", certHash.toString());
+
+ /* null aid means default applet */
+ if (aid.isEmpty() == true)
+ {
+ aid = AID_DEFAULT;
+ }
+
+ /* 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 result;
+ }
+
+ bool AccessControlList::isAuthorizedAccess(unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength)
+ {
+ return isAuthorizedAccess(ByteArray(aidBuffer, aidLength), ByteArray(certHashBuffer, certHashLength));
+ }
+
+ void AccessControlList::printAccessControlList()
+ {
+ ByteArray temp;
+
+ /* release map and vector */
+ map<ByteArray, AccessCondition>::iterator iterMap;
+
+ SCARD_DEBUG("================ Certification Hashes ==================");
+ for (iterMap = mapConditions.begin(); iterMap != mapConditions.end(); iterMap++)
+ {
+ temp = iterMap->first;
+
+ SCARD_DEBUG("+ aid : %s", (temp == AID_DEFAULT) ? "DEFAULT" : (temp == AID_ALL) ? "ALL" : temp.toString());
+
+ iterMap->second.printAccessConditions();
+ }
+ SCARD_DEBUG("========================================================");
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ ByteArray ByteArray::EMPTY = ByteArray();
+
+ ByteArray::ByteArray()
+ {
+ buffer = NULL;
+ length = 0;
+ }
+
+ ByteArray::ByteArray(uint8_t *array, uint32_t bufferLen)
+ {
+ buffer = NULL;
+ length = 0;
+
+ setBuffer(array, bufferLen);
+ }
+
+ ByteArray::ByteArray(const ByteArray &T)
+ {
+ buffer = NULL;
+ length = 0;
+
+ setBuffer(T.buffer, T.length);
+ }
+
+ ByteArray::~ByteArray()
+ {
+ releaseBuffer();
+ }
+
+ bool ByteArray::setBuffer(uint8_t *array, uint32_t bufferLen)
+ {
+ if (array == NULL || bufferLen == 0)
+ {
+ return false;
+ }
+
+ releaseBuffer();
+
+ buffer = new uint8_t[bufferLen];
+ if (buffer == NULL)
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ return false;
+ }
+
+ memcpy(buffer, array, bufferLen);
+ length = bufferLen;
+
+ return true;
+ }
+
+ bool ByteArray::_setBuffer(uint8_t *array, uint32_t bufferLen)
+ {
+ if (array == NULL || bufferLen == 0)
+ {
+ return false;
+ }
+
+ releaseBuffer();
+
+ buffer = array;
+ length = bufferLen;
+
+ return true;
+ }
+
+ uint32_t ByteArray::getLength() const
+ {
+ return length;
+ }
+
+ uint8_t *ByteArray::getBuffer() const
+ {
+ return getBuffer(0);
+ }
+
+ uint8_t *ByteArray::getBuffer(uint32_t offset) const
+ {
+ if (length == 0)
+ return NULL;
+
+ if (offset >= length)
+ {
+ SCARD_DEBUG_ERR("buffer overflow, offset [%d], length [%d]", offset, length);
+ return NULL;
+ }
+
+ return buffer + offset;
+ }
+
+ uint8_t ByteArray::getAt(uint32_t index) const
+ {
+ if (index >= length)
+ {
+ SCARD_DEBUG_ERR("buffer overflow, index [%d], length [%d]", index, length);
+ return buffer[length -1];
+ }
+
+ return buffer[index];
+ }
+
+ uint8_t ByteArray::getReverseAt(uint32_t index) const
+ {
+ if (index >= length)
+ {
+ SCARD_DEBUG_ERR("buffer underflow, index [%d], length [%d]", index, length);
+ return buffer[0];
+ }
+
+ return buffer[length - index - 1];
+ }
+
+ uint32_t ByteArray::copyFromArray(uint8_t *array, uint32_t bufferLen) const
+ {
+ uint32_t min_len = 0;
+
+ if (array == NULL || bufferLen == 0)
+ {
+ SCARD_DEBUG_ERR("invaild param");
+ return false;
+ }
+
+ min_len = (bufferLen < length) ? bufferLen : length;
+
+ memcpy(array, buffer, min_len);
+
+ return min_len;
+ }
+
+ void ByteArray::releaseBuffer()
+ {
+ if (buffer != NULL)
+ {
+ delete []buffer;
+ buffer = NULL;
+ }
+ length = 0;
+ }
+
+ /* operator overloading */
+ ByteArray ByteArray::operator +(const ByteArray &T)
+ {
+ uint32_t newLen;
+ uint8_t *newBuffer;
+ ByteArray newArray;
+
+ if (length == 0)
+ {
+ SCARD_DEBUG("length is zero");
+
+ return T;
+ }
+
+ newLen = T.length;
+
+ if (newLen == 0)
+ return *this;
+
+ newLen += length;
+
+ newBuffer = new uint8_t[newLen];
+ if (newBuffer == NULL)
+ {
+ /* assert.... */
+ SCARD_DEBUG_ERR("alloc failed");
+
+ return *this;
+ }
+
+ memcpy(newBuffer, buffer, length);
+ memcpy(newBuffer + length, T.buffer, T.length);
+
+ newArray._setBuffer(newBuffer, newLen);
+
+ return newArray;
+ }
+
+ ByteArray &ByteArray::operator =(const ByteArray &T)
+ {
+ if (this != &T)
+ {
+ setBuffer(T.buffer, T.length);
+ }
+
+ return *this;
+ }
+
+ ByteArray &ByteArray::operator +=(const ByteArray &T)
+ {
+ *this = *this + T;
+
+ return *this;
+ }
+
+ bool ByteArray::operator ==(const ByteArray &T) const
+ {
+ if (length != T.length)
+ return false;
+
+ return (memcmp(buffer, T.buffer, length) == 0);
+ }
+
+ bool ByteArray::operator !=(const ByteArray &T) const
+ {
+ return !(*this == T);
+ }
+
+ bool ByteArray::operator <(const ByteArray &T) const
+ {
+ return (memcmp(buffer, T.buffer, (length < T.length) ? length : T.length) < 0);
+ }
+
+ bool ByteArray::operator >(const ByteArray &T) const
+ {
+ return (memcmp(buffer, T.buffer, (length < T.length) ? length : T.length) > 0);
+ }
+
+ uint8_t &ByteArray::operator [](uint32_t index) const
+ {
+ if (index >= length)
+ {
+ SCARD_DEBUG_ERR("buffer overflow, index [%d], length [%d]", index, length);
+ return buffer[length -1];
+ }
+
+ return buffer[index];
+ }
+
+ const char *ByteArray::toString()
+ {
+ memset(strBuffer, 0, sizeof(strBuffer));
+
+ if (length == 0)
+ {
+ snprintf(strBuffer, sizeof(strBuffer), "buffer is empty");
+ }
+ else
+ {
+ int count;
+ int i, offset = 0;
+ bool ellipsis = false;
+
+ count = length;
+ if (count > 20)
+ {
+ count = 20;
+ ellipsis = true;
+ }
+
+ snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "{ ");
+ offset += 2;
+
+ for (i = 0; i < count; i++)
+ {
+ snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "%02X ", buffer[i]);
+ offset += 3;
+ }
+
+ if (ellipsis)
+ {
+ snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "... }");
+ }
+ else
+ {
+ snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "}");
+ }
+ }
+
+ return (const char *)strBuffer;
+ }
+
+ void ByteArray::save(const char *filePath)
+ {
+ FILE *file = NULL;
+
+ if (filePath == NULL || buffer == NULL || length == 0)
+ return;
+
+ if ((file = fopen(filePath, "w")) != NULL)
+ {
+ fwrite(buffer, 1, length, file);
+ fflush(file);
+
+ fclose(file);
+ SCARD_DEBUG("file has written, file [%s], length[%d]", filePath, length);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("file open failed, [%d]", errno);
+ }
+ }
+
+} /* namespace smartcard_service_api */
+
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(smartcard-service-common CXX)
+
+SET(LIB_NAME "smartcard-service-common")
+SET(VERSION_MAJOR 1)
+SET(VERSION ${VERSION_MAJOR}.0.0)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SRCS)
+
+#IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+# SET(CMAKE_BUILD_TYPE "Debug")
+#ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+#MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_common REQUIRED dlog glib-2.0 gthread-2.0 dpl-wrt-dao-ro aul libssl)
+
+MESSAGE("${LIB_NAME} ld flag : ${pkgs_common_LDFLAGS}")
+
+FOREACH(flag ${pkgs_common_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${pkgs_common_CFLAGS})
+ SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+#SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -finstrument-functions")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+#SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+#SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+#SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -finstrument-functions")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+#SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+#SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+ ADD_DEFINITIONS("-DTARGET")
+ MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+MESSAGE("CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DSLP_DEBUG")
+ADD_DEFINITIONS("-DUSE_UNIX_DOMAIN")
+
+ADD_DEFINITIONS("-DLOG_TAG=\"SCARD_COMMON\"")
+
+# Temporary add #############
+ADD_DEFINITIONS("-std=c++0x")
+#############################
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES VERSION ${VERSION})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_common_LDFLAGS})
+
+SET(EXPORT_HEADER
+ include/Debug.h
+ include/ByteArray.h
+ include/Lock.h
+ include/Synchronous.h
+ include/TerminalInterface.h
+ include/Terminal.h
+ include/SignatureHelper.h
+ include/GPSEACL.h
+)
+
+#CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc DESTINATION lib/pkgconfig)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib)
+FOREACH(hfile ${EXPORT_HEADER})
+ INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
+ENDFOREACH(hfile)
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "DispatcherHelper.h"
+
+namespace smartcard_service_api
+{
+ DispatcherHelper::DispatcherHelper()
+ {
+ dispatcherThread = 0;
+ }
+
+ DispatcherHelper::~DispatcherHelper()
+ {
+ stopDispatcherThread();
+ }
+
+ DispatcherMsg *DispatcherHelper::fetchMessage()
+ {
+ DispatcherMsg *result = NULL;
+
+ if (messageQ.size() > 0)
+ {
+ result = messageQ.front();
+ messageQ.pop();
+ }
+
+ return result;
+ }
+
+ void DispatcherHelper::clearQueue()
+ {
+ DispatcherMsg *temp = NULL;
+
+ while (messageQ.size() > 0)
+ {
+ temp = fetchMessage();
+ delete temp;
+ }
+ }
+
+ void DispatcherHelper::pushMessage(DispatcherMsg *msg)
+ {
+ syncLock();
+
+ messageQ.push(msg);
+
+ signalCondition();
+ syncUnlock();
+ }
+
+ void *DispatcherHelper::_dispatcherThreadFunc(void *data)
+ {
+ DispatcherMsg *msg = NULL;
+ DispatcherHelper *helper = (DispatcherHelper *)data;
+
+ while (1)
+ {
+ helper->syncLock();
+ if ((msg = helper->fetchMessage()) == NULL)
+ {
+ helper->waitTimedCondition(0);
+ helper->syncUnlock();
+ continue;
+ }
+ helper->syncUnlock();
+
+ /* process message */
+ helper->dispatcherThreadFunc(msg, data);
+
+ delete msg;
+ }
+
+ return (void *)NULL;
+ }
+
+ bool DispatcherHelper::runDispatcherThread()
+ {
+ bool result = false;
+ pthread_attr_t attr;
+
+ if (dispatcherThread == 0)
+ {
+ int ret;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ if ((ret = pthread_create(&dispatcherThread, &attr, &DispatcherHelper::_dispatcherThreadFunc, this)) != 0)
+ {
+ SCARD_DEBUG_ERR("pthread_create failed [%d]", ret);
+ }
+ else
+ {
+ SCARD_DEBUG("pthread_create success");
+ result = true;
+ }
+ }
+ else
+ {
+ SCARD_DEBUG("thread already start");
+ result = true;
+ }
+
+ return result;
+ }
+
+ void DispatcherHelper::stopDispatcherThread()
+ {
+ if (dispatcherThread != 0)
+ {
+ pthread_cancel(dispatcherThread);
+ dispatcherThread = 0;
+ }
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "FCI.h"
+#include "SimpleTLV.h"
+//#include "ISO7816BERTLV.h"
+#include "NumberStream.h"
+
+namespace smartcard_service_api
+{
+ /* FCP class method */
+ FCP::FCP()
+ {
+ resetMemberVar();
+ }
+
+ FCP::FCP(ByteArray &array)
+ {
+ resetMemberVar();
+
+ setFCP(array);
+ }
+
+ FCP::~FCP()
+ {
+ }
+
+ void FCP::resetMemberVar()
+ {
+ fileSize = FCI::INFO_NOT_AVAILABLE;
+ totalFileSize = FCI::INFO_NOT_AVAILABLE;
+ fid = FCI::INFO_NOT_AVAILABLE;
+ sfi = FCI::INFO_NOT_AVAILABLE;
+ maxRecordSize = FCI::INFO_NOT_AVAILABLE;
+ numberOfRecord = FCI::INFO_NOT_AVAILABLE;
+ fileType = FCI::INFO_NOT_AVAILABLE;
+ fileStructure = FCI::INFO_NOT_AVAILABLE;
+ lcs = FCI::INFO_NOT_AVAILABLE;
+ }
+
+ bool FCP::setFCP(ByteArray array)
+ {
+ bool result = false;
+ SimpleTLV tlv;
+
+ SCARD_BEGIN();
+
+ releaseFCP();
+
+ if (array.getLength() == 0)
+ return false;
+
+ fcpBuffer = array;
+
+ if (fcpBuffer[0] != 0x62)
+ {
+ SCARD_DEBUG_ERR("it is not FCP response [%02X]", fcpBuffer[0]);
+ return false;
+ }
+
+ /* parse... */
+ tlv.setTLVBuffer(fcpBuffer.getBuffer(), fcpBuffer.getLength());
+
+ if (tlv.decodeTLV())
+ {
+ tlv.enterToValueTLV();
+
+ while (tlv.decodeTLV())
+ {
+ switch (tlv.getTag())
+ {
+ case 0x80 : /* file length without sturctural inforamtion */
+ {
+ SCARD_DEBUG("0x%02X : file length without sturctural inforamtion : %s", tlv.getTag(), tlv.getValue().toString());
+ if (tlv.getLength() > 0)
+ {
+ fileSize = NumberStream::getBigEndianNumber(tlv.getValue());
+ }
+ }
+ break;
+
+ case 0x81 : /* file length with sturctural inforamtion */
+ {
+ SCARD_DEBUG("0x%02X : file length with sturctural inforamtion : %s", tlv.getTag(), tlv.getValue().toString());
+ if (tlv.getLength() > 0)
+ {
+ maxRecordSize = NumberStream::getBigEndianNumber(tlv.getValue());
+ }
+ }
+ break;
+
+ case 0x82 : /* file descriptor bytes */
+ {
+ SCARD_DEBUG("0x%02X : file descriptor bytes : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0x83 : /* file identifier */
+ {
+ SCARD_DEBUG("0x%02X : file identifier : %s", tlv.getTag(), tlv.getValue().toString());
+ if (tlv.getLength() > 0)
+ {
+ ByteArray value = tlv.getValue();
+
+ fid = 0;
+
+ memcpy(&fid, value.getBuffer(), value.getLength());
+ }
+ }
+ break;
+
+ case 0x84 : /* DF name */
+ {
+ SCARD_DEBUG("0x%02X : DF name : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0x85 : /* proprietary information not encoded in BER-TLV */
+ {
+ SCARD_DEBUG("0x%02X : proprietary information not encoded in BER-TLV : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0x86 : /* Security attribute in proprietary format */
+ {
+ SCARD_DEBUG("0x%02X : Security attribute in proprietary format : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0x87 : /* Identifier of an EF containing an extension of the file control information */
+ {
+ SCARD_DEBUG("0x%02X : Identifier of an EF containing an extension of the file control information : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0x88 : /* Short EF identifier */
+ {
+ SCARD_DEBUG("0x%02X : Short EF identifier : %s", tlv.getTag(), tlv.getValue().toString());
+
+ if (tlv.getLength() > 0)
+ {
+ ByteArray value = tlv.getValue();
+
+ sfi = 0;
+
+ memcpy(&sfi, value.getBuffer(), value.getLength());
+ }
+ }
+ break;
+
+ case 0x8A : /* life cycle status byte */
+ {
+ SCARD_DEBUG("0x%02X : life cycle status byte : %s", tlv.getTag(), tlv.getValue().toString());
+ if (tlv.getLength() > 0)
+ {
+ ByteArray value = tlv.getValue();
+
+ lcs = 0;
+
+ memcpy(&lcs, value.getBuffer(), value.getLength());
+ }
+ }
+ break;
+
+ case 0x8B : /* Security attribute referencing the expanded format */
+ {
+ SCARD_DEBUG("0x%02X : Security attribute referencing the expanded format : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0x8C : /* Security attribute in compact format */
+ {
+ SCARD_DEBUG("0x%02X : Security attribute in compact format : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0x8D : /* Identifier of an EF containing security environment templates */
+ {
+ SCARD_DEBUG("0x%02X : Identifier of an EF containing security environment templates : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0x8E : /* Channel security attribute */
+ {
+ SCARD_DEBUG("0x%02X : Channel security attribute : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0xA0 : /* Security attribute template for data objects */
+ {
+ SCARD_DEBUG("0x%02X : Security attribute template for data objects : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0xA1 : /* Security attribute template in proprietary format */
+ {
+ SCARD_DEBUG("0x%02X : Security attribute template in proprietary format : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0xA2 : /* Template consisting of one or more pairs of data objects */
+ {
+ SCARD_DEBUG("0x%02X : Template consisting of one or more pairs of data objects : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0xA5 : /* proprietary information encoded in BER-TLV */
+ {
+ SCARD_DEBUG("0x%02X : proprietary information encoded in BER-TLV : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0xAB : /* Security attribute template in expanded format */
+ {
+ SCARD_DEBUG("0x%02X : Security attribute template in expanded format : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0xAC : /* Cryptographic mechanism identifier template */
+ {
+ SCARD_DEBUG("0x%02X : Cryptographic mechanism identifier template : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ case 0xC6 : /* PIN status template DO */
+ {
+ SCARD_DEBUG("0x%02X : PIN status template DO : %s", tlv.getTag(), tlv.getValue().toString());
+ // ByteArray value = tlv.getValue();
+ }
+ break;
+
+ default :
+ {
+ SCARD_DEBUG("0x%02X : unknown : %s", tlv.getTag(), tlv.getValue().toString());
+ }
+ break;
+ }
+ }
+ tlv.returnToParentTLV();
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("tlv.decodeTLV failed");
+ }
+
+ SCARD_END();
+
+ return result;
+ }
+
+ ByteArray FCP::getFCP()
+ {
+ return fcpBuffer;
+ }
+
+ void FCP::releaseFCP()
+ {
+ fcpBuffer.releaseBuffer();
+
+ resetMemberVar();
+ }
+
+ unsigned int FCP::getFileSize()
+ {
+ return fileSize;
+ }
+
+ unsigned int FCP::getTotalFileSize()
+ {
+ return totalFileSize;
+ }
+
+ unsigned int FCP::getFID()
+ {
+ return fid;
+ }
+
+ unsigned int FCP::getSFI()
+ {
+ return sfi;
+ }
+
+ unsigned int FCP::getMaxRecordSize()
+ {
+ return maxRecordSize;
+ }
+
+ unsigned int FCP::getNumberOfRecord()
+ {
+ return numberOfRecord;
+ }
+
+ unsigned int FCP::getFileType()
+ {
+ return fileType;
+ }
+
+ unsigned int FCP::getFileStructure()
+ {
+ return fileStructure;
+ }
+
+ unsigned int FCP::getLCS()
+ {
+ return lcs;
+ }
+
+ const char *FCP::toString()
+ {
+ memset(strBuffer, 0, sizeof(strBuffer));
+
+ snprintf(strBuffer, sizeof(strBuffer), "size [%d], total size [%d], fid [%x], sfi [%x], max rec [%d], n of rec [%d], type [%d], struct [%d], lcs [%d]",
+ getFileSize(), getTotalFileSize(), getFID(), getSFI(), getMaxRecordSize(), getNumberOfRecord(), getFileType(), getFileStructure(), getLCS());
+
+ return (const char *)strBuffer;
+ }
+
+
+ /* FCM class method */
+ FCM::FCM()
+ {
+ }
+
+ FCM::~FCM()
+ {
+ }
+
+
+ /* FCI class method */
+ FCI::FCI()
+ {
+ }
+
+ FCI::~FCI()
+ {
+ }
+
+ bool FCI::setFCIBuffer(ByteArray array)
+ {
+ bool result = false;
+
+ return result;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "FileObject.h"
+#include "APDUHelper.h"
+
+namespace smartcard_service_api
+{
+ FileObject::FileObject(Channel *channel):ProviderHelper(channel)
+ {
+ }
+
+ FileObject::FileObject(Channel *channel, ByteArray selectResponse):ProviderHelper(channel)
+ {
+ setSelectResponse(selectResponse);
+ }
+
+ FileObject::~FileObject()
+ {
+ }
+
+ bool FileObject::setSelectResponse(ByteArray response)
+ {
+ bool result = false;
+
+ selectResponse = response;
+
+ if (selectResponse.getLength() > 2)
+ {
+ ResponseHelper resp(selectResponse);
+
+ fcp.setFCP(resp.getDataField());
+
+ result = true;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("invalid response : %s", selectResponse.toString());
+ }
+
+ return result;
+ }
+
+ int FileObject::select(ByteArray aid)
+ {
+ int ret = ERROR_ILLEGAL_STATE;
+ ByteArray command, result;
+ APDUHelper apdu;
+
+ if (channel == NULL || channel->isClosed())
+ {
+ SCARD_DEBUG_ERR("channel is not open");
+
+ return ret;
+ }
+
+ /* make apdu command */
+ command = apdu.generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, 0, aid);
+ SCARD_DEBUG("command : %s", command.toString());
+ ret = channel->transmitSync(command, result);
+
+ if (ret == 0 && result.getLength() >= 2)
+ {
+ ResponseHelper resp(result);
+ this->selectResponse = result;
+
+ if (resp.getStatus() == 0)
+ {
+ SCARD_DEBUG("response [%d] : %s", result.getLength(), result.toString());
+
+ fcp.releaseFCP();
+
+ if (result.getLength() > 2)
+ {
+ fcp.setFCP(resp.getDataField());
+
+ SCARD_DEBUG("FCP : %s", fcp.toString());
+ }
+
+ ret = SUCCESS;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, result.getLength());
+ }
+
+ return ret;
+ }
+
+ int FileObject::select(ByteArray path, bool fromCurrentDF)
+ {
+ int ret = ERROR_ILLEGAL_STATE;
+ ByteArray command, result;
+ APDUHelper apdu;
+
+ if (channel == NULL || channel->isClosed())
+ {
+ SCARD_DEBUG_ERR("channel is not open");
+
+ return ret;
+ }
+
+ /* make apdu command */
+ if (fromCurrentDF == true)
+ {
+ command = apdu.generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH_FROM_CURRENT_DF, 0, path);
+ }
+ else
+ {
+ command = apdu.generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH, 0, path);
+ }
+ SCARD_DEBUG("command : %s", command.toString());
+
+ ret = channel->transmitSync(command, result);
+
+ if (ret == 0 && result.getLength() >= 2)
+ {
+ ResponseHelper resp(result);
+ this->selectResponse = result;
+
+ if (resp.getStatus() == 0)
+ {
+ SCARD_DEBUG("response [%d] : %s", result.getLength(), result.toString());
+
+ fcp.releaseFCP();
+
+ if (result.getLength() > 2)
+ {
+ fcp.setFCP(resp.getDataField());
+
+ SCARD_DEBUG("FCP : %s", fcp.toString());
+ }
+
+ ret = SUCCESS;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, result.getLength());
+ }
+
+ return ret;
+ }
+
+ int FileObject::select(unsigned int fid)
+ {
+ int ret = ERROR_ILLEGAL_STATE;
+ ByteArray command, result, fidData((unsigned char *)&fid, 2);
+
+ if (channel == NULL || channel->isClosed())
+ {
+ SCARD_DEBUG_ERR("channel is not open");
+
+ return ret;
+ }
+
+ /* make apdu command */
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, fidData);
+ ret = channel->transmitSync(command, result);
+
+ if (ret == 0 && result.getLength() >= 2)
+ {
+ ResponseHelper resp(result);
+ this->selectResponse = result;
+
+ if (resp.getStatus() == 0)
+ {
+ SCARD_DEBUG("response [%d] : %s", result.getLength(), result.toString());
+
+ fcp.releaseFCP();
+
+ if (result.getLength() > 2)
+ {
+ fcp.setFCP(resp.getDataField());
+
+ SCARD_DEBUG("FCP : %s", fcp.toString());
+ }
+
+ ret = SUCCESS;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, result.getLength());
+ }
+
+ return ret;
+ }
+
+ int FileObject::selectParent()
+ {
+ int ret = ERROR_ILLEGAL_STATE;
+ ByteArray command, result;
+ APDUHelper apdu;
+
+ if (channel == NULL || channel->isClosed())
+ {
+ SCARD_DEBUG_ERR("channel is not open");
+
+ return ret;
+ }
+
+ /* make apdu command */
+ command = apdu.generateAPDU(APDUHelper::COMMAND_SELECT_PARENT_DF, 0, ByteArray::EMPTY);
+ SCARD_DEBUG("command : %s", command.toString());
+
+ ret = channel->transmitSync(command, result);
+
+ if (ret == 0 && result.getLength() >= 2)
+ {
+ ResponseHelper resp(result);
+ this->selectResponse = result;
+
+ if (resp.getStatus() == 0)
+ {
+ SCARD_DEBUG("response [%d] : %s", result.getLength(), result.toString());
+
+ fcp.releaseFCP();
+
+ if (result.getLength() > 2)
+ {
+ fcp.setFCP(resp.getDataField());
+
+ SCARD_DEBUG("FCP : %s", fcp.toString());
+ }
+
+ ret = SUCCESS;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, result.getLength());
+ }
+
+ return ret;
+ }
+
+ FCI *FileObject::getFCI()
+ {
+ return NULL;
+ }
+
+ FCP *FileObject::getFCP()
+ {
+ return &fcp;
+ }
+
+ int FileObject::readRecord(unsigned int sfi, unsigned int recordId, Record &result)
+ {
+ ByteArray command, response;
+ APDUCommand apdu;
+ int ret;
+
+ apdu.setCommand(0, APDUCommand::INS_READ_RECORD, recordId, 4, ByteArray::EMPTY, 0);
+ apdu.getBuffer(command);
+ SCARD_DEBUG("command : %s", command.toString());
+
+ ret = channel->transmitSync(command, response);
+ if (ret == 0 && response.getLength() >= 2)
+ {
+ ResponseHelper resp(response);
+
+ if (resp.getStatus() == 0)
+ {
+ SCARD_DEBUG("response [%d] : %s", response.getLength(), response.toString());
+
+// result = resp.getDataField();
+
+ ret = SUCCESS;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), response[response.getLength() - 2], response[response.getLength() - 1]);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, response.getLength());
+ }
+
+ return ret;
+ }
+
+ int FileObject::writeRecord(unsigned int sfi, Record record)
+ {
+ return 0;
+ }
+
+ int FileObject::searchRecord(unsigned int sfi, ByteArray searchParam, vector<int> &result)
+ {
+ return 0;
+ }
+
+ int FileObject::readBinary(unsigned int sfi, unsigned int offset, unsigned int length, ByteArray &result)
+ {
+ ByteArray command, response;
+ APDUCommand apdu;
+ int ret;
+
+ apdu.setCommand(0, APDUCommand::INS_READ_BINARY, offset, 0, ByteArray::EMPTY, length);
+ apdu.getBuffer(command);
+ SCARD_DEBUG("command : %s", command.toString());
+
+ ret = channel->transmitSync(command, response);
+ if (ret == 0 && response.getLength() >= 2)
+ {
+ ResponseHelper resp(response);
+
+ if (resp.getStatus() == 0)
+ {
+ SCARD_DEBUG("response [%d] : %s", response.getLength(), response.toString());
+
+ result = resp.getDataField();
+
+ ret = SUCCESS;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), response[response.getLength() - 2], response[response.getLength() - 1]);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, response.getLength());
+ }
+
+ return ret;
+ }
+
+ int FileObject::writeBinary(unsigned int sfi, ByteArray data, unsigned int offset, unsigned int length)
+ {
+ ByteArray command, response;
+ APDUCommand apdu;
+ int ret;
+
+ apdu.setCommand(0, APDUCommand::INS_WRITE_BINARY, offset, 0, data, 0);
+ apdu.getBuffer(command);
+ SCARD_DEBUG("command : %s", command.toString());
+
+ ret = channel->transmitSync(command, response);
+ if (ret == 0 && response.getLength() >= 2)
+ {
+ ResponseHelper resp(response);
+
+ if (resp.getStatus() == 0)
+ {
+ SCARD_DEBUG("response [%d] : %s", response.getLength(), response.toString());
+
+ ret = SUCCESS;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), response[response.getLength() - 2], response[response.getLength() - 1]);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, response.getLength());
+ }
+
+ return ret;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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(Channel *channel):AccessControlList(channel)
+ {
+ this->channel = channel;
+
+ if (channel->getSelectResponse().isEmpty() == true)
+ {
+ pkcs15 = new PKCS15(channel);
+ }
+ else
+ {
+ pkcs15 = new PKCS15(channel, channel->getSelectResponse());
+ }
+ }
+
+ GPSEACL::~GPSEACL()
+ {
+ if (pkcs15 != NULL)
+ {
+ delete pkcs15;
+ }
+ }
+
+ int GPSEACL::loadACL()
+ {
+ ByteArray aid, certHash;
+ PKCS15ODF *odf;
+
+ if ((odf = pkcs15->getODF()) != NULL)
+ {
+ PKCS15DODF *dodf;
+
+ if ((dodf = odf->getDODF()) != NULL)
+ {
+ loadAccessControl(dodf);
+
+ printAccessControlList();
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("dodf null");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("odf null");
+ }
+
+ return 0;
+ }
+
+ int GPSEACL::loadAccessControl(PKCS15DODF *dodf)
+ {
+ ByteArray path;
+
+ if (dodf->searchOID(OID_GLOBALPLATFORM, path) == 0)
+ {
+ ByteArray data;
+ FileObject file(channel);
+
+ SCARD_DEBUG("oid path : %s", path.toString());
+
+ file.select(NumberStream::getLittleEndianNumber(path));
+ file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
+
+ SCARD_DEBUG("data : %s", data.toString());
+
+ SimpleTLV tlv(data);
+
+ if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : AccessControlMainFile */
+ {
+ tlv.enterToValueTLV();
+
+ /* refresh Tag */
+ ByteArray refreshTag;
+
+ refreshTag = SimpleTLV::getOctetString(tlv);
+ SCARD_DEBUG("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());
+ SCARD_DEBUG("access control rule path : %s", path.toString());
+
+ if (loadRules(path) == 0)
+ {
+ SCARD_DEBUG("loadRules success");
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("loadRules failed");
+ }
+ }
+ }
+ tlv.returnToParentTLV();
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("tlv.decodeTLV failed");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("search failed");
+ }
+
+ return 0;
+ }
+
+ int GPSEACL::loadRules(ByteArray path)
+ {
+ FileObject file(channel);
+ ByteArray data, aid;
+
+ file.select(NumberStream::getLittleEndianNumber(path));
+ file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
+
+ SCARD_DEBUG("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;
+ }
+
+ SCARD_DEBUG("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());
+ SCARD_DEBUG("path : %s", path.toString());
+
+ if (loadAccessConditions(aid, path) == 0)
+ {
+ SCARD_DEBUG("loadCertHashes success");
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("loadCertHashes failed");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("decodeTLV failed");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("decodeTLV failed");
+ }
+ tlv.returnToParentTLV();
+ }
+
+ return 0;
+ }
+
+ int GPSEACL::loadAccessConditions(ByteArray aid, ByteArray path)
+ {
+ FileObject file(channel);
+ ByteArray data;
+
+ file.select(NumberStream::getLittleEndianNumber(path));
+ file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
+
+ SCARD_DEBUG("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 \
+ { \
+ SCARD_DEBUG_ERR("Invalid param"); \
+ }
+
+using namespace smartcard_service_api;
+
+EXTERN_API gp_se_acl_h gp_se_acl_create_instance(channel_h channel)
+{
+ GPSEACL *acl = new GPSEACL((Channel *)channel);
+
+ return (gp_se_acl_h)acl;
+}
+
+EXTERN_API int gp_se_acl_load_acl(gp_se_acl_h handle)
+{
+ int result = -1;
+
+ GP_SE_ACL_EXTERN_BEGIN;
+ result = acl->loadACL();
+ GP_SE_ACL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int gp_se_acl_update_acl(gp_se_acl_h handle)
+{
+ int result = -1;
+
+ GP_SE_ACL_EXTERN_BEGIN;
+ acl->updateACL();
+ 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;
+}
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/socket.h>
+#ifdef USE_UNIX_DOMAIN
+#include <sys/un.h>
+#include <sys/stat.h>
+#else /* USE_UNIX_DOMAIN */
+#include <netinet/in.h>
+#endif /* USE_UNIX_DOMAIN */
+#include <fcntl.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "IPCHelper.h"
+
+#ifdef USE_UNIX_DOMAIN
+#define OMAPI_SERVER_DOMAIN "/tmp/omapi-server-domain"
+#endif /* USE_UNIX_DOMAIN */
+
+static void setNonBlockSocket(int socket)
+{
+ int flags;
+
+ flags = fcntl(socket, F_GETFL);
+
+ flags |= O_NONBLOCK;
+
+ if (fcntl(socket, F_SETFL, flags) < 0)
+ {
+ /* SCARD_DEBUG_ERR("fcntl, executing nonblock error"); */
+ }
+}
+
+namespace smartcard_service_api
+{
+ IPCHelper::IPCHelper()
+ {
+ ipcSocket = -1;
+ ioChannel = NULL;
+ watchId = 0;
+ memset(&ipcLock, 0, sizeof(ipcLock));
+ dispatcher = NULL;
+ }
+
+ IPCHelper::~IPCHelper()
+ {
+ }
+
+ gboolean IPCHelper::channelCallbackFunc(GIOChannel* channel, GIOCondition condition, gpointer data)
+ {
+ IPCHelper *helper = (IPCHelper *)data;
+ gboolean result = FALSE;
+
+ SCARD_DEBUG("channel [%p], condition [%d], data [%p]", channel, condition, data);
+
+ if (helper == NULL)
+ {
+ SCARD_DEBUG_ERR("ipchelper is null");
+ return result;
+ }
+
+ if ((G_IO_ERR & condition) || (G_IO_HUP & condition))
+ {
+ result = helper->handleIOErrorCondition(channel, condition);
+ }
+ else if (G_IO_NVAL & condition)
+ {
+ result = helper->handleInvalidSocketCondition(channel, condition);
+ }
+ else if (G_IO_IN & condition)
+ {
+ result = helper->handleIncomingCondition(channel, condition);
+ }
+
+ return result;
+ }
+
+ bool IPCHelper::createListenSocket()
+ {
+ GIOCondition condition = (GIOCondition)(G_IO_ERR | G_IO_HUP | G_IO_IN);
+ struct sockaddr_un saddrun_rv;
+
+ if (ipcSocket >= 0)
+ return true;
+
+ memset(&saddrun_rv, 0, sizeof(struct sockaddr_un));
+
+ unlink(OMAPI_SERVER_DOMAIN);
+
+ ipcSocket = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (ipcSocket == -1)
+ {
+ SCARD_DEBUG_ERR("get socket is failed");
+ return false;
+ }
+
+ ::setNonBlockSocket(ipcSocket);
+
+ saddrun_rv.sun_family = AF_UNIX;
+ strncpy(saddrun_rv.sun_path, OMAPI_SERVER_DOMAIN, sizeof(saddrun_rv.sun_path) - 1);
+
+ if (bind(ipcSocket, (struct sockaddr *)&saddrun_rv, sizeof(saddrun_rv)) < 0)
+ {
+ SCARD_DEBUG_ERR("bind is failed \n");
+ goto ERROR;
+ }
+
+ if (chmod(OMAPI_SERVER_DOMAIN, 0777) < 0)
+ {
+ SCARD_DEBUG_ERR("can not change permission of UNIX DOMAIN file");
+ goto ERROR;
+ }
+
+ if (listen(ipcSocket, IPC_SERVER_MAX_CLIENT) < 0)
+ {
+ SCARD_DEBUG_ERR("listen is failed \n");
+ goto ERROR;
+ }
+
+ if ((ioChannel = g_io_channel_unix_new(ipcSocket)) != NULL)
+ {
+ if ((watchId = g_io_add_watch(ioChannel, condition, &IPCHelper::channelCallbackFunc, this)) < 1)
+ {
+ SCARD_DEBUG_ERR(" g_io_add_watch is failed \n");
+ goto ERROR;
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR(" g_io_channel_unix_new is failed \n");
+ goto ERROR;
+ }
+
+#ifdef SECURITY_SERVER
+ gid = security_server_get_gid(NET_NFC_MANAGER_OBJECT);
+ if(gid == 0)
+ {
+ SCARD_DEBUG("get gid from security server is failed. this object is not allowed by security server");
+ goto ERROR;
+ }
+
+ if((cookies_size = security_server_get_cookie_size()) != 0)
+ {
+ if((cookies = (char *)calloc(1, cookies_size)) == NULL)
+ {
+ goto ERROR;
+ }
+ }
+#endif
+
+ SCARD_DEBUG("server ipc is initialized");
+
+ return true;
+ERROR :
+ if (watchId != (uint32_t)-1)
+ {
+ g_source_remove(watchId);
+ watchId = -1;
+ }
+
+ if (ioChannel != NULL)
+ {
+ g_io_channel_unref(ioChannel);
+ ioChannel = NULL;
+ }
+
+ if (ipcSocket != -1)
+ {
+ shutdown(ipcSocket, SHUT_RDWR);
+ close(ipcSocket);
+
+ ipcSocket = -1;
+ }
+
+ return false;
+ }
+
+ bool IPCHelper::createConnectSocket()
+ {
+ GIOCondition condition = (GIOCondition) (G_IO_ERR | G_IO_HUP | G_IO_IN);
+
+ SCARD_BEGIN();
+
+ if (ipcSocket >= 0)
+ return true;
+
+ pthread_mutex_lock(&ipcLock);
+
+ struct sockaddr_un saddrun_rv;
+ socklen_t len_saddr = 0;
+
+ memset(&saddrun_rv, 0, sizeof(struct sockaddr_un));
+
+ ipcSocket = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (ipcSocket == -1)
+ {
+ SCARD_DEBUG_ERR("get socket is failed \n");
+ pthread_mutex_unlock(&ipcLock);
+
+ SCARD_END();
+
+ return false;
+ }
+
+ SCARD_DEBUG("socket is created");
+
+ ::setNonBlockSocket(ipcSocket);
+
+ saddrun_rv.sun_family = AF_UNIX;
+ strncpy(saddrun_rv.sun_path, OMAPI_SERVER_DOMAIN, sizeof(saddrun_rv.sun_path) - 1);
+
+ len_saddr = sizeof(saddrun_rv.sun_family) + strlen(OMAPI_SERVER_DOMAIN);
+
+ if ((connect(ipcSocket, (struct sockaddr *)&saddrun_rv, len_saddr)) < 0)
+ {
+ SCARD_DEBUG_ERR("error is occured");
+ pthread_mutex_unlock(&ipcLock);
+ goto ERROR;
+ }
+
+ pthread_mutex_unlock(&ipcLock);
+
+ if ((ioChannel = g_io_channel_unix_new(ipcSocket)) != NULL)
+ {
+ if ((watchId = g_io_add_watch(ioChannel, condition, &IPCHelper::channelCallbackFunc, this)) < 1)
+ {
+ SCARD_DEBUG_ERR(" g_io_add_watch is failed \n");
+ goto ERROR;
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR(" g_io_channel_unix_new is failed \n");
+ goto ERROR;
+ }
+
+ SCARD_DEBUG("socket and g io channel is binded");
+
+ SCARD_END();
+
+ return true;
+
+ERROR :
+ SCARD_DEBUG_ERR("error while initializing client ipc");
+
+ if(watchId != 0)
+ {
+ g_source_remove(watchId);
+ watchId = 0;
+ }
+
+ if(ioChannel != NULL)
+ {
+ g_io_channel_unref(ioChannel);
+ ioChannel = NULL;
+ }
+
+ if (ipcSocket != -1)
+ {
+ shutdown(ipcSocket, SHUT_RDWR);
+ close(ipcSocket);
+ ipcSocket = -1;
+ }
+
+ SCARD_END();
+
+ return false;
+ }
+
+ bool IPCHelper::sendMessage(Message *msg)
+ {
+ if (ipcSocket == -1)
+ return false;
+
+ return sendMessage(ipcSocket, msg);
+ }
+
+ bool IPCHelper::sendMessage(int socket, Message *msg)
+ {
+ bool result = false;
+ ByteArray stream;
+ unsigned int length = 0;
+
+ stream = msg->serialize();
+ length = stream.getLength();
+
+ SCARD_DEBUG(">>>[SEND]>>> socket [%d], msg [%d], length [%d]", socket, msg->message, length);
+
+ if (length > 0)
+ {
+ int sentBytes = 0;
+
+ /* send 4 bytes (length) */
+ pthread_mutex_lock(&ipcLock);
+ sentBytes = send(socket, &length, sizeof(length), 0);
+ pthread_mutex_unlock(&ipcLock);
+ if (sentBytes == sizeof(length))
+ {
+ unsigned int current = 0;
+
+ /* send message */
+ pthread_mutex_lock(&ipcLock);
+ do
+ {
+ sentBytes = send(socket, stream.getBuffer(current), length - current, 0);
+ if (sentBytes > 0)
+ current += sentBytes;
+ }
+ while (current < length);
+ pthread_mutex_unlock(&ipcLock);
+
+ result = true;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("send failed, sentBytes [%d]", sentBytes);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("stream length is zero");
+ }
+
+ return result;
+ }
+
+ Message *IPCHelper::retrieveMessage()
+ {
+ return retrieveMessage(ipcSocket);
+ }
+
+ Message *IPCHelper::retrieveMessage(int socket)
+ {
+ Message *msg = NULL;
+ unsigned int length = 0;
+ int readBytes = 0;
+
+ SCARD_BEGIN();
+
+ /* read 4 bytes (length) */
+ pthread_mutex_lock(&ipcLock);
+ readBytes = recv(socket, &length, sizeof(length), 0);
+ pthread_mutex_unlock(&ipcLock);
+ if (readBytes == sizeof(length))
+ {
+ if (length > 0)
+ {
+ unsigned char *buffer = NULL;
+
+ /* prepare buffer */
+ buffer = new unsigned char[length];
+ if (buffer != NULL)
+ {
+ int retry = 0;
+ unsigned int current = 0;
+
+ /* read message */
+ pthread_mutex_lock(&ipcLock);
+ do
+ {
+ readBytes = recv(socket, buffer + current, length - current, 0);
+ if (readBytes > 0)
+ current += readBytes;
+ retry++;
+ }
+ while (current < length);
+ pthread_mutex_unlock(&ipcLock);
+
+ msg = new Message();
+ if (msg != NULL)
+ {
+ msg->deserialize(buffer, length);
+
+ SCARD_DEBUG("<<<[RETRIEVE]<<< socket [%d], msg_length [%d]", socket, length);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ }
+
+ delete []buffer;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("allocation failed");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("invalid length, socket = [%d], msg_length = [%d]", socket, length);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("failed to recv length, socket = [%d], readBytes [%d]", socket, readBytes);
+ }
+
+
+ SCARD_END();
+
+ return msg;
+ }
+
+ void IPCHelper::setDispatcher(DispatcherHelper *dispatcher)
+ {
+ this->dispatcher = dispatcher;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "ISO7816BERTLV.h"
+
+namespace smartcard_service_api
+{
+ ISO7816BERTLV::ISO7816BERTLV():TLVHelper()
+ {
+ tagClass = 0;
+ encoding = 0;
+ }
+
+ ISO7816BERTLV::ISO7816BERTLV(TLVHelper *parent):TLVHelper(parent)
+ {
+ parentTLV = parent;
+
+ tagClass = 0;
+ encoding = 0;
+ }
+
+ ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array):TLVHelper(array)
+ {
+ tagClass = 0;
+ encoding = 0;
+ }
+
+ ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array, TLVHelper *parent):TLVHelper(array, parent)
+ {
+ parentTLV = parent;
+
+ tagClass = 0;
+ encoding = 0;
+ }
+
+ ISO7816BERTLV::~ISO7816BERTLV()
+ {
+ if (childTLV != NULL)
+ {
+ delete childTLV;
+ childTLV = NULL;
+ }
+ }
+
+ int ISO7816BERTLV::decodeTag(unsigned char *buffer)
+ {
+ /* 0x00 is invalid tag value */
+ if (buffer[0] == 0x00)
+ {
+ return -1;
+ }
+
+ /* first byte */
+ tagClass = (buffer[0] & 0xE0) >> 6;
+ encoding = (buffer[0] & 0x20) >> 5;
+
+ currentT = buffer[0];
+
+ if ((buffer[0] & 0x1F) < 0x1F)
+ {
+ return 1;
+ }
+
+ /* second byte */
+ currentT = (currentT << 8) | buffer[1];
+ if (buffer[1] & 0x80)
+ {
+ /* third byte */
+ if (buffer[2] & 0x80)
+ {
+ return -1;
+ }
+
+ currentT = (currentT << 8) | buffer[2];
+
+ return 3;
+ }
+
+ return 2;
+ }
+
+ int ISO7816BERTLV::decodeLength(unsigned char *buffer)
+ {
+ if (buffer[0] & 0x80)
+ {
+ uint8_t count = (buffer[0] & 0x7F);
+ uint8_t i;
+
+ /* count will be less than 5 */
+ if (count > 4)
+ return -1;
+
+ count++; /* increse count and increase i value, too */
+
+ for (i = 1; i < count; i++)
+ {
+ /* if big endian */
+ currentL = (currentL << 8) | buffer[i];
+
+ /* if little endian */
+ /* currentL = currentL | (buffer[i] << (8 * (i - 1))); */
+ }
+
+ return count;
+ }
+ else
+ {
+ currentL = buffer[0];
+
+ return 1;
+ }
+ }
+
+ int ISO7816BERTLV::decodeValue(unsigned char *buffer)
+ {
+ if (currentL == 0)
+ return 0;
+
+ currentV.setBuffer(buffer, currentL);
+
+ return currentL;
+ }
+
+ unsigned int ISO7816BERTLV::getClass()
+ {
+ return tagClass;
+ }
+
+ unsigned int ISO7816BERTLV::getEncoding()
+ {
+ return encoding;
+ }
+
+ ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, ByteArray buffer)
+ {
+ unsigned char temp_tag[3] = { 0, };
+ unsigned char temp_tag_len = 0;
+ unsigned char temp_len[5] = { 0, };
+ unsigned char temp_len_len = 0;
+ ByteArray result;
+ unsigned int total_len = 0;
+ unsigned int current = 0;
+ unsigned char *temp_buffer = NULL;
+
+ /* add tag's length */
+ if (tag > 0x7FFF)
+ return result;
+
+ temp_tag[0] = (tagClass << 6) | (encoding << 5);
+
+ if (tag < 0x1F)
+ {
+ temp_tag[0] |= tag;
+ temp_tag_len = 1;
+ }
+ else
+ {
+ temp_tag[0] |= 0x1F;
+
+ if (tag < 0x80)
+ {
+ temp_tag[1] = tag;
+
+ temp_tag_len = 2;
+ }
+ else
+ {
+ temp_tag[1] = (tag & 0x000000FF);
+ temp_tag[2] = (tag & 0x0000FF00);
+
+ temp_tag_len = 3;
+ }
+ }
+
+ total_len += temp_tag_len;
+
+ /* add length's length */
+ if (buffer.getLength() < 128)
+ {
+ temp_len[0] = buffer.getLength();
+
+ temp_len_len = 1;
+ }
+ else
+ {
+ temp_len[0] = 0x80;
+ temp_len_len = 1;
+
+ if (buffer.getLength() > 0x00FFFFFF)
+ {
+ temp_len[4] = (buffer.getLength() & 0xFF000000) >> 24;
+ temp_len_len++;
+ }
+
+ if (buffer.getLength() > 0x0000FFFF)
+ {
+ temp_len[3] = (buffer.getLength() & 0x00FF0000) >> 16;
+ temp_len_len++;
+ }
+
+ if (buffer.getLength() > 0x000000FF)
+ {
+ temp_len[2] = (buffer.getLength() & 0x0000FF00) >> 8;
+ temp_len_len++;
+ }
+
+ temp_len[1] = buffer.getLength() & 0x000000FF;
+ temp_len_len++;
+
+ temp_len[0] |= temp_len_len;
+ }
+
+ /* add buffer's length */
+ total_len += buffer.getLength();
+
+ /* alloc new buffer */
+ temp_buffer = new unsigned char[total_len];
+ if (temp_buffer == NULL)
+ {
+ return result;
+ }
+ memset(temp_buffer, 0, total_len);
+
+ /* fill tag */
+ memcpy(temp_buffer + current, temp_tag, temp_tag_len);
+ current += temp_tag_len;
+
+ /* fill length */
+ memcpy(temp_buffer + current, temp_len, temp_len_len);
+ current += temp_len_len;
+
+ /* fill value */
+ if (buffer.getLength() > 0)
+ memcpy(temp_buffer + current, buffer.getBuffer(), buffer.getLength());
+
+ result.setBuffer(temp_buffer, total_len);
+
+ delete []temp_buffer;
+
+ return result;
+ }
+
+ ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, unsigned char *buffer, unsigned int length)
+ {
+ return encode(tagClass, encoding, tag, ByteArray(buffer, length));
+ }
+
+ TLVHelper *ISO7816BERTLV::getChildTLV(ByteArray data)
+ {
+ if (childTLV != NULL)
+ {
+ delete childTLV;
+ childTLV = NULL;
+ }
+ childTLV = new ISO7816BERTLV(data, this);
+
+ return (TLVHelper *)childTLV;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Message.h"
+
+namespace smartcard_service_api
+{
+ Message::Message()
+ {
+ message = 0;
+ param1 = 0;
+ param2 = 0;
+ error = 0;
+ caller = NULL;
+ callback = NULL;
+ userParam = NULL;
+ }
+
+ Message::~Message()
+ {
+ }
+
+ ByteArray Message::serialize()
+ {
+ ByteArray result;
+ unsigned int length = 0;
+ unsigned int dataLength = 0;
+ unsigned char *buffer = NULL;
+
+ length = sizeof(message) + sizeof(param1) + sizeof(param2) + sizeof(error) + sizeof(caller) + sizeof(callback) + sizeof(userParam);
+ if (data.getLength() > 0)
+ {
+ dataLength = data.getLength();
+ length += sizeof(dataLength) + data.getLength();
+ }
+
+ buffer = new unsigned char[length];
+ if (buffer != NULL)
+ {
+ unsigned int current = 0;
+
+ memset(buffer, 0, length);
+
+ memcpy(buffer + current, &message, sizeof(message));
+ current += sizeof(message);
+
+ memcpy(buffer + current, ¶m1, sizeof(param1));
+ current += sizeof(param1);
+
+ memcpy(buffer + current, ¶m2, sizeof(param2));
+ current += sizeof(param2);
+
+ memcpy(buffer + current, &error, sizeof(error));
+ current += sizeof(error);
+
+ memcpy(buffer + current, &caller, sizeof(caller));
+ current += sizeof(caller);
+
+ memcpy(buffer + current, &callback, sizeof(callback));
+ current += sizeof(callback);
+
+ memcpy(buffer + current, &userParam, sizeof(userParam));
+ current += sizeof(userParam);
+
+ if (data.getLength() > 0)
+ {
+ memcpy(buffer + current, &dataLength, sizeof(dataLength));
+ current += sizeof(dataLength);
+
+ memcpy(buffer + current, data.getBuffer(), dataLength);
+ current += data.getLength();
+ }
+
+ result.setBuffer(buffer, length);
+
+ delete []buffer;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("allocation failed");
+ }
+
+ return result;
+ }
+
+ void Message::deserialize(ByteArray buffer)
+ {
+ deserialize(buffer.getBuffer(), buffer.getLength());
+ }
+
+ void Message::deserialize(unsigned char *buffer, unsigned int length)
+ {
+ unsigned int current = 0;
+ unsigned int dataLength = 0;
+
+// SCARD_DEBUG("buffer [%p], length [%d]", buffer, length);
+
+ memcpy(&message, buffer + current, sizeof(message));
+ current += sizeof(message);
+
+// SCARD_DEBUG("message [%d]", message);
+
+ memcpy(¶m1, buffer + current, sizeof(param1));
+ current += sizeof(param1);
+
+// SCARD_DEBUG("param1 [%d]", param1);
+
+ memcpy(¶m2, buffer + current, sizeof(param2));
+ current += sizeof(param2);
+
+// SCARD_DEBUG("param2 [%d]", param2);
+
+ memcpy(&error, buffer + current, sizeof(error));
+ current += sizeof(error);
+
+ memcpy(&caller, buffer + current, sizeof(caller));
+ current += sizeof(caller);
+
+ memcpy(&callback, buffer + current, sizeof(callback));
+ current += sizeof(callback);
+
+ memcpy(&userParam, buffer + current, sizeof(userParam));
+ current += sizeof(userParam);
+
+// SCARD_DEBUG("userContext [%p]", userContext);
+
+ if (current + sizeof(dataLength) < length)
+ {
+ memcpy(&dataLength, buffer + current, sizeof(dataLength));
+ current += sizeof(dataLength);
+
+// SCARD_DEBUG("dataLength [%d]", dataLength);
+
+ data.setBuffer(buffer + current, dataLength);
+ current += dataLength;
+ }
+ }
+
+ const char *Message::toString()
+ {
+ const char *msg = NULL;
+
+ memset(&text, 0, sizeof(text));
+
+ switch (message)
+ {
+ case MSG_REQUEST_READERS :
+ msg = "MSG_REQUEST_READERS";
+ break;
+
+// case MSG_REQUEST_READER_NAME :
+// msg = "MSG_REQUEST_READER_NAME";
+// break;
+//
+ case MSG_REQUEST_OPEN_SESSION :
+ msg = "MSG_REQUEST_OPEN_SESSION";
+ break;
+
+ case MSG_REQUEST_CLOSE_SESSION :
+ msg = "MSG_REQUEST_CLOSE_CHANNEL";
+ break;
+
+ case MSG_REQUEST_OPEN_CHANNEL :
+ msg = "MSG_REQUEST_OPEN_CHANNEL";
+ break;
+
+ case MSG_REQUEST_CLOSE_CHANNEL :
+ msg = "MSG_REQUEST_CLOSE_CHANNEL";
+ break;
+
+ case MSG_REQUEST_GET_ATR :
+ msg = "MSG_REQUEST_GET_ATR";
+ break;
+
+ case MSG_REQUEST_TRANSMIT :
+ msg = "MSG_REQUEST_TRANSMIT";
+ break;
+
+ case MSG_REQUEST_GET_CHANNEL_COUNT :
+ msg = "MSG_REQUEST_GET_CHANNEL_COUNT";
+ break;
+
+ default :
+ msg = "Unknown";
+ break;
+ }
+
+ snprintf(text, sizeof(text), "Message [%s, %d], param1 [%d], param2 [%d], error [%d], caller [%p], callback [%p], userParam [%p], data length [%d]", msg, message, param1, param2, error, caller, callback, userParam, data.getLength());
+
+ return (const char *)text;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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.
+*/
+
+
+#include "NumberStream.h"
+
+namespace smartcard_service_api
+{
+ NumberStream::NumberStream(const ByteArray &T)
+ {
+ setBuffer(T.getBuffer(), T.getLength());
+ }
+
+ unsigned int NumberStream::getBigEndianNumber()
+ {
+ return getBigEndianNumber(*this);
+ }
+
+ unsigned int NumberStream::getLittleEndianNumber()
+ {
+ return getLittleEndianNumber(*this);
+ }
+
+ NumberStream &NumberStream::operator =(const ByteArray &T)
+ {
+ if (this != &T)
+ {
+ setBuffer(T.getBuffer(), T.getLength());
+ }
+
+ return *this;
+ }
+
+ NumberStream &NumberStream::operator =(const NumberStream &T)
+ {
+ if (this != &T)
+ {
+ setBuffer(T.getBuffer(), T.getLength());
+ }
+
+ return *this;
+ }
+
+ unsigned int NumberStream::getBigEndianNumber(const ByteArray &T)
+ {
+ int i, len;
+ unsigned int result = 0;
+
+ len = (T.getLength() < 4) ? T.getLength() : 4;
+
+ for (i = 0; i < len; i++)
+ {
+ result = (result << 8) | T.getAt(i);
+ }
+
+ return result;
+ }
+
+ unsigned int NumberStream::getLittleEndianNumber(const ByteArray &T)
+ {
+ int i, len;
+ unsigned int result = 0;
+
+ len = (T.getLength() < 4) ? T.getLength() : 4;
+
+ for (i = 0; i < len; i++)
+ {
+ result = result | (T.getAt(i) << (i * 8));
+ }
+
+ return result;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+#include <openssl/buffer.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ByteArray.h"
+#include "OpensslHelper.h"
+
+namespace smartcard_service_api
+{
+ bool OpensslHelper::encodeBase64String(const ByteArray &buffer, ByteArray &result, bool newLineChar)
+ {
+ bool ret = false;
+ BUF_MEM *bptr;
+ BIO *b64, *bmem;
+
+ if (buffer.getLength() == 0)
+ {
+ return ret;
+ }
+
+ b64 = BIO_new(BIO_f_base64());
+ bmem = BIO_new(BIO_s_mem());
+
+ if (newLineChar == false)
+ BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+
+ b64 = BIO_push(b64, bmem);
+
+ BIO_write(b64, buffer.getBuffer(), buffer.getLength());
+ BIO_flush(b64);
+ BIO_get_mem_ptr(b64, &bptr);
+
+ result.setBuffer((unsigned char *)bptr->data, bptr->length);
+
+ BIO_free_all(b64);
+
+ ret = true;
+
+ return ret;
+ }
+
+ bool OpensslHelper::decodeBase64String(const char *buffer, ByteArray &result, bool newLineChar)
+ {
+ ByteArray temp;
+
+ temp.setBuffer((unsigned char *)buffer, strlen(buffer));
+
+ return decodeBase64String(temp, result, newLineChar);
+ }
+
+ bool OpensslHelper::decodeBase64String(const ByteArray &buffer, ByteArray &result, bool newLineChar)
+ {
+ bool ret = false;
+ unsigned int length = 0;
+ char *temp;
+
+ if (buffer.getBuffer() == NULL || buffer.getLength() == 0)
+ {
+ return ret;
+ }
+
+ length = buffer.getLength();
+
+ temp = new char[length];
+ if (temp != NULL)
+ {
+ BIO *b64, *bmem;
+
+ memset(temp, 0, length);
+
+ b64 = BIO_new(BIO_f_base64());
+ bmem = BIO_new_mem_buf(buffer.getBuffer(), length);
+ if (newLineChar == false)
+ BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+ bmem = BIO_push(b64, bmem);
+
+ length = BIO_read(bmem, temp, length);
+
+ BIO_free_all(bmem);
+
+ result.setBuffer((unsigned char *)temp, length);
+
+ delete []temp;
+
+ ret = true;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ }
+
+ return ret;
+ }
+
+ bool OpensslHelper::digestBuffer(const char *algorithm, const uint8_t *buffer, const uint32_t length, ByteArray &result)
+ {
+ ByteArray temp((uint8_t *)buffer, (uint32_t)length);
+
+ return digestBuffer(algorithm, temp, result);
+ }
+
+ bool OpensslHelper::digestBuffer(const char *algorithm, const ByteArray &buffer, ByteArray &result)
+ {
+ const EVP_MD *md;
+ unsigned char *temp;
+ bool ret = false;
+
+ if (algorithm == NULL || buffer.getLength() == 0)
+ {
+ return ret;
+ }
+
+ OpenSSL_add_all_digests();
+
+ if ((md = EVP_get_digestbyname(algorithm)) != NULL)
+ {
+ temp = new unsigned char[EVP_MAX_MD_SIZE];
+ if (temp != NULL)
+ {
+ EVP_MD_CTX mdCtx;
+ unsigned int resultLen = 0;
+
+ memset(temp, 0, EVP_MAX_MD_SIZE);
+
+ EVP_DigestInit(&mdCtx, md);
+ EVP_DigestUpdate(&mdCtx, buffer.getBuffer(), buffer.getLength());
+ EVP_DigestFinal(&mdCtx, temp, &resultLen);
+
+ result.setBuffer(temp, resultLen);
+
+ delete []temp;
+
+ ret = true;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("EVP_get_digestbyname(\"%s\") returns NULL", algorithm);
+ }
+
+ return ret;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "PKCS15.h"
+
+namespace smartcard_service_api
+{
+ static unsigned char aid[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
+ ByteArray PKCS15::PKCS15_AID(ARRAY_AND_SIZE(aid));
+
+ PKCS15::PKCS15(Channel *channel):PKCS15Object(channel), odf(NULL)
+ {
+ int ret = 0;
+
+ if ((ret = select(PKCS15::PKCS15_AID)) == 0)
+ {
+ SCARD_DEBUG("response : %s", selectResponse.toString());
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select failed, [%d]", ret);
+ }
+ }
+
+ PKCS15::PKCS15(Channel *channel, ByteArray selectResponse):PKCS15Object(channel, selectResponse), odf(NULL)
+ {
+ }
+
+ PKCS15::~PKCS15()
+ {
+ if (odf != NULL)
+ {
+ delete odf;
+ odf = NULL;
+ }
+ }
+
+ PKCS15ODF *PKCS15::getODF()
+ {
+ if (odf == NULL)
+ {
+ odf = new PKCS15ODF(channel);
+ }
+
+ SCARD_DEBUG("odf [%p]", odf);
+
+ return odf;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "PKCS15DODF.h"
+#include "SimpleTLV.h"
+
+namespace smartcard_service_api
+{
+// PKCS15DODF::PKCS15DODF():PKCS15Object()
+// {
+//
+// }
+
+ PKCS15DODF::PKCS15DODF(unsigned int fid, Channel *channel):PKCS15Object(channel)
+ {
+ int ret = 0;
+
+ if ((ret = select(fid)) == 0)
+ {
+ ByteArray dodfData, extra;
+
+ SCARD_DEBUG("response : %s", selectResponse.toString());
+
+ if ((ret = readBinary(0, 0, getFCP()->getFileSize(), dodfData)) == 0)
+ {
+ SCARD_DEBUG("odfData : %s", dodfData.toString());
+
+ parseData(dodfData);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select failed, [%d]", ret);
+ }
+ }
+
+ PKCS15DODF::PKCS15DODF(ByteArray path, Channel *channel):PKCS15Object(channel)
+ {
+ int ret = 0;
+
+ if ((ret = select(path)) == 0)
+ {
+ ByteArray dodfData, extra;
+
+ SCARD_DEBUG("response : %s", selectResponse.toString());
+
+ if ((ret = readBinary(0, 0, getFCP()->getFileSize(), dodfData)) == 0)
+ {
+ SCARD_DEBUG("dodfData : %s", dodfData.toString());
+
+ parseData(dodfData);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select failed, [%d]", ret);
+ }
+ }
+
+ PKCS15DODF::~PKCS15DODF()
+ {
+ }
+
+ bool PKCS15DODF::parseData(ByteArray data)
+ {
+ bool result = false;
+ SimpleTLV tlv(data);
+
+ while (tlv.decodeTLV())
+ {
+ switch (tlv.getTag())
+ {
+ case (unsigned int)0xA1 : /* CHOICE 1 : OidDO */
+ {
+ PKCS15OID oid(tlv.getValue());
+
+ SCARD_DEBUG("OID DataObject");
+
+ pair<ByteArray, PKCS15OID> newPair(oid.getOID(), oid);
+ mapOID.insert(newPair);
+ }
+ break;
+
+ default :
+ SCARD_DEBUG("Unknown tlv : t [%X], l [%d], v %s", tlv.getTag(), tlv.getLength(), tlv.getValue().toString());
+ break;
+ }
+ }
+
+ SCARD_DEBUG("dataList.size() = %d", mapOID.size());
+
+ return result;
+ }
+
+ int PKCS15DODF::searchOID(ByteArray oid, ByteArray &data)
+ {
+ int result = -1;
+ map<ByteArray, PKCS15OID>::iterator item;
+
+ item = mapOID.find(oid);
+ if (item != mapOID.end())
+ {
+ data = item->second.getPath();
+ result = 0;
+ }
+
+ return result;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "PKCS15ODF.h"
+#include "SimpleTLV.h"
+#include "NumberStream.h"
+
+namespace smartcard_service_api
+{
+// PKCS15ODF::PKCS15ODF():PKCS15Object()
+// {
+//
+// }
+
+ PKCS15ODF::PKCS15ODF(Channel *channel):PKCS15Object(channel), dodf(NULL)
+ {
+ int ret = 0;
+
+ if ((ret = select(PKCS15ODF::ODF_FID)) == 0)
+ {
+ ByteArray odfData, extra;
+
+ SCARD_DEBUG("response : %s", selectResponse.toString());
+
+ if ((ret = readBinary(0, 0, getFCP()->getFileSize(), odfData)) == 0)
+ {
+ SCARD_DEBUG("odfData : %s", odfData.toString());
+
+ parseData(odfData);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select failed, [%d]", ret);
+ }
+ }
+
+ PKCS15ODF::PKCS15ODF(Channel *channel, ByteArray selectResponse):PKCS15Object(channel, selectResponse), dodf(NULL)
+ {
+ int ret = 0;
+ ByteArray odfData;
+
+ if ((ret = readBinary(0, 0, 0, odfData)) == 0)
+ {
+ SCARD_DEBUG("odfData : %s", odfData.toString());
+
+ parseData(odfData);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+ }
+ }
+
+ PKCS15ODF::~PKCS15ODF()
+ {
+ if (dodf != NULL)
+ {
+ delete dodf;
+ dodf = NULL;
+ }
+ }
+
+ bool PKCS15ODF::parseData(ByteArray data)
+ {
+ bool result = false;
+ SimpleTLV tlv(data);
+
+ while (tlv.decodeTLV())
+ {
+ switch (tlv.getTag())
+ {
+ case (unsigned int)0xA7 ://PKCS15ODF::TAG_DODF :
+ {
+ ByteArray dodf;
+
+ SCARD_DEBUG("TAG_DODF");
+
+ dodf = PKCS15Object::getOctetStream(tlv.getValue());
+
+ SCARD_DEBUG("path : %s", dodf.toString());
+
+ pair<unsigned int, ByteArray> newPair(tlv.getTag(), dodf);
+ dataList.insert(newPair);
+ }
+ break;
+
+ case (unsigned int)0xA5 ://PKCS15ODF::TAG_TOKENINFO :
+ {
+ ByteArray tokeninfo;
+
+ SCARD_DEBUG("TAG_TOKENINFO");
+
+ tokeninfo = PKCS15Object::getOctetStream(tlv.getValue());
+
+ SCARD_DEBUG("path : %s", tokeninfo.toString());
+
+ pair<unsigned int, ByteArray> newPair(tlv.getTag(), tokeninfo);
+ dataList.insert(newPair);
+ }
+ break;
+
+ default :
+ SCARD_DEBUG("Unknown tlv : t [%X], l [%d], v %s", tlv.getTag(), tlv.getLength(), tlv.getValue().toString());
+ break;
+ }
+
+ }
+
+ SCARD_DEBUG("dataList.size() = %d", dataList.size());
+
+ return result;
+ }
+
+ PKCS15DODF *PKCS15ODF::getDODF()
+ {
+ map<unsigned int, ByteArray>::iterator item;
+
+ if (dodf == NULL)
+ {
+ item = dataList.find((unsigned int)0xA7/*PKCS15ODF::TAG_DODF*/);
+ if (item != dataList.end())
+ {
+ NumberStream num(item->second);
+ unsigned int fid = num.getLittleEndianNumber();
+
+ SCARD_DEBUG("fid [%X]", fid);
+
+ dodf = new PKCS15DODF(fid, channel);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("[%02X] is not found. total [%d]", TAG_DODF, dataList.size());
+ }
+ }
+
+ SCARD_DEBUG("dodf [%p]", dodf);
+
+ return dodf;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "PKCS15.h"
+#include "PKCS15OID.h"
+#include "SimpleTLV.h"
+
+namespace smartcard_service_api
+{
+ PKCS15OID::PKCS15OID(ByteArray data)
+ {
+ parseOID(data);
+ }
+
+ PKCS15OID::~PKCS15OID()
+ {
+ }
+
+ bool PKCS15OID::parseOID(ByteArray data)
+ {
+ bool result = false;
+ SimpleTLV tlv(data);
+
+ SCARD_BEGIN();
+
+ while (tlv.decodeTLV() == true)
+ {
+ switch (tlv.getTag())
+ {
+ case PKCS15::TAG_SEQUENCE :
+ if (tlv.getLength() > 0)
+ {
+ /* common object attribute */
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV() == true && tlv.getTag() == 0x0C) /* ?? */
+ {
+ name = tlv.getValue();
+ SCARD_DEBUG("name : %s", name.toString());
+ }
+ tlv.returnToParentTLV();
+ }
+ else
+ {
+ /* common object attribute */
+ /* if you want to use this value, add member variable and parse here */
+// SCARD_DEBUG_ERR("common object attribute is empty");
+ }
+ break;
+
+ case 0xA0 : /* CHOICE 0 : External Oid??? */
+ SCARD_DEBUG_ERR("oid doesn't exist");
+ break;
+
+ case 0xA1 : /* CHOICE 1 : OidDO */
+ tlv.enterToValueTLV();
+
+ /* attribute */
+ if (tlv.decodeTLV() == true && tlv.getTag() == PKCS15::TAG_SEQUENCE)
+ {
+ tlv.enterToValueTLV();
+
+ /* oid */
+ if (tlv.decodeTLV() == true && tlv.getTag() == (unsigned int)0x06) /* ?? */
+ {
+ oid = tlv.getValue();
+
+ SCARD_DEBUG("oid : %s", oid.toString());
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("oid is empty");
+ }
+
+ /* path */
+ if (tlv.decodeTLV() == true && tlv.getTag() == PKCS15::TAG_SEQUENCE)
+ {
+ path = SimpleTLV::getOctetString(tlv.getValue());
+
+ SCARD_DEBUG("path : %s", path.toString());
+
+ result = true;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("sequence is empty");
+ }
+
+ tlv.returnToParentTLV();
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("common dataobject attribute is empty");
+ }
+ tlv.returnToParentTLV();
+
+ break;
+
+ default :
+ SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
+ break;
+ }
+ }
+
+ SCARD_END();
+
+ return result;
+ }
+
+ ByteArray PKCS15OID::getOID()
+ {
+ return oid;
+ }
+
+ ByteArray PKCS15OID::getName()
+ {
+ return name;
+ }
+
+ ByteArray PKCS15OID::getPath()
+ {
+ return path;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "SimpleTLV.h"
+#include "PKCS15Object.h"
+
+namespace smartcard_service_api
+{
+// PKCS15Object::PKCS15Object():FileObject()
+// {
+// }
+
+ PKCS15Object::PKCS15Object(Channel *channel):FileObject(channel)
+ {
+ }
+
+ PKCS15Object::PKCS15Object(Channel *channel, ByteArray selectResponse):FileObject(channel, selectResponse)
+ {
+ }
+
+ PKCS15Object::~PKCS15Object()
+ {
+ }
+
+ ByteArray PKCS15Object::getOctetStream(const ByteArray &data)
+ {
+ ByteArray result;
+ SimpleTLV tlv(data);
+
+ if (tlv.decodeTLV() && tlv.getTag() == TAG_SEQUENCE)
+ {
+ tlv.enterToValueTLV();
+
+ if (tlv.decodeTLV() && tlv.getTag() == TAG_OCTET_STREAM)
+ {
+ result = tlv.getValue();
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("TAG_OCTET_STREAM not found");
+ }
+ tlv.returnToParentTLV();
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("TAG_SEQUENCE not found");
+ }
+
+ return result;
+ }
+
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "PKCS15Path.h"
+
+namespace smartcard_service_api
+{
+ PKCS15Path::PKCS15Path()
+ {
+ }
+
+ PKCS15Path::~PKCS15Path()
+ {
+ }
+
+// PKCS15Path(ByteArray &data);
+// PKCS15Path(ByteArray path, int index);
+// PKCS15Path(unsigned char *path, unsigned int length, int index);
+// ~PKCS15Path();
+//
+// bool PKCS15Path::parseData(ByteArray &data)
+// {
+// SimpleTLV tlv(data);
+//
+// if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE */
+// {
+// /* get path */
+// path = tlv.getOctetString();
+//
+// if (tlv.decodeTLV())
+// index = t
+//
+// }
+// }
+//
+// int getPath(ByteArray &path);
+// bool hasIndexLength();
+// int getIndex();
+// unsigned int getLength();
+// int encode(ByteArray &result);
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "PKCS15TokenInfo.h"
+
+namespace smartcard_service_api
+{
+ PKCS15TokenInfo::PKCS15TokenInfo(Channel *channel):PKCS15Object(channel)
+ {
+ }
+
+ PKCS15TokenInfo::~PKCS15TokenInfo()
+ {
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "ProviderHelper.h"
+
+namespace smartcard_service_api
+{
+// ProviderHelper::ProviderHelper()
+// {
+// }
+
+ ProviderHelper::ProviderHelper(Channel *channel)
+ {
+ this->channel = NULL;
+
+ if (channel == NULL)
+ {
+ SCARD_DEBUG_ERR("invalid channel");
+ return;
+ }
+
+ this->channel = channel;
+ }
+
+ ProviderHelper::~ProviderHelper()
+ {
+ }
+
+ Channel *ProviderHelper::getChannel()
+ {
+ return channel;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ReaderHelper.h"
+
+namespace smartcard_service_api
+{
+ ReaderHelper::ReaderHelper()
+ {
+ memset(name, 0, sizeof(name));
+ seService = NULL;
+ }
+
+ ReaderHelper::~ReaderHelper()
+ {
+ }
+
+ const char *ReaderHelper::getName()
+ {
+ return (const char *)name;
+ }
+
+ SEServiceHelper *ReaderHelper::getSEService()
+ {
+ return seService;
+ }
+
+ bool ReaderHelper::isSecureElementPresent()
+ {
+ /* get checkse() symbol of se library (dlsym) */
+ /* invoke checkse() and return result */
+
+ return true /* checkse() */;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "Record.h"
+
+namespace smartcard_service_api
+{
+ Record::Record()
+ {
+ }
+
+ Record::~Record()
+ {
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "SEServiceHelper.h"
+
+namespace smartcard_service_api
+{
+ SEServiceHelper::SEServiceHelper()
+ {
+ connected = false;
+ }
+
+ SEServiceHelper::~SEServiceHelper()
+ {
+ shutdown();
+ }
+
+ vector<ReaderHelper *> SEServiceHelper::getReaders()
+ {
+ return readers;
+ }
+
+ bool SEServiceHelper::isConnected()
+ {
+ return (readers.size() > 0);
+ }
+
+ void SEServiceHelper::shutdown()
+ {
+ uint32_t i;
+
+ for (i = 0; i < readers.size(); i++)
+ {
+ readers[i]->closeSessions();
+ }
+
+ readers.clear();
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "Serializable.h"
+
+namespace smartcard_service_api
+{
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "SessionHelper.h"
+#include "ReaderHelper.h"
+
+namespace smartcard_service_api
+{
+ SessionHelper::SessionHelper(ReaderHelper *reader)
+ {
+ closed = true;
+
+ if (reader == NULL)
+ return;
+
+ this->reader = reader;
+ }
+
+ SessionHelper::~SessionHelper()
+ {
+ }
+
+ ReaderHelper *SessionHelper::getReader()
+ {
+ return reader;
+ }
+
+// ByteArray SessionHelper::getATR()
+// {
+// return atr;
+// }
+
+ bool SessionHelper::isClosed()
+ {
+ return closed;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <list>
+#include <string>
+
+/* SLP library header */
+#include "dpl/wrt-dao-ro/WrtDatabase.h"
+#include "dpl/wrt-dao-ro/widget_dao_read_only.h"
+#include "dpl/wrt-dao-ro/wrt_db_types.h"
+#include "dpl/db/sql_connection.h"
+#include "aul.h"
+
+/* local header */
+#include "Debug.h"
+#include "SignatureHelper.h"
+#include "OpensslHelper.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+using namespace WrtDB;
+using namespace std;
+
+namespace smartcard_service_api
+{
+ int SignatureHelper::getProcessName(int pid, char *processName, uint32_t length)
+ {
+ int ret = -1;
+ FILE *file = NULL;
+ char filename[1024] = { 0, };
+
+ if (pid < 0 || processName == NULL || length == 0)
+ return ret;
+
+ snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
+ SCARD_DEBUG("pid : %d, file name : %s", pid, filename);
+
+ if ((file = fopen(filename, "r")) != NULL)
+ {
+ char *name = NULL;
+ ByteArray hash, result;
+ size_t len;
+
+ memset(filename, 0, sizeof(filename));
+ len = fread(filename, 1, sizeof(filename) - 1, file);
+ fclose(file);
+
+ name = basename(filename);
+ SCARD_DEBUG("file name : %s", name);
+
+ OpensslHelper::digestBuffer("sha256", (uint8_t *)name, strlen(name), hash);
+ SCARD_DEBUG("digest [%d] : %s", hash.getLength(), hash.toString());
+
+ OpensslHelper::encodeBase64String(hash, result, false);
+
+ memset(processName, 0, length);
+ memcpy(processName, result.getBuffer(), (result.getLength() < length - 1) ? result.getLength() : length - 1);
+
+ ret = 0;
+ }
+ else
+ {
+
+ }
+
+ return ret;
+ }
+
+ ByteArray SignatureHelper::getCertificationHash(const char *packageName)
+ {
+ ByteArray result;
+ list<string>::iterator item;
+ CertificateChainList certList;
+
+ SCARD_DEBUG("package name : %s", packageName);
+
+ try
+ {
+ WrtDatabase::attachToThreadRO();
+
+ int handle = WidgetDAOReadOnly::getHandle(DPL::FromUTF8String(packageName));
+ WidgetDAOReadOnly widget(handle);
+ certList = widget.getWidgetCertificate();
+
+ SCARD_DEBUG("certList.size [%d]", certList.size());
+
+ WrtDatabase::detachFromThread();
+ }
+ catch(...)
+ {
+ SCARD_DEBUG_ERR("exception occurs!!!");
+ return result;
+ }
+
+ if (certList.size() > 0)
+ {
+ string certString;
+ ByteArray certArray;
+
+#if 0
+ for (item = certList.begin(); item != certList.end(); item++)
+ {
+ SCARD_DEBUG("certList : %s", item->data());
+ }
+#endif
+ certString = certList.back();
+ SCARD_DEBUG("certString[%d] :\n%s", certString.size(), certString.data());
+
+ /* base64 decoding */
+ if (OpensslHelper::decodeBase64String(certString.data(), certArray) == true)
+ {
+ int count = 0, offset = 0, length;
+// int i;
+ ByteArray cert;
+
+ SCARD_DEBUG("decoded[%d] : %s", certArray.getLength(), certArray.toString());
+
+ /* get count */
+ count = *(int *)certArray.getBuffer();
+ offset += sizeof(int);
+ SCARD_DEBUG("certificate count [%d]", count);
+
+// for (i = 0; i < count; i++)
+ if (count > 0)
+ {
+ /* certificate length */
+ length = *(int *)certArray.getBuffer(offset);
+ offset += sizeof(int);
+ SCARD_DEBUG("certificate length [%d]", length);
+
+ /* certificate byte stream */
+ cert.setBuffer(certArray.getBuffer(offset), length);
+ offset += length;
+
+ SCARD_DEBUG("certificate buffer [%d] : %s", cert.getLength(), cert.toString());
+
+ /* sha1 digest */
+ if (OpensslHelper::digestBuffer("sha1", cert, result) == true)
+ {
+ SCARD_DEBUG("digest[%d] : %s", result.getLength(), result.toString());
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("digestBuffer failed");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("invalid certificate count [%d]", count);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("decodeBase64String failed");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("certList.size is zero");
+ }
+
+ return result;
+ }
+
+ ByteArray SignatureHelper::getCertificationHash(int pid)
+ {
+ ByteArray result;
+ int error = 0;
+ char pkgName[256] = { 0, };
+
+ if ((error = aul_app_get_pkgname_bypid(pid, pkgName, sizeof(pkgName))) == 0)
+ {
+ result = getCertificationHash(pkgName);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("aul_app_get_pkgname_bypid failed [%d]", error);
+ }
+
+ return result;
+ }
+
+} /* namespace smartcard_service_api */
+
+/* export C API */
+using namespace smartcard_service_api;
+
+EXTERN_API int signature_helper_get_certificate_hash(const char *packageName, uint8_t *hash, uint32_t *length)
+{
+ int ret = -1;
+ ByteArray result;
+
+ if (packageName == NULL || strlen(packageName) == 0 || hash == NULL || length == NULL || *length < 20)
+ return ret;
+
+ result = SignatureHelper::getCertificationHash(packageName);
+
+ if (result.isEmpty() == false)
+ {
+ memcpy(hash, result.getBuffer(), (result.getLength() < *length) ? result.getLength() : *length);
+ *length = result.getLength();
+
+ ret = 0;
+ }
+ else
+ {
+ ret = -1;
+ }
+
+ return ret;
+}
+
+EXTERN_API int signature_helper_get_certificate_hash_by_pid(int pid, uint8_t *hash, uint32_t *length)
+{
+ int ret = -1;
+ ByteArray result;
+
+ if (pid < 0 || hash == NULL || length == NULL || *length < 20)
+ return ret;
+
+ result = SignatureHelper::getCertificationHash(pid);
+
+ if (result.isEmpty() == false && result.getLength() < *length)
+ {
+ memcpy(hash, result.getBuffer(), result.getLength());
+ *length = result.getLength();
+
+ ret = 0;
+ }
+ else
+ {
+ ret = -1;
+ }
+
+ return ret;
+}
+
+EXTERN_API int signature_helper_get_process_name(int pid, char *processName, uint32_t length)
+{
+ int ret = -1;
+
+ if (pid < 0 || processName == NULL || length == 0)
+ return ret;
+
+ ret = SignatureHelper::getProcessName(pid, processName, length);
+
+ return ret;
+}
+
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "SimpleTLV.h"
+
+namespace smartcard_service_api
+{
+ SimpleTLV::SimpleTLV():TLVHelper()
+ {
+ }
+
+ SimpleTLV::SimpleTLV(TLVHelper *parent):TLVHelper(parent)
+ {
+ parentTLV = parent;
+ }
+
+ SimpleTLV::SimpleTLV(const ByteArray &array):TLVHelper(array)
+ {
+ }
+
+ SimpleTLV::SimpleTLV(const ByteArray &array, TLVHelper *parent):TLVHelper(array, parent)
+ {
+ parentTLV = parent;
+ }
+
+ SimpleTLV::~SimpleTLV()
+ {
+ if (childTLV != NULL)
+ {
+ delete childTLV;
+ childTLV = NULL;
+ }
+ }
+
+ int SimpleTLV::decodeTag(unsigned char *buffer)
+ {
+ /* 0x00 or 0xFF is invalid tag value */
+ if (buffer[0] == 0x00 || buffer[0] == 0xFF)
+ {
+ return -1;
+ }
+
+ currentT = buffer[0];
+
+ return 1;
+ }
+
+ int SimpleTLV::decodeLength(unsigned char *buffer)
+ {
+ int count = 0;
+
+ if (buffer[0] == 0xFF)
+ {
+ /* 3 bytes length */
+ currentL = (buffer[1] << 8) | buffer[2];
+ count = 3;
+ }
+ else
+ {
+ /* 1 byte length */
+ currentL = buffer[0];
+ count = 1;
+ }
+
+ return count;
+ }
+
+ int SimpleTLV::decodeValue(unsigned char *buffer)
+ {
+ if (currentL == 0)
+ return 0;
+
+ currentV.setBuffer(buffer, currentL);
+
+ return currentL;
+ }
+
+ ByteArray SimpleTLV::encode(unsigned int tag, ByteArray buffer)
+ {
+ bool isLongBuffer = false;
+ ByteArray result;
+ unsigned int total_len = 0;
+ unsigned int current = 0;
+ unsigned char *temp_buffer = NULL;
+
+ /* add tag's length */
+ total_len += 1;
+
+ /* add length's length */
+ if (buffer.getLength() < 255)
+ {
+ total_len += 1;
+ }
+ else if (buffer.getLength() < 65536)
+ {
+ total_len += 3;
+ isLongBuffer = true;
+ }
+ else
+ {
+ return result;
+ }
+
+ /* add buffer's length */
+ total_len += buffer.getLength();
+
+ /* alloc new buffer */
+ temp_buffer = new unsigned char[total_len];
+ if (temp_buffer == NULL)
+ {
+ return result;
+ }
+ memset(temp_buffer, 0, total_len);
+
+ /* fill tag */
+ temp_buffer[current++] = (unsigned char)tag;
+
+ /* fill length */
+ if (isLongBuffer == true)
+ {
+ temp_buffer[current++] = (unsigned char)(0xFF);
+ temp_buffer[current++] = (unsigned char)(buffer.getLength() >> 8);
+ temp_buffer[current++] = (unsigned char)(buffer.getLength());
+ }
+ else
+ {
+ temp_buffer[current++] = (unsigned char)(buffer.getLength());
+ }
+
+ /* fill value */
+ if (buffer.getLength() > 0)
+ memcpy(temp_buffer + current, buffer.getBuffer(), buffer.getLength());
+
+ result.setBuffer(temp_buffer, total_len);
+
+ delete []temp_buffer;
+
+ return result;
+ }
+
+ ByteArray SimpleTLV::encode(unsigned int tag, unsigned char *buffer, unsigned int length)
+ {
+ return encode(tag, ByteArray(buffer, length));
+ }
+
+ TLVHelper *SimpleTLV::getChildTLV(ByteArray data)
+ {
+ if (childTLV != NULL)
+ {
+ delete childTLV;
+ childTLV = NULL;
+ }
+ childTLV = new SimpleTLV(data, this);
+
+ return (TLVHelper *)childTLV;
+ }
+
+ ByteArray SimpleTLV::getOctetString(const ByteArray &array)
+ {
+ SimpleTLV tlv(array);
+
+ return SimpleTLV::getOctetString(tlv);
+ }
+
+ ByteArray SimpleTLV::getOctetString(SimpleTLV &tlv)
+ {
+ ByteArray result;
+
+ if (tlv.decodeTLV() == true && tlv.getTag() == 0x04) /* OCTET STRING */
+ {
+ result = tlv.getValue();
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("getOctetString failed (0x%02X)", tlv.getTag());
+ }
+
+ return result;
+ }
+
+ bool SimpleTLV::getBoolean(const ByteArray &array)
+ {
+ SimpleTLV tlv(array);
+
+ return SimpleTLV::getBoolean(tlv);
+ }
+
+ bool SimpleTLV::getBoolean(SimpleTLV &tlv)
+ {
+ bool result = false;
+
+ if (tlv.decodeTLV() == true && tlv.getTag() == 0x80) /* BOOLEAN */
+ {
+ if (tlv.getValue().getAt(0) == 0)
+ result = false;
+ else
+ result = true;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("getBoolean failed (0x%02X)", tlv.getTag());
+ }
+
+ return result;
+ }
+
+ int SimpleTLV::getInteger(const ByteArray &array)
+ {
+ SimpleTLV tlv(array);
+
+ return SimpleTLV::getInteger(tlv);
+ }
+
+ int SimpleTLV::getInteger(SimpleTLV &tlv)
+ {
+ int result = 0;
+
+ if (tlv.decodeTLV() == true && tlv.getTag() == 0x80) /* TODO : INTEGER */
+ {
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("getInteger failed (0x%02X)", tlv.getTag());
+ }
+
+ return result;
+ }
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <sys/time.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+
+namespace smartcard_service_api
+{
+ Synchronous::Synchronous()
+ {
+ pthread_mutex_init(&syncMutex, NULL);
+ pthread_cond_init(&syncCondition, NULL);
+ }
+
+ void Synchronous::syncLock()
+ {
+ pthread_mutex_lock(&syncMutex);
+ }
+
+ void Synchronous::syncUnlock()
+ {
+ pthread_mutex_unlock(&syncMutex);
+ }
+
+ int Synchronous::waitTimedCondition(int second)
+ {
+ struct timeval now;
+ struct timespec ts;
+ int result;
+
+ if (second > 0)
+ {
+ gettimeofday(&now, NULL);
+ ts.tv_sec = now.tv_sec + second;
+ ts.tv_nsec = now.tv_usec * 1000;
+
+ result = pthread_cond_timedwait(&syncCondition, &syncMutex, &ts);
+ }
+ else
+ {
+ result = pthread_cond_wait(&syncCondition, &syncMutex);
+ }
+
+ return result;
+ }
+
+ void Synchronous::signalCondition()
+ {
+ pthread_cond_signal(&syncCondition);
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "TLVHelper.h"
+
+namespace smartcard_service_api
+{
+ void TLVHelper::initialize(TLVHelper *parent)
+ {
+ parentTLV = parent;
+ childTLV = NULL;
+ currentTLV = this;
+ offset = 0;
+ currentT = 0;
+ currentL = 0;
+ }
+
+ TLVHelper::TLVHelper()
+ {
+ initialize();
+ }
+
+ TLVHelper::TLVHelper(TLVHelper *parent)
+ {
+ initialize(parent);
+ }
+
+ TLVHelper::TLVHelper(const ByteArray &array)
+ {
+ setTLVBuffer(array);
+ }
+
+ TLVHelper::TLVHelper(const ByteArray &array, TLVHelper *parent)
+ {
+ setTLVBuffer(array, parent);
+ }
+
+ TLVHelper::~TLVHelper()
+ {
+ }
+
+ bool TLVHelper::setTLVBuffer(const ByteArray &array, TLVHelper *parent)
+ {
+ initialize(parent);
+
+ if (array.getLength() == 0)
+ return false;
+
+ tlvBuffer = array;
+
+ return true;
+ }
+
+ bool TLVHelper::setTLVBuffer(unsigned char *buffer, unsigned int length, TLVHelper *parent)
+ {
+ return setTLVBuffer(ByteArray(buffer, length), parent);
+ }
+
+ bool TLVHelper::_decodeTLV()
+ {
+ int result;
+
+ currentT = 0;
+ currentL = 0;
+ currentV.releaseBuffer();
+
+ if (isEndOfBuffer())
+ return false;
+
+ /* T */
+ if ((result = decodeTag(tlvBuffer.getBuffer(offset))) < 0)
+ return false;
+
+ offset += result;
+
+ /* L */
+ if ((result = decodeLength(tlvBuffer.getBuffer(offset))) < 0)
+ return false;
+
+ offset += result;
+
+ if (currentL > 0)
+ {
+ /* V */
+ if ((result = decodeValue(tlvBuffer.getBuffer(offset))) < 0)
+ return false;
+
+ offset += result;
+ }
+
+ return true;
+ }
+
+ const char *TLVHelper::toString()
+ {
+ memset(strBuffer, 0, sizeof(strBuffer));
+
+ if (currentL == 0)
+ {
+ snprintf(strBuffer, sizeof(strBuffer), "T [%X], L [%d]", getTag(), getLength());
+ }
+ else
+ {
+ snprintf(strBuffer, sizeof(strBuffer), "T [%X], L [%d], V %s", getTag(), getLength(), getValue().toString());
+ }
+
+ return strBuffer;
+ }
+
+ TLVHelper *TLVHelper::getParentTLV()
+ {
+ return parentTLV;
+ }
+
+ bool TLVHelper::enterToValueTLV()
+ {
+ bool result = false;
+ TLVHelper *temp = NULL;
+
+ if (getLength() >= 2)
+ {
+ temp = currentTLV->getChildTLV(getValue());
+
+ if (temp != NULL)
+ {
+ currentTLV = temp;
+ result = true;
+ }
+ }
+
+ return result;
+ }
+
+ bool TLVHelper::returnToParentTLV()
+ {
+ bool result = true;
+
+// SCARD_DEBUG("current [%p], parent [%p]", currentTLV, currentTLV->getParentTLV());
+
+ if (currentTLV->getParentTLV() != NULL)
+ {
+ currentTLV = currentTLV->getParentTLV();
+ }
+ else
+ {
+ /* top tlv */
+ }
+
+ return result;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 APDUHELPER_H_
+#define APDUHELPER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ class ResponseHelper
+ {
+ private:
+ ByteArray response;
+ unsigned char sw[2];
+ int status;
+ ByteArray dataField;
+
+ static int parseStatusWord(unsigned char *sw);
+ public:
+ ResponseHelper();
+ ResponseHelper(const ByteArray &response);
+ ~ResponseHelper();
+
+ bool setResponse(const ByteArray &response);
+ int getStatus();
+// char *getErrorString();
+ ByteArray getDataField();
+
+ static int getStatus(const ByteArray &response);
+ static ByteArray getDataField(const ByteArray &response);
+// static char *getErrorString();
+ };
+
+ class APDUCommand
+ {
+ private:
+ typedef struct _command_header_t
+ {
+ unsigned char cla;
+ unsigned char ins;
+ unsigned char param[2];
+ } command_header_t;
+
+ command_header_t header;
+ ByteArray commandData;
+ unsigned int maxResponseSize;
+ bool isExtendedLength;
+
+ public:
+ static const unsigned char INS_DEACTIVATE_FILE = (unsigned char)0x04;
+ static const unsigned char INS_TERMINAL_PROFILE = (unsigned char)0x10;
+ static const unsigned char INS_TERMINAL_RESPONSE = (unsigned char)0x14;
+ static const unsigned char INS_VERIFY = (unsigned char)0x20;
+ static const unsigned char INS_CHANGE_PIN = (unsigned char)0x24;
+ static const unsigned char INS_DISABLE_PIN = (unsigned char)0x26;
+ static const unsigned char INS_ENABLE_PIN = (unsigned char)0x28;
+ static const unsigned char INS_UNBLOCK_PIN = (unsigned char)0x2C;
+ static const unsigned char INS_INCREASE = (unsigned char)0x32;
+ static const unsigned char INS_ACTIVATE_FILE = (unsigned char)0x44;
+ static const unsigned char INS_GET_CHALLENGE = (unsigned char)0x84;
+ static const unsigned char INS_AUTHENTICATE = (unsigned char)0x88;
+ static const unsigned char INS_AUTHENTICATE2 = (unsigned char)0x89;
+ static const unsigned char INS_MANAGE_CHANNEL = (unsigned char)0x70;
+ static const unsigned char INS_SEARCH_RECORD = (unsigned char)0xA2;
+ static const unsigned char INS_SELECT_FILE = (unsigned char)0xA4;
+ static const unsigned char INS_TERMINAL_CAPABILITY = (unsigned char)0xAA;
+ static const unsigned char INS_READ_BINARY = (unsigned char)0xB0;
+ static const unsigned char INS_READ_RECORD = (unsigned char)0xB2;
+ static const unsigned char INS_GET_RESPONSE = (unsigned char)0xC0;
+ static const unsigned char INS_RETRIEVE_DATA = (unsigned char)0xCB;
+ static const unsigned char INS_WRITE_BINARY = (unsigned char)0xD0;
+ static const unsigned char INS_UPDATE_BINARY = (unsigned char)0xD6;
+ static const unsigned char INS_UPDATE_RECORD = (unsigned char)0xDC;
+ static const unsigned char INS_SET_DATA = (unsigned char)0xDB;
+ static const unsigned char INS_CREATE_FILE = (unsigned char)0xE0;
+ static const unsigned char INS_APPEND_RECORD = (unsigned char)0xE2;
+ static const unsigned char INS_DELETE_FILE = (unsigned char)0xE4;
+ static const unsigned char INS_STATUS = (unsigned char)0xF2;
+// static const unsigned char INS_ = (unsigned char)0x;
+
+ static const unsigned char P1_SELECT_BY_ID = (unsigned char)0x00;
+ static const unsigned char P1_SELECT_PARENT_DF = (unsigned char)0x03;
+ static const unsigned char P1_SELECT_BY_DF_NAME = (unsigned char)0x04;
+ static const unsigned char P1_SELECT_BY_PATH = (unsigned char)0x08;
+ static const unsigned char P1_SELECT_BY_PATH_FROM_CURRENT_DF = (unsigned char)0x09;
+// static const unsigned char P1_ = (unsigned char)0x;
+
+ static const unsigned char P2_SELECT_GET_FCP = (unsigned char)0x04;
+// static const unsigned char P2_ = (unsigned char)0x;
+
+ APDUCommand();
+ ~APDUCommand();
+
+ bool setCommand(unsigned char cla, unsigned char ins, unsigned char p1, unsigned char p2, ByteArray commandData, unsigned int maxResponseSize);
+ bool setCommand(const ByteArray &command);
+
+ bool setChannel(int type, int channelNum);
+
+ void setCLA(unsigned char cla);
+ unsigned char getCLA();
+
+ void setINS(unsigned char ins);
+ unsigned char getINS();
+
+ void setP1(unsigned char p1);
+ unsigned char getP1();
+
+ void setP2(unsigned char p2);
+ unsigned char getP2();
+
+ void setCommandData(const ByteArray &data);
+ ByteArray getCommandData();
+
+ void setMaxResponseSize(unsigned int maxResponseSize);
+ unsigned int setMaxResponseSize();
+
+ bool getBuffer(ByteArray &array);
+ };
+
+ class APDUHelper
+ {
+ public:
+ static const int COMMAND_OPEN_LOGICAL_CHANNEL = 1;
+ static const int COMMAND_CLOSE_LOGICAL_CHANNEL = 2;
+ static const int COMMAND_SELECT_BY_ID = 3;
+ static const int COMMAND_SELECT_PARENT_DF = 4;
+ static const int COMMAND_SELECT_BY_DF_NAME = 5;
+ static const int COMMAND_SELECT_BY_PATH = 6;
+ static const int COMMAND_SELECT_BY_PATH_FROM_CURRENT_DF = 7;
+ static const int COMMAND_READ_BINARY = 8;
+ static const int COMMAND_READ_RECORD = 9;
+ static const int COMMAND_WRITE_BINARY = 10;
+ static const int COMMAND_WRITE_RECORD = 11;
+
+ static ByteArray generateAPDU(int command, int channel, ByteArray data);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* APDUHELPER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 ACCESSCONDITION_H_
+#define ACCESSCONDITION_H_
+
+/* standard library header */
+#include <vector>
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class APDUAccessRule
+ {
+ private :
+ bool permission;
+ map<ByteArray, ByteArray> mapApduFilters;
+
+ public :
+ APDUAccessRule()
+ {
+ permission = true;
+ }
+
+ void loadAPDUAccessRule(const ByteArray &data);
+ bool isAuthorizedAccess(const ByteArray &command);
+
+ void printAPDUAccessRules();
+ };
+
+ class NFCAccessRule
+ {
+ private :
+ bool permission;
+
+ public :
+ NFCAccessRule()
+ {
+ permission = true;
+ }
+
+ void loadNFCAccessRule(const ByteArray &data);
+ bool isAuthorizedAccess(void);
+
+ void printNFCAccessRules();
+ };
+
+ class AccessCondition
+ {
+ private :
+ bool permission;
+ ByteArray aid;
+ vector<ByteArray> hashes;
+ APDUAccessRule apduRule;
+ NFCAccessRule nfcRule;
+
+ public :
+ AccessCondition() : permission(false)
+ {
+ }
+
+ void loadAccessCondition(ByteArray &aid, ByteArray &data);
+ bool isAuthorizedAccess(ByteArray &certHash);
+ bool isAuthorizedAPDUAccess(ByteArray &command);
+ bool isAuthorizedNFCAccess();
+
+ void printAccessConditions();
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* ACCESSCONDITION_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 ACCESSCONTROLLIST_H_
+#define ACCESSCONTROLLIST_H_
+
+/* standard library header */
+#include <vector>
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+#include "Channel.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class Terminal;
+ class AccessCondition;
+
+ class AccessControlList
+ {
+ protected:
+ map<ByteArray, AccessCondition> mapConditions;
+ Channel *channel;
+ Terminal *terminal;
+
+ void printAccessControlList();
+
+ public:
+ static ByteArray AID_ALL;
+ static ByteArray AID_DEFAULT;
+
+ AccessControlList();
+ AccessControlList(Channel *channel);
+ AccessControlList(Terminal *terminal);
+ ~AccessControlList();
+
+ int setChannel(Channel *channel);
+ virtual int setTerminal(Terminal *terminal) { this->terminal = terminal; return 0; }
+
+ virtual int loadACL() = 0;
+
+ int updateACL();
+ void releaseACL();
+
+ bool isAuthorizedAccess(ByteArray aid, ByteArray certHash);
+ bool isAuthorizedAccess(unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* ACCESSCONTROLLIST_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 BYTEARRAY_H_
+#define BYTEARRAY_H_
+
+/* standard library header */
+#include <stdint.h>
+
+/* SLP library header */
+
+/* local header */
+//#include "Serializable.h"
+
+#define ARRAY_AND_SIZE(x) (uint8_t *)(&x), sizeof(x)
+
+namespace smartcard_service_api
+{
+ class ByteArray //: public Serializable
+ {
+ protected:
+ uint8_t *buffer;
+ uint32_t length;
+ char strBuffer[100];
+
+ bool _setBuffer(uint8_t *array, uint32_t bufferLen);
+ void save(const char *filePath);
+
+ public:
+ static ByteArray EMPTY;
+
+ ByteArray();
+ ByteArray(uint8_t *array, uint32_t bufferLen);
+ ByteArray(const ByteArray &T);
+ ~ByteArray();
+
+// ByteArray serialize();
+// void deserialize(ByteArray buffer);
+
+ bool setBuffer(uint8_t *array, uint32_t bufferLen);
+ void releaseBuffer();
+
+ uint32_t getLength() const;
+ uint8_t *getBuffer() const;
+ uint8_t *getBuffer(uint32_t offset) const;
+
+ uint8_t getAt(uint32_t index) const;
+ uint8_t getReverseAt(uint32_t index) const;
+
+ uint32_t copyFromArray(uint8_t *array, uint32_t bufferLen) const;
+
+ /* operator overloading */
+ ByteArray &operator =(const ByteArray &T);
+ ByteArray operator +(const ByteArray &T);
+ ByteArray &operator +=(const ByteArray &T);
+ bool operator ==(const ByteArray &T) const;
+ bool operator !=(const ByteArray &T) const;
+ bool operator <(const ByteArray &T) const;
+ bool operator >(const ByteArray &T) const;
+ uint8_t &operator [](uint32_t index) const;
+
+ inline bool isEmpty() { return (buffer == (void *)0 || length == 0); }
+ const char *toString();
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* BYTEARRAY_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 CHANNEL_H_
+#define CHANNEL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ class SessionHelper; /* explicit declaration */
+
+ typedef void (*transmitCallback)(unsigned char *buffer, unsigned int length, int error, void *userParam);
+ typedef void (*closeCallback)(int error, void *userParam);
+
+ class Channel : public Synchronous
+ {
+ protected:
+ ByteArray selectResponse;
+ SessionHelper *session;
+ int channelNum;
+
+ Channel() : Synchronous()
+ {
+ channelNum = -1;
+ }
+ Channel(SessionHelper *session) : Synchronous()
+ {
+ this->session = session;
+ }
+
+ virtual void closeSync() = 0;
+ virtual int transmitSync(ByteArray command, ByteArray &result) = 0;
+
+ public:
+ virtual ~Channel() {}
+
+ virtual int close(closeCallback callback, void *userParam) = 0;
+ inline bool isBasicChannel() const { return (channelNum == 0); }
+ inline bool isClosed() const { return (channelNum < 0); }
+
+ inline ByteArray getSelectResponse() const { return selectResponse; }
+ inline SessionHelper *getSession() const { return session; }
+ virtual int transmit(ByteArray command, transmitCallback callback, void *userData) = 0;
+
+ friend class FileObject;
+ friend class ServerSession;
+ friend class ServerChannel;
+ friend class ServerDispatcher;
+ friend class ServerResource;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* CHANNEL_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 DEBUG_H_
+#define DEBUG_H_
+
+/* standard library header */
+
+/* SLP library header */
+#include "dlog.h"
+
+/* local header */
+
+#define COLOR_RED "\033[0;31m"
+#define COLOR_GREEN "\033[0;32m"
+#define COLOR_BROWN "\033[0;33m"
+#define COLOR_BLUE "\033[0;34m"
+#define COLOR_PURPLE "\033[0;35m"
+#define COLOR_CYAN "\033[0;36m"
+#define COLOR_LIGHTBLUE "\033[0;37m"
+#define COLOR_END "\033[0;m"
+
+#define SCARD_DEBUG(fmt, ...)\
+ do\
+ {\
+ LOGD("[%s(): %d] " fmt, __FUNCTION__, __LINE__,##__VA_ARGS__);\
+ } while (0)
+
+#define SCARD_DEBUG_ERR(fmt, ...)\
+ do\
+ {\
+ LOGE(COLOR_RED"[%s(): %d] " fmt COLOR_END, __FUNCTION__, __LINE__,##__VA_ARGS__);\
+ }while (0)
+
+#define SCARD_BEGIN() \
+ do\
+ {\
+ LOGD(COLOR_BLUE"[%s(): %d] BEGIN >>>>"COLOR_END, __FUNCTION__ ,__LINE__);\
+ } while( 0 )
+
+#define SCARD_END() \
+ do\
+ {\
+ LOGD(COLOR_BLUE"[%s(): %d] END <<<<"COLOR_END, __FUNCTION__,__LINE__ );\
+ } \
+ while( 0 )
+
+#endif /* DEBUG_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 DISPATCHERHELPER_H_
+#define DISPATCHERHELPER_H_
+
+/* standard library header */
+#include <queue>
+#include <pthread.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+#include "DispatcherMsg.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class DispatcherHelper : public Synchronous
+ {
+ private:
+ pthread_t dispatcherThread;
+
+ queue<DispatcherMsg *> messageQ;
+
+ static void *_dispatcherThreadFunc(void *data);
+
+ DispatcherMsg *fetchMessage();
+
+ protected:
+ virtual void *dispatcherThreadFunc(DispatcherMsg *msg, void *data) = 0;
+
+ public:
+ DispatcherHelper();
+ ~DispatcherHelper();
+
+ void clearQueue();
+
+ void pushMessage(DispatcherMsg *msg);
+
+ bool runDispatcherThread();
+ void stopDispatcherThread();
+
+ friend void *_dispatcherThreadFunc(void *data);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* DISPATCHERHELPER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 DISPATCHERMSG_H_
+#define DISPATCHERMSG_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Message.h"
+
+namespace smartcard_service_api
+{
+ class DispatcherMsg: public Message
+ {
+ private:
+ int peerSocket;
+
+ public:
+ DispatcherMsg():Message()
+ {
+ peerSocket = -1;
+ }
+
+ DispatcherMsg(Message *msg):Message()
+ {
+ peerSocket = -1;
+ message = msg->message;
+ param1 = msg->param1;
+ param2 = msg->param2;
+ error = msg->error;
+ data = msg->data;
+ caller = msg->caller;
+ callback = msg->callback;
+ userParam = msg->userParam;
+ }
+
+ DispatcherMsg(Message *msg, int socket):Message()
+ {
+ peerSocket = socket;
+ message = msg->message;
+ param1 = msg->param1;
+ param2 = msg->param2;
+ error = msg->error;
+ data = msg->data;
+ caller = msg->caller;
+ callback = msg->callback;
+ userParam = msg->userParam;
+ }
+
+ ~DispatcherMsg() {}
+
+ inline int getPeerSocket() { return peerSocket; }
+ inline void setPeerSocket(int socket) { peerSocket = socket; }
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* DISPATCHERMSG_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 FCI_H_
+#define FCI_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ class FCP
+ {
+ private:
+ ByteArray fcpBuffer;
+
+ char strBuffer[400];
+
+ unsigned int fileSize;
+ unsigned int totalFileSize;
+ unsigned int fid;
+ unsigned int sfi;
+ unsigned int maxRecordSize;
+ unsigned int numberOfRecord;
+ unsigned int fileType;
+ unsigned int fileStructure;
+ unsigned int lcs;
+
+ void resetMemberVar();
+
+ public:
+ FCP();
+ FCP(ByteArray &array);
+ ~FCP();
+
+ bool setFCP(ByteArray array);
+ ByteArray getFCP();
+ void releaseFCP();
+
+ unsigned int getFileSize();
+ unsigned int getTotalFileSize();
+ unsigned int getFID();
+ unsigned int getSFI();
+ unsigned int getMaxRecordSize();
+ unsigned int getNumberOfRecord();
+ unsigned int getFileType();
+ unsigned int getFileStructure();
+ unsigned int getLCS();
+
+ const char *toString();
+ };
+
+ class FCM
+ {
+ private:
+ ByteArray fcmBuffer;
+
+ public:
+ FCM();
+ virtual ~FCM();
+ };
+
+ class FCI
+ {
+ private:
+ ByteArray fciBuffer;
+ FCP fcp;
+ FCM fcm;
+
+ public:
+ static const int INFO_NOT_AVAILABLE = -1;
+
+ static const int FT_DF = 0;
+ static const int FT_EF = 1;
+
+ static const int FS_NO_EF = 0;
+ static const int FS_TRANSPARENT = 1;
+ static const int FS_LINEAR_FIXED = 2;
+ static const int FS_LINEAR_VARIABLE = 3;
+ static const int FS_CYCLIC = 4;
+
+ static const int LCS_NO_INFORMATION_GIVEN = 0;
+ static const int LCS_CREATION_STATE = 1;
+ static const int LCS_INITIALISATION_STATE = 3;
+ static const int LCS_OPERATION_STATE_ACTIVATED = 5;
+ static const int LCS_OPERATION_STATE_DEACTIVATED = 4;
+ static const int LCS_TERMINATION_STATE = 6;
+
+ FCI();
+ ~FCI();
+
+ bool setFCIBuffer(ByteArray array);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* FCI_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 FILEOBJECT_H_
+#define FILEOBJECT_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "ProviderHelper.h"
+#include "ByteArray.h"
+#include "FCI.h"
+#include "Record.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class FileObject : public ProviderHelper
+ {
+ private:
+ FCI fci;
+ FCP fcp;
+
+ protected:
+ ByteArray selectResponse;
+ bool setSelectResponse(ByteArray response);
+
+ public:
+ static const int SUCCESS = 0;
+ static const int ERROR_ILLEGAL_STATE = -1;
+ static const int ERROR_ILLEGAL_REFERENCE = -2;
+ static const int ERROR_ILLEGAL_PARAMETER = -3;
+ static const int ERROR_SECURITY = -4;
+ static const int ERROR_OPERATION_NOT_SUPPORT = -5;
+ static const int ERROR_IO = -6;
+ static const int ERROR_UNKNOWN = -99;
+
+ FileObject(Channel *channel);
+ FileObject(Channel *channel, ByteArray selectResponse);
+ ~FileObject();
+
+ int select(ByteArray aid);
+ int select(ByteArray path, bool fromCurrentDF);
+ int select(unsigned int fid);
+ int selectParent();
+
+ FCI *getFCI();
+ FCP *getFCP();
+
+ int readRecord(unsigned int sfi, unsigned int recordId, Record &result);
+ int writeRecord(unsigned int sfi, Record record);
+
+ int searchRecord(unsigned int sfi, 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);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* FILEOBJECT_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 GPSEACL_H_
+#define GPSEACL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "AccessControlList.h"
+#include "PKCS15.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+ class GPSEACL: public AccessControlList
+ {
+ private:
+ PKCS15 *pkcs15;
+ ByteArray refreshTag;
+
+ static ByteArray OID_GLOBALPLATFORM;
+
+ int loadAccessControl(PKCS15DODF *dodf);
+ int loadRules(ByteArray path);
+ int loadAccessConditions(ByteArray aid, ByteArray path);
+
+ public:
+ GPSEACL(Channel *channel);
+ ~GPSEACL();
+
+ int loadACL();
+
+ };
+
+} /* 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(channel_h channel);
+int gp_se_acl_load_acl(gp_se_acl_h handle);
+int gp_se_acl_update_acl(gp_se_acl_h handle);
+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_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 IPCHELPER_H_
+#define IPCHELPER_H_
+
+/* standard library header */
+#include <glib.h>
+#include <pthread.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Message.h"
+#include "DispatcherHelper.h"
+
+namespace smartcard_service_api
+{
+ class IPCHelper
+ {
+ protected:
+ static const int IPC_SERVER_PORT = 8989;
+ static const int IPC_SERVER_MAX_CLIENT = 10;
+
+ int ipcSocket;
+ unsigned int watchId;
+ GIOChannel *ioChannel;
+ pthread_mutex_t ipcLock;
+ DispatcherHelper *dispatcher;
+
+ static gboolean channelCallbackFunc(GIOChannel* channel, GIOCondition condition, gpointer data);
+
+ virtual int handleIOErrorCondition(void *channel, GIOCondition condition) = 0;
+ virtual int handleInvalidSocketCondition(void *channel, GIOCondition condition) = 0;
+ virtual int handleIncomingCondition(void *channel, GIOCondition condition) = 0;
+
+ public:
+ IPCHelper();
+ ~IPCHelper();
+
+ bool createListenSocket();
+ bool createConnectSocket();
+
+ bool sendMessage(Message *msg);
+ bool sendMessage(int socket, Message *msg);
+ Message *retrieveMessage();
+ Message *retrieveMessage(int socket);
+
+ void setDispatcher(DispatcherHelper *dispatcher);
+
+ friend gboolean channelCallbackFunc(GIOChannel* channel, GIOCondition condition, gpointer data);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* IPCHELPER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 ISO7816BERTLV_H_
+#define ISO7816BERTLV_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+#include "TLVHelper.h"
+
+namespace smartcard_service_api
+{
+ class ISO7816BERTLV: public TLVHelper
+ {
+ private:
+// ISO7816BERTLV child;
+
+ unsigned char firstByte;
+ unsigned int tagClass;
+ unsigned int encoding;
+
+ ISO7816BERTLV(TLVHelper *parent);
+ ISO7816BERTLV(const ByteArray &array, TLVHelper *parent);
+
+ int decodeTag(unsigned char *buffer);
+ int decodeLength(unsigned char *buffer);
+ int decodeValue(unsigned char *buffer);
+
+ TLVHelper *getChildTLV(ByteArray data);
+
+ public:
+ ISO7816BERTLV();
+ ISO7816BERTLV(const ByteArray &array);
+ ~ISO7816BERTLV();
+
+ unsigned int getClass();
+ unsigned int getEncoding();
+
+ static ByteArray encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, ByteArray buffer);
+ static ByteArray encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, unsigned char *buffer, unsigned int length);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* ISO7816BERTLV_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 LOCK_H_
+#define LOCK_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "pthread.h"
+
+namespace smartcard_service_api
+{
+ class Lock
+ {
+ public:
+ virtual ~Lock() {};
+ virtual void lock() = 0;
+ virtual void unlock() = 0;
+ };
+
+ class PMutex : public Lock
+ {
+ private:
+ pthread_mutex_t mutex;
+
+ public:
+ PMutex() { pthread_mutex_init(&mutex, NULL); }
+ ~PMutex() { pthread_mutex_destroy(&mutex); }
+
+ inline void lock() { pthread_mutex_lock(&mutex); }
+ inline void unlock() { pthread_mutex_unlock(&mutex); }
+ };
+#define TOKENPASTE(x, y) x ## y
+#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
+#define SCOPE_LOCK(X) \
+ if (const AutoLockHelper& TOKENPASTE2(lock_, __LINE__) = makeAutoLock(X))
+
+ class AutoLockHelper
+ {
+ public:
+ inline operator bool() const
+ {
+ return true;
+ }
+ };
+
+ template<typename T>
+ class AutoLock : public AutoLockHelper
+ {
+ private:
+ T *lock;
+
+ public:
+ AutoLock(const AutoLock &_lock) { lock = _lock.lock; }
+ AutoLock(T& _lock) : lock(&_lock) { lock->lock(); }
+ ~AutoLock() { lock->unlock(); }
+ };
+
+ template<typename T>
+ inline AutoLock<T> makeAutoLock(T& lock)
+ {
+ return AutoLock<T>(lock);
+ }
+
+} /* namespace smartcard_service_api */
+#endif /* SCOPELOCK_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 MESSAGE_H_
+#define MESSAGE_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Serializable.h"
+
+namespace smartcard_service_api
+{
+ class Message: public Serializable
+ {
+ private:
+ char text[200];
+
+ public:
+ static const int MSG_REQUEST_READERS = 0x80;
+ static const int MSG_REQUEST_SHUTDOWN = 0x81;
+ static const int MSG_REQUEST_OPEN_SESSION = 0x82;
+ static const int MSG_REQUEST_CLOSE_SESSION = 0x83;
+ static const int MSG_REQUEST_OPEN_CHANNEL = 0x84;
+ static const int MSG_REQUEST_CLOSE_CHANNEL = 0x85;
+ static const int MSG_REQUEST_GET_ATR = 0x86;
+ static const int MSG_REQUEST_TRANSMIT = 0x87;
+ static const int MSG_REQUEST_GET_CHANNEL_COUNT = 0x88;
+
+ static const int MSG_NOTIFY_SE_REMOVED = 0x90;
+ static const int MSG_NOTIFY_SE_INSERTED = 0x91;
+
+ static const int MSG_OPERATION_RELEASE_CLIENT = 0xC0;
+
+ unsigned int message;
+ unsigned int param1;
+ unsigned int param2;
+ ByteArray data;
+ int error;
+ void *caller;
+ void *callback;
+ void *userParam;
+
+ Message();
+ ~Message();
+
+ ByteArray serialize();
+ void deserialize(unsigned char *buffer, unsigned int length);
+ void deserialize(ByteArray buffer);
+
+ const char *toString();
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* MESSAGE_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 NUMBERSTREAM_H_
+#define NUMBERSTREAM_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ class NumberStream: public ByteArray
+ {
+ public:
+ NumberStream(const ByteArray &T);
+
+ unsigned int getBigEndianNumber();
+ unsigned int getLittleEndianNumber();
+
+ static unsigned int getBigEndianNumber(const ByteArray &T);
+ static unsigned int getLittleEndianNumber(const ByteArray &T);
+
+ NumberStream &operator =(const ByteArray &T);
+ NumberStream &operator =(const NumberStream &T);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* NUMBERSTREAM_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdint.h>
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+#ifndef OPENSSLHELPER_H_
+#define OPENSSLHELPER_H_
+
+namespace smartcard_service_api
+{
+ class OpensslHelper
+ {
+ public:
+ /* base64 method */
+ static bool encodeBase64String(const ByteArray &buffer, ByteArray &result, bool newLineChar = false);
+ static bool decodeBase64String(const char *buffer, ByteArray &result, bool newLineChar = true);
+ static bool decodeBase64String(const ByteArray &buffer, ByteArray &result, bool newLineChar = true);
+
+ /* digest method */
+ static bool digestBuffer(const char *algorithm, const uint8_t *buffer, const uint32_t length, ByteArray &result);
+ static bool digestBuffer(const char *algorithm, const ByteArray &buffer, ByteArray &result);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* OPENSSLHELPER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 PKCS15_H_
+#define PKCS15_H_
+
+/* standard library header */
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "PKCS15Object.h"
+#include "PKCS15ODF.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class PKCS15: public PKCS15Object
+ {
+ private:
+ map<unsigned int, ByteArray> recordElement;
+ PKCS15ODF *odf;
+
+ public:
+ static ByteArray PKCS15_AID;
+
+ PKCS15(Channel *channel);
+ PKCS15(Channel *channel, ByteArray selectResponse);
+ ~PKCS15();
+
+ PKCS15ODF *getODF();
+ int getTokenInfo(ByteArray &path);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 PKCS15DODF_H_
+#define PKCS15DODF_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "PKCS15Object.h"
+#include "PKCS15OID.h"
+
+namespace smartcard_service_api
+{
+ class PKCS15DODF: public PKCS15Object
+ {
+ private:
+ map<ByteArray, PKCS15OID> mapOID;
+
+ bool parseData(ByteArray data);
+
+ public:
+ PKCS15DODF();
+ PKCS15DODF(unsigned int fid, Channel *channel);
+ PKCS15DODF(ByteArray path, Channel *channel);
+ ~PKCS15DODF();
+
+ int searchOID(ByteArray oid, ByteArray &data);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15DODF_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 PKCS15ODF_H_
+#define PKCS15ODF_H_
+
+/* standard library header */
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "FileObject.h"
+#include "PKCS15DODF.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class PKCS15ODF: public PKCS15Object
+ {
+ private:
+ bool parseData(ByteArray data);
+ PKCS15DODF *dodf;
+
+ public:
+ static const unsigned int ODF_FID = 0x3150;
+
+ static const unsigned int TAG_DODF = (unsigned int)0xA7;
+ static const unsigned int TAG_TOKENINFO = (unsigned int)0xA5;
+
+// PKCS15ODF();
+ PKCS15ODF(Channel *channel);
+ PKCS15ODF(Channel *channel, ByteArray selectResponse);
+ ~PKCS15ODF();
+
+ int getPuKDFPath(ByteArray &path);
+ int getPrKDFPath(ByteArray &path);
+ int getAODFPath(ByteArray &path);
+ int getCDFFPath(ByteArray &path);
+ int getDODFPath(ByteArray &path);
+
+ PKCS15DODF *getDODF();
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15ODF_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 PKCS15OID_H_
+#define PKCS15OID_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ class PKCS15OID
+ {
+ private:
+ ByteArray oid;
+ ByteArray name;
+ ByteArray path;
+
+ bool parseOID(ByteArray data);
+
+ public:
+ PKCS15OID(ByteArray data);
+ ~PKCS15OID();
+
+ ByteArray getOID();
+ ByteArray getName();
+ ByteArray getPath();
+
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15OID_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 PKCS15OBJECT_H_
+#define PKCS15OBJECT_H_
+
+/* standard library header */
+#include <map>
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "FileObject.h"
+#include "PKCS15Path.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class PKCS15Object: public FileObject
+ {
+ protected:
+ map<unsigned int, ByteArray> dataList;
+
+ public:
+ /* TODO : encapsulate below to asn class */
+ static const unsigned int TAG_SEQUENCE = (unsigned int)0x30;
+ static const unsigned int TAG_OCTET_STREAM = (unsigned int)0x04;
+
+// PKCS15Object();
+ PKCS15Object(Channel *channel);
+ PKCS15Object(Channel *channel, ByteArray selectResponse);
+ ~PKCS15Object();
+
+ int decodePath(ByteArray path, PKCS15Path &result);
+ int getPath(unsigned int type, PKCS15Path &result);
+ int getPaths(vector<PKCS15Path> &paths);
+
+ static ByteArray getOctetStream(const ByteArray &data);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15OBJECT_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 PKCS15Path_H_
+#define PKCS15Path_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ class PKCS15Path
+ {
+ private :
+ ByteArray path;
+ int index;
+ int length;
+
+ bool parseData(ByteArray &data);
+
+ public:
+ PKCS15Path();
+ PKCS15Path(ByteArray &data);
+ PKCS15Path(ByteArray path, int index);
+ PKCS15Path(unsigned char *path, unsigned int length, int index);
+ ~PKCS15Path();
+
+ int getPath(ByteArray &path);
+ bool hasIndexLength();
+ int getIndex();
+ unsigned int getLength();
+ int encode(ByteArray &result);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15Path_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 PKCS15TOKENINFO_H_
+#define PKCS15TOKENINFO_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "PKCS15Object.h"
+
+namespace smartcard_service_api
+{
+ class PKCS15TokenInfo: public PKCS15Object
+ {
+ public:
+ PKCS15TokenInfo(Channel *channel);
+ ~PKCS15TokenInfo();
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15TOKENINFO_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 PROVIDERHELPER_H_
+#define PROVIDERHELPER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Channel.h"
+
+namespace smartcard_service_api
+{
+ class ProviderHelper
+ {
+ protected:
+ Channel *channel;
+
+// ProviderHelper();
+
+ public:
+ ProviderHelper(Channel *channel);
+ ~ProviderHelper();
+
+ Channel *getChannel();
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* PROVIDERHELPER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 READERHELPER_H_
+#define READERHELPER_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+#include "SessionHelper.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class SEServiceHelper;
+
+ typedef void (*openSessionCallback)(SessionHelper *session, int error, void *userData);
+
+ class ReaderHelper : public Synchronous
+ {
+ protected:
+ char name[30];
+ vector<SessionHelper *> sessions;
+ SEServiceHelper *seService;
+
+ ReaderHelper();
+
+ virtual SessionHelper *openSessionSync() = 0;
+
+ public:
+ ~ReaderHelper();
+
+ const char *getName();
+ SEServiceHelper *getSEService();
+ bool isSecureElementPresent();
+ virtual int openSession(openSessionCallback callback, void *userData) = 0;
+ virtual void closeSessions() = 0;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* READERHELPER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 RECORD_H_
+#define RECORD_H_
+
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ class Record
+ {
+ private:
+ ByteArray data;
+ unsigned int id;
+
+ public:
+ Record();
+ Record(unsigned int id, ByteArray buffer);
+ ~Record();
+
+ unsigned int getID();
+ int getData(ByteArray &buffer);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* RECORD_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SESERVICEHELPER_H_
+#define SESERVICEHELPER_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+#include "ReaderHelper.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class SEServiceHelper : public Synchronous
+ {
+ protected:
+ bool connected;
+ vector<ReaderHelper *> readers;
+
+ public:
+ SEServiceHelper();
+ ~SEServiceHelper();
+
+ vector<ReaderHelper *> getReaders();
+ bool isConnected();
+ void shutdown();
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SESERVICEHELPER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SERIALIZABLE_H_
+#define SERIALIZABLE_H_
+
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ class Serializable
+ {
+ virtual ByteArray serialize() = 0;
+ virtual void deserialize(ByteArray buffer) = 0;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SERIALIZABLE_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SESSIONHELPER_H_
+#define SESSIONHELPER_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+#include "ByteArray.h"
+#include "Channel.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class ReaderHelper;
+
+ typedef void (*openChannelCallback)(Channel *channel, int error, void *userData);
+ typedef void (*getATRCallback)(unsigned char *atr, unsigned int length, int error, void *userData);
+ typedef void (*closeSessionCallback)(int error, void *userData);
+ typedef void (*getChannelCountCallback)(unsigned count, int error, void *userData);
+
+ class SessionHelper : public Synchronous
+ {
+ protected:
+ ReaderHelper *reader;
+ vector<Channel *> channels;
+ ByteArray atr;
+ bool closed;
+
+ virtual ByteArray getATRSync() = 0;
+ virtual void closeSync() = 0;
+
+ virtual Channel *openBasicChannelSync(ByteArray aid) = 0;
+ virtual Channel *openBasicChannelSync(unsigned char *aid, unsigned int length) = 0;
+ virtual Channel *openLogicalChannelSync(ByteArray aid) = 0;
+ virtual Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length) = 0;
+
+ public:
+ SessionHelper(ReaderHelper *reader);
+ virtual ~SessionHelper();
+
+ ReaderHelper *getReader();
+ virtual int getATR(getATRCallback callback, void *userData) = 0;
+ virtual int close(closeSessionCallback callback, void *userData) = 0;
+ bool isClosed();
+ virtual void closeChannels() = 0;
+
+ virtual int openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData) = 0;
+ virtual int openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData) = 0;
+ virtual int openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData) = 0;
+ virtual int openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData) = 0;
+
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SESSIONHELPER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SIGNATUREHELPER_H_
+#define SIGNATUREHELPER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "ByteArray.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+ class SignatureHelper
+ {
+ public:
+ static int getProcessName(int pid, char *processName, uint32_t length);
+ static ByteArray getCertificationHash(const char *packageName);
+ static ByteArray getCertificationHash(int pid);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+int signature_helper_get_process_name(int pid, char *processName, uint32_t length);
+int signature_helper_get_certificate_hash(const char *packageName, uint8_t *hash, uint32_t *length);
+int signature_helper_get_certificate_hash_by_pid(int pid, uint8_t *hash, uint32_t *length);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SIGNATUREHELPER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SIMPLETLV_H_
+#define SIMPLETLV_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+#include "TLVHelper.h"
+
+namespace smartcard_service_api
+{
+ class SimpleTLV : public TLVHelper
+ {
+ private:
+ SimpleTLV(TLVHelper *parent);
+ SimpleTLV(const ByteArray &array, TLVHelper *parent);
+
+ int decodeTag(unsigned char *buffer);
+ int decodeLength(unsigned char *buffer);
+ int decodeValue(unsigned char *buffer);
+
+ TLVHelper *getChildTLV(ByteArray data);
+
+ public:
+ SimpleTLV();
+ SimpleTLV(const ByteArray &array);
+ ~SimpleTLV();
+
+ static ByteArray getOctetString(const ByteArray &array);
+ static bool getBoolean(const ByteArray &array);
+ static int getInteger(const ByteArray &array);
+
+ static ByteArray getOctetString(SimpleTLV &tlv);
+ static bool getBoolean(SimpleTLV &tlv);
+ static int getInteger(SimpleTLV &tlv);
+
+ static ByteArray encode(unsigned int tag, ByteArray buffer);
+ static ByteArray encode(unsigned int tag, unsigned char *buffer, unsigned int length);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SIMPLETLV_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SYNCHRONOUS_H_
+#define SYNCHRONOUS_H_
+
+/* standard library header */
+#include <pthread.h>
+
+/* SLP library header */
+
+/* local header */
+
+namespace smartcard_service_api
+{
+ class Synchronous
+ {
+ protected:
+ pthread_mutex_t syncMutex;
+ pthread_cond_t syncCondition;
+
+ void syncLock();
+ void syncUnlock();
+ int waitTimedCondition(int second);
+ void signalCondition();
+
+ public:
+ Synchronous();
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SYNCHRONOUS_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 TLVHELPER_H_
+#define TLVHELPER_H_
+
+/* standard library header */
+#include <stddef.h>
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ class TLVHelper
+ {
+ protected:
+ TLVHelper *currentTLV;
+ TLVHelper *parentTLV;
+ TLVHelper *childTLV;
+
+ char strBuffer[200];
+ ByteArray tlvBuffer;
+ unsigned int offset;
+
+ unsigned int currentT;
+ unsigned int currentL;
+ ByteArray currentV;
+
+ void initialize(TLVHelper *parent = NULL);
+ TLVHelper(TLVHelper *parent);
+ TLVHelper(const ByteArray &array, TLVHelper *parent);
+
+ virtual int decodeTag(unsigned char *buffer) = 0;
+ virtual int decodeLength(unsigned char *buffer) = 0;
+ virtual int decodeValue(unsigned char *buffer) = 0;
+
+ virtual TLVHelper *getChildTLV(ByteArray data) = 0;
+ TLVHelper *getParentTLV();
+
+ bool setTLVBuffer(const ByteArray &array, TLVHelper *parent);
+ bool setTLVBuffer(unsigned char *buffer, unsigned int length, TLVHelper *parent);
+
+ bool _isEndOfBuffer() { return offset >= tlvBuffer.getLength(); }
+ bool _decodeTLV();
+
+ unsigned int _getTag() { return currentT; }
+ unsigned int _getLength() { return currentL; }
+ ByteArray _getValue() { return currentV; }
+
+ public:
+ TLVHelper();
+ TLVHelper(const ByteArray &array);
+ ~TLVHelper();
+
+ bool setTLVBuffer(const ByteArray &array) { return setTLVBuffer(array, NULL); }
+ bool setTLVBuffer(unsigned char *buffer, unsigned int length) { return setTLVBuffer(buffer, length, NULL); }
+
+ bool isEndOfBuffer() { return currentTLV->_isEndOfBuffer(); }
+ bool decodeTLV() { return currentTLV->_decodeTLV(); }
+
+ unsigned int getTag() { return currentTLV->_getTag(); }
+ unsigned int getLength() { return currentTLV->_getLength(); }
+ ByteArray getValue() { return currentTLV->_getValue(); }
+
+ const char *toString();
+
+ bool enterToValueTLV();
+ bool returnToParentTLV();
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* TLVHELPER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 TERMINAL_H_
+#define TERMINAL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+#include "Synchronous.h"
+
+namespace smartcard_service_api
+{
+ typedef void (*terminalNotificationCallback)(void *terminal, int event, int error, void *user_param);
+
+ typedef void (*terminalTransmitCallback)(unsigned char *buffer, unsigned int length, int error, void *userParam);
+ typedef void (*terminalGetATRCallback)(unsigned char *buffer, unsigned int length, int error, void *userParam);
+
+ class Terminal : public Synchronous
+ {
+ protected:
+ terminalNotificationCallback statusCallback;
+ bool initialized;
+ char *name;
+
+ public:
+ static const int NOTIFY_SE_AVAILABLE = 1;
+ static const int NOTIFY_SE_NOT_AVAILABLE = -1;
+
+ Terminal()
+ {
+ statusCallback = NULL;
+ initialized = false;
+ name = NULL;
+ }
+ virtual ~Terminal() {}
+
+ virtual bool initialize() = 0;
+ virtual void finalize() = 0;
+ inline bool isInitialized() { return initialized; }
+
+ inline char *getName() { return name; }
+ inline void setStatusCallback(terminalNotificationCallback callback) { statusCallback = callback; }
+
+ virtual bool isSecureElementPresence() = 0;
+
+ virtual int transmitSync(ByteArray command, ByteArray &result) = 0;
+ virtual int getATRSync(ByteArray &atr) = 0;
+
+ virtual int transmit(ByteArray command, terminalTransmitCallback callback, void *userData) = 0;
+ virtual int getATR(terminalGetATRCallback callback, void *userData) = 0;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* TERMINAL_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 TERMINALINTERFACE_H_
+#define TERMINALINTERFACE_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+
+//typedef unsigned int terminal_handle_h;
+//
+//typedef enum
+//{
+// TERMINAL_SUCCESS = 0,
+//
+// TERMINAL_ERROR_UNKNOWN = -1,
+// /* TERMINAL_ERROR_ = -, */
+//} terminal_result_e;
+//
+//typedef char *(*terminal_get_name_fn)();
+//typedef terminal_result_e (*terminal_initialize_fn)(int param1, char *param2);
+//typedef terminal_result_e (*terminal_finalize_fn)(int param1, char *param2);
+//typedef terminal_result_e (*terminal_open_fn)(int param1, char *param2, terminal_handle_h *handle);
+//typedef terminal_result_e (*terminal_close_fn)(terminal_handle_h handle);
+//typedef terminal_result_e (*terminal_transmit_fn)(terminal_handle_h handle, unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int *resp_len);
+//typedef terminal_result_e (*terminal_get_atr_fn)(terminal_handle_h handle, unsigned char *atr, unsigned int *atr_len);
+//
+//typedef struct _terminal_interfaces_t
+//{
+// terminal_get_name_fn api_get_name;
+// terminal_initialize_fn api_initialize;
+// terminal_finalize_fn api_finalize;
+// terminal_open_fn api_open;
+// terminal_close_fn api_close;
+// terminal_transmit_fn api_transmit;
+// terminal_get_atr_fn api_get_atr;
+//} terminal_interfaces_t;
+//
+//typedef int (*terminal_get_interfaces_fn)(terminal_interfaces_t *apis);
+
+typedef const char *(*terminal_get_name_fn)();
+typedef void *(*terminal_create_instance_fn)();
+typedef void (*terminal_destroy_instance_fn)(void *);
+
+#endif /* TERMINALINTERFACE_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SMARTCARD_TYPES_H_
+#define SMARTCARD_TYPES_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef void *se_service_h;
+typedef void *reader_h;
+typedef void *session_h;
+typedef void *channel_h;
+
+typedef void (*se_service_connected_cb)(se_service_h handle, void *context);
+typedef void (*se_service_event_cb)(se_service_h handle, char *se_name, int event, void *context);
+typedef void (*se_sesrvice_error_cb)(se_service_h handle, int error, void *context);
+
+typedef void (*reader_open_session_cb)(session_h session, int error, void *user_data);
+
+typedef void (*session_open_channel_cb)(channel_h channel, int error, void *user_data);
+typedef void (*session_get_atr_cb)(unsigned char *atr, unsigned int length, int error, void *user_data);
+typedef void (*session_close_session_cb)(int error, void *user_data);
+typedef void (*session_get_channel_count_cb)(unsigned count, int error, void *user_data);
+
+typedef void (*channel_transmit_cb)(unsigned char *buffer, unsigned int length, int error, void *user_data);
+typedef void (*channel_close_cb)(int error, void *user_data);
+
+#endif /* SMARTCARD_TYPES_H_ */
--- /dev/null
+# Package Information for pkg-config
+
+prefix=/usr
+exec_prefix=${prefix}/bin
+includedir=${prefix}/include
+libdir=${prefix}/lib
+
+Name: smartcard-service-common
+Description: Make flags of Common library of Smartcard service
+Version: 1.0
+Requires:
+Libs: -L${libdir} -lsmartcard-service-common
+Cflags: -I${includedir}/smartcard-service-common
\ No newline at end of file
--- /dev/null
+smartcard-service (0.1.0-3) unstable; urgency=low
+
+ * add an exceptional case when is openning client channel (nfc-manager)
+ * Git: slp/pkgs/s/smartcard-service
+ * Tag: smartcard-service_0.1.0-3
+
+ -- Wonkyu Kwon <wonkyu.kwon@samsung.com> Fri, 20 Apr 2012 11:00:00 +0900
+
+smartcard-service (0.1.0-2) unstable; urgency=low
+
+ * add helpers for openssl and package signature
+ * Git: slp/pkgs/s/smartcard-service
+ * Tag: smartcard-service_0.1.0-2
+
+ -- Wonkyu Kwon <wonkyu.kwon@samsung.com> Fri, 23 Mar 2012 12:40:00 +0900
+
+smartcard-service (0.1.0-1) unstable; urgency=low
+
+ * Upload package
+ * Git: slp/pkgs/s/smartcard-service
+ * Tag: smartcard-service_0.1.0-1
+
+ -- Wonkyu Kwon <wonkyu.kwon@samsung.com> Wed, 14 Mar 2012 13:30:00 +0900
+
+smartcard-service (0.0.0-4) unstable; urgency=low
+
+ * Upload package
+ * Git: slp/pkgs/s/smartcard-service
+ * Tag: smartcard-service_0.0.0-4
+
+ -- Wonkyu Kwon <wonkyu.kwon@samsung.com> Tue, 13 Mar 2012 13:10:00 +0900
+
+smartcard-service (0.0.0-3) unstable; urgency=low
+
+ * namespace and macro name change
+ * Git: slp/pkgs/s/smartcard-service
+ * Tag: smartcard-service_0.0.0-3
+
+ -- Sangsoo Lee <constant.lee@samsung.com> Wed, 07 Mar 2012 19:26:46 +0900
+
+smartcard-service (0.0.0-2) unstable; urgency=low
+
+ * getChannelCount api add
+ * Git: slp/pkgs/s/smartcard-service
+ * Tag: smartcard-service_0.0.0-2
+
+ -- Sangsoo Lee <constant.lee@samsung.com> Thu, 23 Feb 2012 21:10:42 +0900
+
+smartcard-service (0.0.0-1) unstable; urgency=low
+
+ * Initial release
+ * Git: slp/pkgs/s/smartcard-service
+ * Tag: smartcard-service_0.0.0-1
+
+ -- Wonkyu Kwon <wonkyu.kwon@samsung.com> Thu, 31 Jan 2012 00:00:00 +0900
--- /dev/null
+Source: smartcard-service
+Priority: extra
+Maintainer: Wonkyu Kwon <wonkyu.kwon@samsung.com>, Sangsoo Lee <constant.lee@samsung.com>, Sungjae Lim <sungjae.lim@samsung.com>, Junyong Sim <junyong.sim@samsung.com>, Sechang Sohn <sc.sohn@samsung.com>
+Build-Depends: debhelper (>= 8.0.0), libglib2.0-dev, libvconf-dev, libsecurity-server-client-dev, dlog-dev, wrt-commons-dev, libaul-1-dev, libssl-dev
+#Build-Depends: debhelper (>= 8.0.0), libglib2.0-dev, libvconf-dev, libsecurity-server-client-dev, dlog-dev, libpkcs11-helper1-dev, wrt-commons, libaul-dev, libssl-dev
+#Standards-Version: 3.9.2
+Section: mixed
+Homepage: <insert the upstream URL, if relevant>
+#Vcs-Git: git://git.debian.org/collab-maint/smartcard-service.git
+#Vcs-Browser: http://git.debian.org/?p=collab-maint/smartcard-service.git;a=summary
+
+Package: smartcard-service-common
+Section: libs
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Common library of Smart card service
+ Common library of Smart card service
+
+Package: smartcard-service-common-dev
+Section: libdevel
+Architecture: any
+Depends: smartcard-service-common (= ${binary:Version})
+Description: Common library of Smart card service
+ Common library of Smart card service
+
+Package: smartcard-service-common-dbg
+Section: debug
+Architecture: any
+Depends: smartcard-service-common (= ${binary:Version})
+Description: Common library of Smart card service (unstripped)
+ Common library of Smart card service (unstripped)
+
+Package: smartcard-service-server
+Architecture: any
+Depends: smartcard-service-common-dev (= ${binary:Version})
+Description: Main process of Smart card service
+ Main process of Smart card service
+
+Package: smartcard-service-server-dbg
+Section: debug
+Architecture: any
+Depends: smartcard-service-server (= ${binary:Version})
+Description: Main process of Smart card service (unstripped)
+ Main process of Smart card service (unstripped)
+
+Package: smartcard-service
+Section: libs
+Architecture: any
+Depends: smartcard-service-common-dev (= ${binary:Version})
+Description: User library of Smart card service
+ User library of Smart card service
+
+Package: smartcard-service-dev
+Section: libdevel
+Architecture: any
+Depends: smartcard-service (= ${binary:Version})
+Description: User library of Smart card service
+ User library of Smart card service
+
+Package: smartcard-service-dbg
+Section: debug
+Architecture: any
+Depends: smartcard-service (= ${binary:Version})
+Description: User library of Smart card service (unstripped)
+ User library of Smart card service (unstripped)
--- /dev/null
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+override_dh_auto_build:
+
+ cd $(CMAKE_BINARY_DIR)
+ dh_auto_build
+
+override_dh_install:
+
+ mkdir -p $(CURDIR)/debian/tmp/etc/init.d
+ mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/
+ mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/
+
+ cp -af $(CURDIR)/debian/smartcard-service-server.init $(CURDIR)/debian/tmp/etc/init.d/smartcard-service-server
+ ln -s ../init.d/smartcard-service-server $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/S79smartcard-service-server
+ ln -s ../init.d/smartcard-service-server $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/S79smartcard-service-server
+
+ dh_install
+
+override_dh_installinit:
+
+%:
+ dh $@
+
--- /dev/null
+usr/lib
+usr/include
--- /dev/null
+usr/include/smartcard-service-common/*
+#usr/lib/lib*.a
+usr/lib/libsmartcard-service-common.so
+usr/lib/pkgconfig/smartcard-service-common.pc
+#usr/share/pkgconfig/*
--- /dev/null
+usr/lib/libsmartcard-service-common.so.*
--- /dev/null
+usr/lib
+usr/include
--- /dev/null
+usr/include/smartcard-service/*
+#usr/lib/lib*.a
+usr/lib/libsmartcard-service.so
+usr/lib/pkgconfig/smartcard-service.pc
+#usr/share/pkgconfig/*
--- /dev/null
+usr/bin
+etc
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+### BEGIN INIT INFO
+# Provides: smartcard-service-server
+# Required-Start: $network $local_fs
+# Required-Stop:
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: <Enter a short description of the sortware>
+# Description: <Enter a long description of the software>
+# <...>
+# <...>
+### END INIT INFO
+
+# Author: Wonkyu Kwon <wonkyu.kwon@samsung.com>
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/usr/bin
+DESC=smartcard-daemon # Introduce a short description here
+NAME=smartcard-daemon # Introduce the short server's name here
+DAEMON=/usr/bin/smartcard-daemon # Introduce the server's location here
+DAEMON_ARGS="" # Arguments to run the daemon with
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+
+# Exit if the package is not installed
+[ -x $DAEMON ] || exit 0
+
+$DAEMON $DAEMON_ARGS &
\ No newline at end of file
--- /dev/null
+usr/bin/smartcard-daemon
+etc/*
\ No newline at end of file
--- /dev/null
+usr/lib/libsmartcard-service.so.*
--- /dev/null
+#!/bin/sh
+### BEGIN INIT INFO
+# Provides: smartcard-service-server
+# Required-Start: $network $local_fs
+# Required-Stop:
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: <Enter a short description of the sortware>
+# Description: <Enter a long description of the software>
+# <...>
+# <...>
+### END INIT INFO
+
+# Author: Wonkyu Kwon <wonkyu.kwon@samsung.com>
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/usr/bin
+DESC=smartcard-daemon # Introduce a short description here
+NAME=smartcard-daemon # Introduce the short server's name here
+DAEMON=/usr/bin/smartcard-daemon # Introduce the server's location here
+DAEMON_ARGS="" # Arguments to run the daemon with
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+
+# Exit if the package is not installed
+[ -x $DAEMON ] || exit 0
+
+$DAEMON $DAEMON_ARGS &
\ No newline at end of file
--- /dev/null
+Name: smartcard-service
+Summary: Smartcard Service FW
+Version: 0.1.0
+Release: 8
+Group: libs
+License: Samsung Proprietary License
+Source0: %{name}-%{version}.tar.gz
+Source1: smartcard-service-server.init
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(security-server)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(libssl)
+BuildRequires: pkgconfig(aul)
+BuildRequires: pkgconfig(dpl-wrt-dao-ro)
+BuildRequires: cmake
+BuildRequires: gettext-tools
+Requires(post): /sbin/ldconfig
+Requires(post): /usr/bin/vconftool
+requires(postun): /sbin/ldconfig
+
+%description
+Smartcard Service FW.
+
+%prep
+%setup -q
+
+%package devel
+Summary: smartcard service
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+smartcard service.
+
+%package -n smartcard-service-common
+Summary: common smartcard service
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description -n smartcard-service-common
+common smartcard service.
+
+%package -n smartcard-service-common-devel
+Summary: common smartcard service
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description -n smartcard-service-common-devel
+common smartcard service.
+
+%package -n smartcard-service-server
+Summary: server smartcard service
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description -n smartcard-service-server
+smartcard service.
+
+%build
+mkdir obj-arm-limux-qnueabi
+cd obj-arm-limux-qnueabi
+cmake .. -DCMAKE_INSTALL_PREFIX=%{_prefix}
+#make %{?jobs:-j%jobs}
+
+%install
+cd obj-arm-limux-qnueabi
+%make_install
+%__mkdir -p %{buildroot}/etc/init.d/
+%__mkdir -p %{buildroot}/etc/rc.d/rc3.d/
+%__mkdir -p %{buildroot}/etc/rc.d/rc5.d/
+%__cp -af %SOURCE1 %{buildroot}/etc/init.d/smartcard-service-server
+chmod 755 %{buildroot}/etc/init.d/smartcard-service-server
+
+%post
+/sbin/ldconfig
+
+ln -sf /etc/init.d/smartcard-service-server /etc/rc.d/rc3.d/S79smartcard-service-server
+ln -sf /etc/init.d/smartcard-service-server /etc/rc.d/rc5.d/S79smartcard-service-server
+
+%postun
+/sbin/ldconfig
+
+rm -f /etc/rc.d/rc3.d/S79smartcard-service-server
+rm -f /etc/rc.d/rc5.d/S79smartcard-service-server
+
+#%post
+# -n nfc-common-lib -p /sbin/ldconfig
+
+#%postun
+# -n nfc-common-lib -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+/usr/lib/libsmartcard-service.so.*
+
+%files devel
+%defattr(-,root,root,-)
+/usr/include/smartcard-service/*
+/usr/lib/libsmartcard-service.so
+/usr/lib/pkgconfig/smartcard-service.pc
+
+%files -n smartcard-service-common
+%defattr(-,root,root,-)
+/usr/lib/libsmartcard-service-common.so.*
+
+%files -n smartcard-service-common-devel
+%defattr(-,root,root,-)
+/usr/include/smartcard-service-common/*
+/usr/lib/libsmartcard-service-common.so
+/usr/lib/pkgconfig/smartcard-service-common.pc
+
+%files -n smartcard-service-server
+%defattr(-,root,root,-)
+/usr/bin/smartcard-daemon
+#/usr/bin/smartcard-test-client
+/etc/init.d/smartcard-service-server
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(smartcard-daemon CXX)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ SRCS)
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+ SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_server REQUIRED glib-2.0 gobject-2.0 security-server vconf dlog)
+
+FOREACH(flag ${pkgs_server_CFLAGS})
+ SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+MESSAGE("CHECK MODULE in ${PROJECT_NAME} ${pkgs_server_LDFLAGS}")
+
+# this for NFC flag
+
+SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -pipe -fomit-frame-pointer -Wall -Wno-trigraphs -fno-strict-aliasing -Wl,-zdefs -fvisibility=hidden")
+
+SET(ARM_CXXFLAGS "${ARM_CXXLAGS} -mapcs -mno-sched-prolog -mabi=aapcs-linux -mno-thumb-interwork -msoft-float -Uarm -fno-common -fpic")
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DTARGET")
+ MESSAGE("add -DTARGET")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM_CXXFLAGS}")
+ENDIF()
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DLOG_TAG=\"SCARD_SERVER\"")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_server_LDFLAGS} "-L../common" "-lsmartcard-service-common" "-pie -ldl")
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <pthread.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ClientInstance.h"
+#include "ServerResource.h"
+#include "SignatureHelper.h"
+
+namespace smartcard_service_api
+{
+ void ClientInstance::setPID(int pid)
+ {
+ this->pid = pid;
+
+#if 0
+ if (pid > 0)
+ {
+ certHash = SignatureHelper::getCertificationHash(pid);
+ }
+#endif
+ }
+
+ bool ClientInstance::createService(unsigned int context)
+ {
+ bool result = false;
+
+ if (getService(context) == NULL)
+ {
+ ServiceInstance *instance = new ServiceInstance(this, context);
+ if (instance != NULL)
+ {
+ mapServices.insert(make_pair(context, instance));
+ result = true;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("service already exist [%d]", context);
+ }
+
+ return result;
+ }
+
+ ServiceInstance *ClientInstance::getService(unsigned int context)
+ {
+ ServiceInstance *result = NULL;
+ map<unsigned int, ServiceInstance *>::iterator item;
+
+ if ((item = mapServices.find(context)) != mapServices.end())
+ {
+ result = item->second;
+ }
+
+ return result;
+ }
+
+ void ClientInstance::removeService(unsigned int context)
+ {
+ map<unsigned int, ServiceInstance *>::iterator item;
+
+ if ((item = mapServices.find(context)) != mapServices.end())
+ {
+ delete item->second;
+ mapServices.erase(item);
+ }
+ }
+
+ void ClientInstance::removeServices()
+ {
+ map<unsigned int, ServiceInstance *>::iterator item;
+
+ for (item = mapServices.begin(); item != mapServices.end(); item++)
+ {
+ delete item->second;
+ }
+
+ mapServices.clear();
+ }
+
+ bool ClientInstance::sendMessageToAllServices(int socket, Message &msg)
+ {
+ bool result = true;
+ map<unsigned int, ServiceInstance *>::iterator item;
+
+ for (item = mapServices.begin(); item != mapServices.end(); item++)
+ {
+ if (ServerIPC::getInstance()->sendMessage(socket, &msg) == false)
+ result = false;
+ }
+
+ return result;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "ServerChannel.h"
+#include "APDUHelper.h"
+
+namespace smartcard_service_api
+{
+ ServerChannel::ServerChannel(ServerSession *session, void *caller, int channelNum, Terminal *terminal):Channel(session)
+ {
+ this->terminal = terminal;
+ this->caller = caller;
+ this->channelNum = channelNum;
+ }
+
+ ServerChannel::~ServerChannel()
+ {
+ if (isClosed() == false)
+ {
+ closeSync();
+ }
+ }
+
+ void ServerChannel::closeSync()
+ {
+ ByteArray command, result;
+ APDUHelper apdu;
+ int rv;
+
+ if (isBasicChannel() == false)
+ {
+ /* close channel */
+ command = apdu.generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
+ rv = terminal->transmitSync(command, result);
+
+ if (rv == 0 && result.getLength() >= 2)
+ {
+ ResponseHelper resp(result);
+
+ if (resp.getStatus() == 0)
+ {
+ SCARD_DEBUG("close success");
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, result.getLength());
+ }
+ }
+
+ channelNum = -1;
+ }
+
+ int ServerChannel::getChannelNumber()
+ {
+ return channelNum;
+ }
+
+ int ServerChannel::transmitSync(ByteArray command, ByteArray &result)
+ {
+ APDUCommand helper;
+
+ if (session != NULL) /* admin channel */
+ {
+ helper.setCommand(command);
+
+ /* filter command */
+ if ((helper.getINS() == APDUCommand::INS_SELECT_FILE && helper.getP1() == APDUCommand::P1_SELECT_BY_DF_NAME) ||
+ (helper.getINS() == APDUCommand::INS_MANAGE_CHANNEL))
+ {
+ return -4; /* security reason */
+ }
+
+ /* insert channel ID */
+ helper.setChannel(0, channelNum);
+
+ helper.getBuffer(command);
+ }
+
+ SCARD_DEBUG("command [%d] : %s", command.getLength(), command.toString());
+
+ return terminal->transmitSync(command, result);
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServerDispatcher.h"
+#include "ServerResource.h"
+#include "ServerSEService.h"
+#include "ServerChannel.h"
+#include "ServerSession.h"
+#include "ServerReader.h"
+
+namespace smartcard_service_api
+{
+ ServerDispatcher::ServerDispatcher():DispatcherHelper()
+ {
+ SCARD_BEGIN();
+
+ runDispatcherThread();
+
+ SCARD_END();
+ }
+
+ ServerDispatcher::~ServerDispatcher()
+ {
+ }
+
+ ServerDispatcher *ServerDispatcher::getInstance()
+ {
+ static ServerDispatcher instance;
+
+ return &instance;
+ }
+
+ void *ServerDispatcher::dispatcherThreadFunc(DispatcherMsg *msg, void *data)
+ {
+ int socket = -1;
+ ServerResource *resource = NULL;
+
+ if (data == NULL)
+ {
+ SCARD_DEBUG_ERR("dispatcher instance is null");
+ return NULL;
+ }
+
+ if (msg == NULL)
+ {
+ SCARD_DEBUG_ERR("message is null");
+ return NULL;
+ }
+
+ resource = &ServerResource::getInstance();
+ socket = msg->getPeerSocket();
+
+ switch (msg->message)
+ {
+ /* handle message */
+ case Message::MSG_REQUEST_READERS :
+ {
+ SCARD_DEBUG("[MSG_REQUEST_READERS]");
+
+#if 0
+ seService->dispatcherCallback(msg, msg->getPeerSocket());
+#else
+ int count = 0;
+ Message response(*msg);
+ ByteArray info;
+ ClientInstance *instance = NULL;
+
+ if ((instance = resource->getClient(socket)) != NULL)
+ {
+ /* update client PID */
+ if (instance->getPID() == -1)
+ {
+ instance->setPID(msg->error);
+ SCARD_DEBUG_ERR("update PID [%d]", msg->error);
+ }
+
+ /* create service */
+ if (resource->getService(socket, (unsigned int)msg->userParam) == NULL)
+ {
+ if (resource->createService(socket, (unsigned int)msg->userParam) == true)
+ {
+ SCARD_DEBUG_ERR("client added : context [%d]", (unsigned int)msg->userParam);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("createClient failed");
+
+ response.param1 = 0;
+ response.error = -1;
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+
+ return NULL;
+ }
+ }
+
+ if ((count = resource->getReadersInformation(info)) > 0)
+ {
+ response.param1 = count;
+ response.param2 = 0;
+ response.error = 0;
+ response.data = info;
+ }
+ else
+ {
+ SCARD_DEBUG("no secure elements");
+
+ response.error = -1;
+ }
+ }
+ else
+ {
+ SCARD_DEBUG("client doesn't exist, socket [%d]", socket);
+
+ response.error = -1;
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+#endif
+ }
+ break;
+
+ case Message::MSG_REQUEST_SHUTDOWN :
+#if 0
+ {
+ Message response(*msg);
+
+ SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
+
+ if (msg->param1 != 0)
+ {
+ ServerChannel *channel = NULL;
+
+ channel = (ServerChannel *)msg->param1;
+
+ channel->closeSync();
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+ }
+#else
+ {
+ Message response(*msg);
+
+ SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
+
+ response.error = 0;
+
+ resource->removeService(socket, msg->error/* service context */);
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+ }
+#endif
+ break;
+
+ case Message::MSG_REQUEST_OPEN_SESSION :
+#if 0
+ {
+ Message response(*msg);
+ ServerReader *reader = NULL;
+ ServerSession *session = NULL;
+
+ SCARD_DEBUG("[MSG_REQUEST_OPEN_SESSION]");
+
+ if (msg->param1 != 0)
+ {
+ reader = (ServerReader *)msg->param1;
+
+ session = reader->openSessionSync(msg->data, msg->caller);
+ }
+
+ /* TODO : attach atr??? */
+ response.param1 = (unsigned int)session;
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+ }
+#else
+ {
+ Message response(*msg);
+ unsigned int handle = -1;
+
+ SCARD_DEBUG("[MSG_REQUEST_OPEN_SESSION]");
+
+ response.param1 = -1;
+ response.error = -1;
+
+ if (resource->isValidReaderHandle(msg->param1))
+ {
+ handle = resource->createSession(socket, msg->error/* service context */, msg->param1, msg->data, msg->caller);
+ if (handle != IntegerHandle::INVALID_HANDLE)
+ {
+ response.param1 = handle;
+ response.error = 0;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("createSession failed [%d]", handle);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("request invalid reader handle [%d]", msg->param1);
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+ }
+#endif
+ break;
+
+ case Message::MSG_REQUEST_CLOSE_SESSION :
+#if 0
+ {
+ Message response(*msg);
+ ServerSession *session = NULL;
+
+ SCARD_DEBUG("[MSG_REQUEST_CLOSE_SESSION]");
+
+ if (msg->param1 != 0)
+ {
+ session = (ServerSession *)msg->param1;
+
+ session->closeSync();
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+ }
+#else
+ {
+ Message response(*msg);
+
+ SCARD_DEBUG("[MSG_REQUEST_CLOSE_SESSION]");
+
+ response.param1 = -1;
+ response.error = -1;
+
+ if (resource->isValidSessionHandle(socket, msg->error/* service context */, msg->param1))
+ {
+ resource->removeSession(socket, msg->error/* service context */, msg->param1);
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+ }
+#endif
+ break;
+
+ case Message::MSG_REQUEST_OPEN_CHANNEL :
+#if 0
+ {
+ Message response(*msg);
+ ServerSession *session = NULL;
+
+ SCARD_DEBUG("[MSG_REQUEST_OPEN_CHANNEL]");
+
+ if (/* check valid session handle */msg->param2 != 0)
+ {
+ ServerChannel *channel = NULL;
+
+ session = (ServerSession *)msg->param2;
+
+ if (msg->param1 == 0)
+ channel = (ServerChannel *)session->openBasicChannelSync(msg->data, msg->caller);
+ else
+ channel = (ServerChannel *)session->openLogicalChannelSync(msg->data, msg->caller);
+
+ if (channel != NULL)
+ {
+ response.param1 = (unsigned int)channel;
+ response.param2 = channel->getChannelID();
+ response.error = 0;
+ response.data = channel->getSelectResponse();
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("channel is null.");
+
+ /* set error value */
+ response.param1 = 0;
+ response.param2 = 0;
+ response.error = -4;
+ response.data.releaseBuffer();
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("session is invalid");
+
+ response.param1 = 0;
+ response.param2 = 0;
+ response.error = -1;
+ response.data.releaseBuffer();
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+ }
+#else
+ {
+ Message response(*msg);
+ unsigned int channelID = -1;
+
+ SCARD_DEBUG("[MSG_REQUEST_OPEN_CHANNEL]");
+
+ response.param1 = 0;
+ response.param2 = 0;
+ response.error = -1;
+ response.data.releaseBuffer();
+
+ channelID = resource->createChannel(socket, msg->error/* service context */, msg->param2, msg->param1, msg->data);
+ if (channelID != IntegerHandle::INVALID_HANDLE)
+ {
+ ServerChannel *temp = (ServerChannel *)resource->getChannel(socket, msg->error/* service context */, channelID);
+
+ if (temp != NULL)
+ {
+ response.param1 = channelID;
+ response.param2 = temp->channelNum;
+ response.error = 0;
+ response.data = temp->selectResponse;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("IS IT POSSIBLE??????????????????");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("channel is null.");
+
+ /* set error value */
+ response.error = -4;
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+ }
+#endif
+ break;
+
+ case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
+ {
+ Message response(*msg);
+
+ SCARD_DEBUG("[MSG_REQUEST_GET_CHANNEL_COUNT]");
+
+ response.error = 0;
+
+ response.param1 = resource->getChannelCount(socket, msg->error/* service context */, msg->param1);
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+ }
+ break;
+
+ case Message::MSG_REQUEST_CLOSE_CHANNEL :
+#if 0
+ {
+ Message response(*msg);
+
+ SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
+
+ if (msg->param1 != 0)
+ {
+ ServerChannel *channel = NULL;
+
+ channel = (ServerChannel *)msg->param1;
+
+ channel->closeSync();
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+ }
+#else
+ {
+ Message response(*msg);
+
+ SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
+
+ response.error = 0;
+
+ if (resource->getChannel(socket, msg->error/* service context */, msg->param1) != NULL)
+ {
+ resource->removeChannel(socket, msg->error/* service context */, msg->param1);
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+ }
+#endif
+ break;
+
+ case Message::MSG_REQUEST_GET_ATR :
+#if 0
+ {
+ Message response(*msg);
+
+ SCARD_DEBUG("[MSG_REQUEST_GET_ATR]");
+
+ if (msg->param1 != 0)
+ {
+ ServerChannel *channel = NULL;
+
+ channel = (ServerChannel *)msg->param1;
+
+ channel->closeSync();
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+ }
+#else
+ {
+ int rv;
+ Message response(*msg);
+ ByteArray result;
+ ServiceInstance *client = NULL;
+
+ SCARD_DEBUG("[MSG_REQUEST_GET_ATR]");
+
+ response.param1 = 0;
+ response.param2 = 0;
+ response.error = -1;
+
+ if ((client = resource->getService(socket, msg->error/* service context */)) != NULL)
+ {
+ Terminal *terminal = NULL;
+
+ if ((terminal = client->getTerminal(msg->param1)) != NULL)
+ {
+ if ((rv = terminal->getATRSync(result)) == 0)
+ {
+ response.data = result;
+ response.error = 0;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("transmit failed [%d]", rv);
+
+ response.error = rv;
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("getTerminal failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("getClient failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+ }
+#endif
+ break;
+
+ case Message::MSG_REQUEST_TRANSMIT :
+#if 0
+ {
+ Message response(*msg);
+ ByteArray result;
+ int rv;
+
+ SCARD_DEBUG("[MSG_REQUEST_TRANSMIT]");
+
+ if (msg->param1 != 0)
+ {
+ ServerChannel *channel = NULL;
+
+ channel = (ServerChannel *)msg->param1;
+
+ if ((rv = channel->transmitSync(msg->data, result)) == 0)
+ {
+ response.data = result;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("transmit failed [%d]", rv);
+ }
+ }
+
+// if (resource->isValidChannelHandle((void *)msg->param1))
+// {
+// }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+ }
+#else
+ {
+ int rv;
+ Message response(*msg);
+ ByteArray result;
+ Channel *channel = NULL;
+
+ SCARD_DEBUG("[MSG_REQUEST_TRANSMIT]");
+
+ response.param1 = 0;
+ response.param2 = 0;
+ response.error = -1;
+
+ if ((channel = resource->getChannel(socket, msg->error/* service context */, msg->param1)) != NULL)
+ {
+ if ((rv = channel->transmitSync(msg->data, result)) == 0)
+ {
+ response.data = result;
+ response.error = 0;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("transmit failed [%d]", rv);
+
+ response.error = rv;
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("invalid handle : socket [%d], context [%d], channel [%d]", socket, msg->error/* service context */, msg->param1);
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+ }
+#endif
+ break;
+
+ case Message::MSG_OPERATION_RELEASE_CLIENT :
+#if 0
+ {
+ Message response(*msg);
+
+ SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
+
+ if (msg->param1 != 0)
+ {
+ ServerChannel *channel = NULL;
+
+ channel = (ServerChannel *)msg->param1;
+
+ channel->closeSync();
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+ }
+#else
+ {
+ SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
+
+ resource->removeClient(msg->param1);
+ }
+#endif
+ break;
+
+ default :
+ SCARD_DEBUG("unknown message [%s], socket [%d]", msg->toString(), socket);
+ break;
+ }
+
+ return NULL;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServerIPC.h"
+#include "ServerResource.h"
+#include "ServerDispatcher.h"
+
+namespace smartcard_service_api
+{
+ ServerIPC::ServerIPC():IPCHelper()
+ {
+ SCARD_BEGIN();
+
+ setDispatcher(ServerDispatcher::getInstance());
+
+ SCARD_END();
+ }
+
+ ServerIPC::~ServerIPC()
+ {
+ }
+
+ ServerIPC *ServerIPC::getInstance()
+ {
+ static ServerIPC instance;
+
+ return &instance;
+ }
+
+ bool ServerIPC::acceptClient()
+ {
+ GIOCondition condition = (GIOCondition)(G_IO_ERR | G_IO_HUP | G_IO_IN);
+ socklen_t addrlen = 0;
+ int client_sock_fd = 0;
+ GIOChannel *client_channel = NULL;
+ int client_src_id;
+
+ SCARD_DEBUG("client is trying to connect to server");
+
+ pthread_mutex_lock(&ipcLock);
+ client_sock_fd = accept(ipcSocket, NULL, &addrlen);
+ pthread_mutex_unlock(&ipcLock);
+
+ if (client_sock_fd < 0)
+ {
+ SCARD_DEBUG_ERR("can not accept client");
+ goto ERROR;
+ }
+
+ SCARD_DEBUG("client is accepted by server");
+
+ if ((client_channel = g_io_channel_unix_new(client_sock_fd)) == NULL)
+ {
+ SCARD_DEBUG_ERR("create new g io channel is failed");
+ goto ERROR;
+ }
+
+ if ((client_src_id = g_io_add_watch(client_channel, condition, &IPCHelper::channelCallbackFunc, this)) < 1)
+ {
+ SCARD_DEBUG_ERR("add io callback is failed");
+ goto ERROR;
+ }
+
+ SCARD_DEBUG("client socket is bound with g_io_channel");
+
+ if (ServerResource::getInstance().createClient(client_channel, client_sock_fd, client_src_id, 0, -1) == false)
+ {
+ SCARD_DEBUG_ERR("failed to add client");
+ }
+
+ return true;
+
+ERROR :
+ if (client_channel != NULL)
+ {
+ g_io_channel_unref(client_channel);
+ }
+
+ if (client_sock_fd != -1)
+ {
+ shutdown(client_sock_fd, SHUT_RDWR);
+ close(client_sock_fd);
+ }
+
+ return false;
+ }
+
+ void ServerIPC::restartServerIPC()
+ {
+ if (watchId != 0)
+ {
+ g_source_remove(watchId);
+ watchId = 0;
+ }
+
+ if (ioChannel != NULL)
+ {
+ g_io_channel_unref(ioChannel);
+ ioChannel = NULL;
+ }
+
+ if (ipcSocket != -1)
+ {
+ shutdown(ipcSocket, SHUT_RDWR);
+ close(ipcSocket);
+
+ ipcSocket = -1;
+ }
+
+ createListenSocket();
+ }
+
+ void ServerIPC::releaseClient(void *channel, int socket, int watchID)
+ {
+ if (watchID != 0)
+ {
+ g_source_remove(watchID);
+ }
+
+ if (channel != NULL)
+ {
+ g_io_channel_unref((GIOChannel *)channel);
+ }
+
+ if (socket >= 0)
+ {
+ shutdown(socket, SHUT_RDWR);
+ close(socket);
+ }
+ }
+
+ int ServerIPC::handleIOErrorCondition(void *channel, GIOCondition condition)
+ {
+ SCARD_BEGIN();
+
+ if(channel == ioChannel)
+ {
+ SCARD_DEBUG("server socket is closed");
+ restartServerIPC();
+ }
+ else
+ {
+ DispatcherMsg *dispMsg = NULL;
+ int peerSocket = g_io_channel_unix_get_fd((GIOChannel *)channel);
+
+ SCARD_DEBUG("client socket is closed, socket [%d]", peerSocket);
+
+ /* push messsage to dispatcher */
+ dispMsg = new DispatcherMsg();
+
+ dispMsg->message = Message::MSG_OPERATION_RELEASE_CLIENT;
+ dispMsg->param1 = peerSocket;
+ dispMsg->setPeerSocket(peerSocket);
+
+ /* push to dispatcher */
+ ServerDispatcher::getInstance()->pushMessage(dispMsg);
+ }
+
+ SCARD_END();
+
+ return FALSE;
+ }
+
+ int ServerIPC::handleInvalidSocketCondition(void *channel, GIOCondition condition)
+ {
+ SCARD_BEGIN();
+ SCARD_END();
+
+ return FALSE;
+ }
+
+ int ServerIPC::handleIncomingCondition(void *channel, GIOCondition condition)
+ {
+ int result = FALSE;
+
+ SCARD_BEGIN();
+
+ if(channel == ioChannel)
+ {
+ /* connect state. should accept */
+ SCARD_DEBUG("new client connected");
+
+ result = acceptClient();
+ }
+ else
+ {
+ int peerSocket = g_io_channel_unix_get_fd((GIOChannel *)channel);
+
+ SCARD_DEBUG("data incomming from [%d]", peerSocket);
+
+ if (peerSocket >= 0)
+ {
+ Message *msg = NULL;
+
+ /* read message */
+ if ((msg = retrieveMessage(peerSocket)) != NULL)
+ {
+ DispatcherMsg *dispMsg = new DispatcherMsg(msg, peerSocket);
+
+ /* push to dispatcher */
+ ServerDispatcher::getInstance()->pushMessage(dispMsg);
+
+ result = TRUE;
+
+ delete msg;
+ }
+ else
+ {
+ /* clear client connection */
+ SCARD_DEBUG_ERR("retrieve message failed, socket [%d]", peerSocket);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("client context doesn't exist, socket [%d]", peerSocket);
+ }
+ }
+
+ SCARD_END();
+
+ return result;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServerSEService.h"
+#include "ServerReader.h"
+#include "GPSEACL.h"
+
+namespace smartcard_service_api
+{
+ ServerReader::ServerReader(ServerSEService *seService, char *name, Terminal *terminal):ReaderHelper()
+ {
+ unsigned int length = 0;
+
+ acList = NULL;
+
+ if (seService == NULL || name == NULL || strlen(name) == 0 || terminal == NULL)
+ {
+ SCARD_DEBUG_ERR("invalid param");
+
+ return;
+ }
+
+ this->terminal = terminal;
+ this->seService = seService;
+
+ length = strlen(name);
+ length = (length < sizeof(this->name)) ? length : sizeof(this->name);
+ memcpy(this->name, name, length);
+
+ /* open admin channel */
+ adminChannel = new ServerChannel(NULL, NULL, 0, terminal);
+ if (adminChannel == NULL)
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ }
+ }
+
+ ServerReader::~ServerReader()
+ {
+ closeSessions();
+
+ if (acList != NULL)
+ {
+ delete acList;
+ acList = NULL;
+ }
+
+ if (adminChannel != NULL)
+ {
+ delete adminChannel;
+ adminChannel = NULL;
+ }
+ }
+
+ void ServerReader::closeSessions()
+ {
+ size_t i;
+
+ for (i = 0; i < sessions.size(); i++)
+ {
+ if (sessions[i] != NULL)
+ ((ServerSession *)sessions[i])->closeSync();
+ }
+
+ sessions.clear();
+ }
+
+ AccessControlList *ServerReader::getAccessControlList()
+ {
+ if (acList == NULL)
+ {
+ /* load access control */
+ acList = new GPSEACL(adminChannel);
+ if (acList != NULL)
+ {
+ acList->loadACL();
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ }
+ }
+
+ return acList;
+ }
+
+ ServerSession *ServerReader::openSessionSync()
+ {
+ return openSessionSync(ByteArray::EMPTY, NULL);
+ }
+
+ ServerSession *ServerReader::openSessionSync(ByteArray packageCert, void *caller)
+ {
+ ServerSession *session = NULL;
+
+ session = new ServerSession(this, packageCert, caller, terminal);
+ if (session == NULL)
+ return session;
+
+ sessions.push_back(session);
+
+ return session;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <dirent.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServerResource.h"
+#include "TerminalInterface.h"
+#include "APDUHelper.h"
+#include "SignatureHelper.h"
+#include "GPSEACL.h"
+
+namespace smartcard_service_api
+{
+ unsigned int IntegerHandle::newHandle = 0;
+ set<unsigned int> IntegerHandle::setHandles;
+ PMutex IntegerHandle::mutexLock;
+
+ unsigned int IntegerHandle::assignHandle()
+ {
+ SCOPE_LOCK(mutexLock)
+ {
+ pair<set<unsigned int>::iterator, bool> result;
+
+ do
+ {
+ newHandle++;
+ if (newHandle == (unsigned int)-1)
+ {
+ newHandle = 1;
+ }
+
+ result = setHandles.insert(newHandle);
+
+ }
+ while (!result.second);
+ }
+
+ SCARD_DEBUG("assign handle : newHandle [%d]", newHandle);
+
+ return newHandle;
+ }
+
+ void IntegerHandle::releaseHandle(unsigned int handle)
+ {
+ SCARD_DEBUG("will be released : Handle [%d]", handle);
+
+ SCOPE_LOCK(mutexLock)
+ {
+ setHandles.erase(handle);
+ }
+ }
+
+#define OMAPI_SE_PATH "/usr/lib/se"
+
+ ServerResource::ServerResource()
+ {
+ SCARD_BEGIN();
+
+ serverIPC = ServerIPC::getInstance();
+ serverDispatcher = ServerDispatcher::getInstance();
+
+#if 1
+ loadSecureElements();
+#endif
+ SCARD_END();
+ }
+
+ ServerResource::~ServerResource()
+ {
+ }
+
+ ServerResource &ServerResource::getInstance()
+ {
+ static ServerResource serverResource;
+
+ return serverResource;
+ }
+
+ bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
+ {
+ bool result = false;
+
+ if (getClient(socket) == NULL)
+ {
+ ClientInstance *instance = new ClientInstance(ioChannel, socket, watchID, state, pid);
+ if (instance != NULL)
+ {
+ mapClients.insert(make_pair(socket, instance));
+ result = true;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("client already exist [%d]", socket);
+ }
+
+ return result;
+ }
+
+ ClientInstance *ServerResource::getClient(int socket)
+ {
+ ClientInstance *result = NULL;
+ map<int, ClientInstance *>::iterator item;
+
+ if ((item = mapClients.find(socket)) != mapClients.end())
+ {
+ result = item->second;
+ }
+
+ return result;
+ }
+
+ void ServerResource::setPID(int socket, int pid)
+ {
+ map<int, ClientInstance *>::iterator item;
+
+ if ((item = mapClients.find(socket)) != mapClients.end())
+ {
+ if (item->second->getPID() < 0)
+ item->second->setPID(pid);
+ }
+ }
+
+ void ServerResource::removeClient(int socket)
+ {
+ map<int, ClientInstance *>::iterator item;
+
+ if ((item = mapClients.find(socket)) != mapClients.end())
+ {
+ ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
+
+ delete item->second;
+ mapClients.erase(item);
+ }
+ else
+ {
+ SCARD_DEBUG("client exists already [%d]", socket);
+ }
+ }
+
+ void ServerResource::removeClients()
+ {
+ map<int, ClientInstance *>::iterator item;
+
+ for (item = mapClients.begin(); item != mapClients.end(); item++)
+ {
+ ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
+
+ delete item->second;
+ }
+
+ mapClients.clear();
+ }
+
+ bool ServerResource::createService(int socket, unsigned int context)
+ {
+ bool result = false;
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ if ((result = instance->createService(context)) == false)
+ {
+ SCARD_DEBUG_ERR("ClientInstance::createService failed [%d] [%d]", socket, context);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+ }
+
+ return result;
+ }
+
+ ServiceInstance *ServerResource::getService(int socket, unsigned int context)
+ {
+ ServiceInstance *result = NULL;
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ result = instance->getService(context);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeService(int socket, unsigned int context)
+ {
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ instance->removeService(context);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+ }
+ }
+
+ void ServerResource::removeServices(int socket)
+ {
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ instance->removeServices();
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+ }
+ }
+
+ Terminal *ServerResource::getTerminal(unsigned int terminalID)
+ {
+ Terminal *result = NULL;
+ map<unsigned int, Terminal *>::iterator item;
+
+ if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
+ {
+ result = item->second;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("Terminal doesn't exist [%d]", terminalID);
+ }
+
+ return result;
+ }
+
+ Terminal *ServerResource::getTerminal(const char *name)
+ {
+ Terminal *result = NULL;
+ map<unsigned int, Terminal *>::iterator item;
+
+ for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
+ {
+ if (strncmp(name, item->second->getName(), strlen(name)) == 0)
+ {
+ result = item->second;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ unsigned int ServerResource::createSession(int socket, unsigned int context, unsigned int terminalID, ByteArray packageCert, void *caller)
+ {
+ unsigned int result = -1;
+ Terminal *temp = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, context)) != NULL)
+ {
+ if ((temp = getTerminal(terminalID)) != NULL)
+ {
+ result = instance->openSession(temp, packageCert, caller);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+ }
+
+ return result;
+ }
+
+ ServerSession *ServerResource::getSession(int socket, unsigned int context, unsigned int sessionID)
+ {
+ ServerSession *result = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, context)) != NULL)
+ {
+ result = instance->getSession(sessionID);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("Session doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, sessionID);
+ }
+
+ return result;
+ }
+
+ unsigned int ServerResource::getChannelCount(int socket, unsigned int context, unsigned int sessionID)
+ {
+ unsigned int result = -1;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, context)) != NULL)
+ {
+ result = instance->getChannelCountBySession(sessionID);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeSession(int socket, unsigned int context, unsigned int sessionID)
+ {
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, context)) != NULL)
+ {
+ instance->closeSession(sessionID);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+ }
+ }
+
+ unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
+ {
+ unsigned int result = -1;
+ ServiceInstance *client = NULL;
+
+ if ((client = getService(socket, context)) != NULL)
+ {
+ if (client->isVaildSessionHandle(sessionID) == true)
+ {
+ AccessControlList *acList = NULL;
+ ServerSession *session = NULL;
+ Terminal *terminal = NULL;
+
+ terminal = client->getTerminal(sessionID);
+ session = client->getSession(sessionID);
+ if (terminal != NULL && session != NULL)
+ {
+ int rv = 0;
+ int channelNum = 0;
+ ByteArray certHash;
+ ByteArray selectResponse;
+ ByteArray command;
+ char filename[1024] = { 0, };
+
+ /* check exceptional case */
+ SignatureHelper::getProcessName(client->getParent()->getPID(), filename, sizeof(filename));
+ if (strncmp(filename, "ozD3Dw1MZruTDKHWGgYaDib2B2LV4/nfT+8b/g1Vsk8=", sizeof(filename)) != 0)
+ {
+#if 1
+ certHash = session->packageCert;
+#else
+ certHash = client->getParent()->getCertificationHash();
+#endif
+ /* request open channel sequence */
+ if ((acList = getAccessControlList(terminal)) == NULL)
+ {
+ SCARD_DEBUG_ERR("acList is null");
+
+ return result;
+ }
+
+ if (acList->isAuthorizedAccess(aid, certHash) == false)
+ {
+ SCARD_DEBUG_ERR("unauthorized access, aid %s, hash %s", aid.toString(), certHash.toString());
+
+ return result;
+ }
+ }
+
+ if (channelType == 1)
+ {
+ ByteArray response;
+
+ /* open channel */
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
+ rv = terminal->transmitSync(command, response);
+
+ if (rv == 0 && response.getLength() >= 2)
+ {
+ ResponseHelper resp(response);
+
+ if (resp.getStatus() == 0)
+ {
+ channelNum = resp.getDataField()[0];
+
+ SCARD_DEBUG("channelNum [%d]", channelNum);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), response[response.getLength() - 2], response[response.getLength() - 1]);
+
+ return result;
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+
+ return result;
+ }
+ }
+
+ /* select aid */
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelNum, aid);
+ rv = terminal->transmitSync(command, selectResponse);
+ if (rv == 0 && selectResponse.getLength() >= 2)
+ {
+ ResponseHelper resp(selectResponse);
+
+ if (resp.getStatus() == 0)
+ {
+ result = client->openChannel(sessionID, channelNum);
+ if (result != IntegerHandle::INVALID_HANDLE)
+ {
+ ServerChannel *temp = (ServerChannel *)client->getChannel(result);
+ if (temp != NULL)
+ {
+ /* set select response */
+ temp->selectResponse = selectResponse;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("IS IT POSSIBLE??????????????????");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("channel is null.");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), selectResponse[selectResponse.getLength() - 2], selectResponse[selectResponse.getLength() - 1]);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, selectResponse.getLength());
+ }
+
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("getClient is failed [%d] [%d]", socket, context);
+ }
+
+ return result;
+ }
+
+ Channel *ServerResource::getChannel(int socket, unsigned int context, unsigned int channelID)
+ {
+ Channel *result = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, context)) != NULL)
+ {
+ result = instance->getChannel(channelID);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("Channel doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, channelID);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeChannel(int socket, unsigned int context, unsigned int channelID)
+ {
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, context)) != NULL)
+ {
+ instance->closeChannel(channelID);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+ }
+ }
+
+ AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
+ {
+ AccessControlList *result = NULL;
+ map<Terminal *, AccessControlList *>::iterator item;
+
+ if ((item = mapACL.find(terminal)) == mapACL.end())
+ {
+ ServerChannel *channel = new ServerChannel(NULL, NULL, 0, terminal);
+ if (channel != NULL)
+ {
+ /* load access control */
+ result = new GPSEACL(channel);
+ if (result != NULL)
+ {
+ result->loadACL();
+
+ mapACL.insert(make_pair(terminal, result));
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ }
+ }
+ else
+ {
+ result = item->second;
+ }
+
+ return result;
+ }
+
+ Terminal *ServerResource::createInstance(void *library)
+ {
+ Terminal *terminal = NULL;
+ terminal_create_instance_fn createInstance = NULL;
+
+ /* create se instance */
+ createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
+ if (createInstance != NULL)
+ {
+ terminal = (Terminal *)createInstance();
+ if (terminal != NULL)
+ {
+ SCARD_DEBUG("terminal [%p]", terminal);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("terminal is null");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("create_instance is null [%d]", errno);
+ }
+
+ return terminal;
+ }
+
+ bool ServerResource::appendSELibrary(char *library)
+ {
+ void *libHandle = NULL;
+ bool result = false;
+
+ libHandle = dlopen(library, RTLD_LAZY);
+ if (libHandle != NULL)
+ {
+ Terminal *terminal = NULL;
+
+ terminal = createInstance(libHandle);
+ if (terminal != NULL)
+ {
+ unsigned int handle = IntegerHandle::assignHandle();
+
+ mapTerminals.insert(make_pair(handle, terminal));
+ libraries.push_back(libHandle);
+
+ terminal->setStatusCallback(&ServerResource::terminalCallback);
+
+ SCARD_DEBUG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
+
+ result = true;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("terminal is null [%s]", library);
+
+ dlclose(libHandle);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("it is not se file [%s] [%d]", library, errno);
+ }
+
+ return result;
+ }
+
+ int ServerResource::loadSecureElements()
+ {
+ int result;
+ void *libHandle;
+ DIR *dir = NULL;
+ struct dirent *entry = NULL;
+
+ if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
+ {
+ while ((entry = readdir(dir)) != NULL)
+ {
+ if (strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0)
+ {
+ char fullPath[1024] = { 0, };
+
+ /* TODO : need additional name rule :) */
+
+ /* open each files */
+ libHandle = NULL;
+
+ snprintf(fullPath, sizeof(fullPath), "%s/%s", OMAPI_SE_PATH, entry->d_name);
+
+ SCARD_DEBUG("se name [%s]", fullPath);
+
+ result = appendSELibrary(fullPath);
+ }
+ }
+
+ closedir(dir);
+
+ result = 0;
+ }
+ else
+ {
+ result = -1;
+ }
+
+ return result;
+ }
+
+ void ServerResource::unloadSecureElements()
+ {
+ size_t i;
+ map<unsigned int, Terminal *>::iterator item;
+
+ for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
+ {
+ item->second->finalize();
+
+ IntegerHandle::releaseHandle(item->first);
+ }
+
+ mapTerminals.clear();
+
+ for (i = 0; i < libraries.size(); i++)
+ {
+ if (libraries[i] != NULL)
+ dlclose(libraries[i]);
+ }
+
+ libraries.clear();
+ }
+
+ bool ServerResource::isValidReaderHandle(unsigned int reader)
+ {
+ return (getTerminal(reader) != NULL);
+ }
+
+ bool ServerResource::isValidSessionHandle(int socket, unsigned int context, unsigned int session)
+ {
+ ServiceInstance *instance = NULL;
+
+ return (((instance = getService(socket, context)) != NULL) && (getService(socket, context)->isVaildSessionHandle(session)));
+ }
+
+ int ServerResource::getReadersInformation(ByteArray &info)
+ {
+ int result = 0;
+ unsigned char *buffer = NULL;
+ unsigned int length = 0;
+ unsigned int offset = 0;
+ unsigned int nameLen = 0;
+
+ if (mapTerminals.size() > 0)
+ {
+ map<unsigned int, Terminal *>::iterator item;
+
+ for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
+ {
+ if (item->second->isSecureElementPresence())
+ {
+ length += sizeof(nameLen) + strlen(item->second->getName()) + sizeof(unsigned int);
+ result++;
+ }
+ }
+
+ buffer = new unsigned char[length];
+ if (buffer != NULL)
+ {
+ memset(buffer, 0, length);
+
+ for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
+ {
+ if (item->second->isSecureElementPresence())
+ {
+ nameLen = strlen(item->second->getName());
+
+ memcpy(buffer + offset, &nameLen, sizeof(nameLen));
+ offset += sizeof(nameLen);
+
+ memcpy(buffer + offset, item->second->getName(), nameLen);
+ offset += nameLen;
+
+ memcpy(buffer + offset, &item->first, sizeof(unsigned int));
+ offset += sizeof(unsigned int);
+ }
+ }
+
+ info.setBuffer(buffer, length);
+ delete []buffer;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ result = -1;
+ }
+ }
+ else
+ {
+ SCARD_DEBUG("no secure element");
+ }
+
+ return result;
+ }
+
+ bool ServerResource::sendMessageToAllClients(Message &msg)
+ {
+ bool result = true;
+ map<int, ClientInstance *>::iterator item;
+
+ for (item = mapClients.begin(); item != mapClients.end(); item++)
+ {
+ if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
+ result = false;
+ }
+
+ return result;
+ }
+
+ void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
+ {
+ SCARD_BEGIN();
+
+ switch (event)
+ {
+ case Terminal::NOTIFY_SE_AVAILABLE :
+ {
+ Message msg;
+
+ SCARD_DEBUG("[NOTIFY_SE_AVAILABLE]");
+
+ SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
+
+ /* send all client to refresh reader */
+ msg.message = msg.MSG_NOTIFY_SE_INSERTED;
+ msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+
+ ServerResource::getInstance().sendMessageToAllClients(msg);
+ }
+ break;
+
+ case Terminal::NOTIFY_SE_NOT_AVAILABLE :
+ {
+ Message msg;
+
+ SCARD_DEBUG("[NOTIFY_SE_NOT_AVAILABLE]");
+
+ SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
+
+ /* send all client to refresh reader */
+ msg.message = msg.MSG_NOTIFY_SE_REMOVED;
+ msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+
+ ServerResource::getInstance().sendMessageToAllClients(msg);
+ }
+ break;
+
+ default :
+ break;
+ }
+
+ SCARD_END();
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <errno.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Message.h"
+#include "TerminalInterface.h"
+#include "ServerSEService.h"
+#include "ServerResource.h"
+
+namespace smartcard_service_api
+{
+#define OMAPI_SE_PATH "/usr/lib/se"
+
+ ServerSEService::ServerSEService():SEServiceHelper()
+ {
+#if 0
+ openSELibraries();
+#endif
+ }
+
+ ServerSEService::~ServerSEService()
+ {
+#if 0
+ closeSELibraries();
+#endif
+ }
+
+ ServerSEService &ServerSEService::getInstance()
+ {
+ static ServerSEService seService;
+
+ return seService;
+ }
+
+ Terminal *ServerSEService::createInstance(void *library)
+ {
+ Terminal *terminal = NULL;
+ terminal_create_instance_fn createInstance = NULL;
+
+ /* create se instance */
+ createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
+ if (createInstance != NULL)
+ {
+ terminal = (Terminal *)createInstance();
+ if (terminal != NULL)
+ {
+ SCARD_DEBUG("terminal [%p]", terminal);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("terminal is null");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("create_instance is null [%d]", errno);
+ }
+
+ return terminal;
+ }
+
+ bool ServerSEService::appendSELibrary(char *library)
+ {
+ void *libHandle = NULL;
+ bool result = false;
+
+ libHandle = dlopen(library, RTLD_LAZY);
+ if (libHandle != NULL)
+ {
+ Terminal *terminal = NULL;
+
+ terminal = createInstance(libHandle);
+ if (terminal != NULL)
+ {
+ SCARD_DEBUG("SE info : [%s] [%s]", library, terminal->getName());
+
+ libraries.push_back(libHandle);
+
+ pair<char *, Terminal *> newPair(terminal->getName(), terminal);
+ mapTerminals.insert(newPair);
+
+ if (terminal->isSecureElementPresence() == true)
+ {
+ ServerReader *reader = new ServerReader(this, terminal->getName(), terminal);
+ if (reader != NULL)
+ {
+ SCARD_DEBUG("register success [%s]", terminal->getName());
+
+ readers.push_back(reader);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("ServerReader alloc failed [%s]", terminal->getName());
+ /* throw exception */
+ }
+ }
+ else
+ {
+ SCARD_DEBUG("SE is not ready [%s]", terminal->getName());
+ }
+
+ result = true;
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("createInstance failed [%s]", library);
+
+ dlclose(libHandle);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("it is not se file [%s] [%d]", library, errno);
+ }
+
+ return result;
+ }
+
+ int ServerSEService::openSELibraries()
+ {
+ int result;
+ void *libHandle;
+ DIR *dir = NULL;
+ struct dirent *entry = NULL;
+
+ if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
+ {
+ while ((entry = readdir(dir)) != NULL)
+ {
+ if (strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0)
+ {
+ char fullPath[1024] = { 0, };
+
+ /* need additional name rule :) */
+ /* open each files */
+ libHandle = NULL;
+
+ snprintf(fullPath, sizeof(fullPath), "%s/%s", OMAPI_SE_PATH, entry->d_name);
+
+ SCARD_DEBUG("se name [%s]", fullPath);
+
+ result = appendSELibrary(fullPath);
+ }
+ }
+
+ closedir(dir);
+
+ result = 0;
+ }
+ else
+ {
+ result = -1;
+ }
+
+ return result;
+ }
+
+ void ServerSEService::closeSELibraries()
+ {
+ if (libraries.size() > 0)
+ {
+ size_t i;
+
+ for (i = 0; i < libraries.size(); i++)
+ {
+ if (libraries[i] != NULL)
+ dlclose(libraries[i]);
+ }
+ }
+ }
+
+#if 0
+ bool ServerSEService::isValidReaderHandle(void *handle)
+ {
+ bool result = false;
+ size_t i;
+
+ for (i = 0; i < readers.size(); i++)
+ {
+ if ((void *)readers[i] == handle)
+ {
+ result = true;
+ break;
+ }
+ }
+
+ return false;
+ }
+#endif
+
+#if 0
+ bool ServerSEService::dispatcherCallback(void *message, int socket)
+ {
+ unsigned char *buffer = NULL;
+ unsigned int length = 0;
+ unsigned int offset = 0;
+ unsigned int nameLen = 0;
+
+ ByteArray result;
+ vector<ReaderHelper *> readers;
+ Message response(*(Message *)message);
+
+// response.param1 = resource->getSECount();
+// response.data = resource->getReadersInformation();
+
+ readers = ServerSEService::getInstance().getReaders();
+ if (readers.size() > 0)
+ {
+ size_t i;
+ ServerReader *reader;
+
+ for (i = 0; i < readers.size(); i++)
+ {
+ reader = (ServerReader *)readers[i];
+
+ /* check se existance */
+ if (reader->isSecureElementPresent() == true)
+ {
+ length += sizeof(nameLen) + strlen(reader->getName()) + sizeof(reader);
+ }
+ }
+
+ if (length > 0)
+ {
+ buffer = new unsigned char[length];
+ if (buffer == NULL)
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+
+ return false;
+ }
+ memset(buffer, 0, length);
+
+ for (i = 0; i < readers.size(); i++)
+ {
+ reader = (ServerReader *)readers[i];
+
+ /* check se existance */
+ if (reader->isSecureElementPresent() == true)
+ {
+ nameLen = strlen(reader->getName());
+
+ memcpy(buffer + offset, &nameLen, sizeof(nameLen));
+ offset += sizeof(nameLen);
+
+ memcpy(buffer + offset, reader->getName(), nameLen);
+ offset += nameLen;
+
+ memcpy(buffer + offset, &reader, sizeof(reader));
+ offset += sizeof(reader);
+ }
+ }
+
+ result.setBuffer(buffer, length);
+ }
+ }
+
+ response.param1 = readers.size();
+ response.data = result;
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+
+ return true;
+ }
+#else
+ bool ServerSEService::dispatcherCallback(void *message, int socket)
+ {
+ int count = 0;
+ ByteArray info;
+ Message *msg = (Message *)message;
+ Message response(*msg);
+ ServerResource &resource = ServerResource::getInstance();
+
+ if (resource.getService(socket, msg->error) == NULL)
+ {
+ if (resource.createService(socket, msg->error) == true)
+ {
+ SCARD_DEBUG_ERR("client added : pid [%d]", msg->error);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("createClient failed");
+
+ response.param1 = 0;
+ response.error = -1;
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+
+ return false;
+ }
+ }
+
+ if ((count = resource.getReadersInformation(info)) > 0)
+ {
+ response.param1 = count;
+ response.param2 = 0;
+ response.error = 0;
+ response.data = info;
+ }
+ else
+ {
+ SCARD_DEBUG("no secure elements");
+
+ response.error = -1;
+ }
+
+ /* response to client */
+ ServerIPC::getInstance()->sendMessage(socket, &response);
+
+ return false;
+ }
+#endif
+
+ void ServerSEService::terminalCallback(void *terminal, int event, int error, void *user_param)
+ {
+ Message msg;
+// Terminal *term = NULL;
+
+ switch (event)
+ {
+ case Terminal::NOTIFY_SE_AVAILABLE :
+ {
+ /* add right se reader */
+// if ((term = ServerResource::getInstance().getTerminal((char *)terminal)) != NULL)
+// {
+// SCARD_DEBUG("terminal : [%s]", (char *)terminal);
+//
+// term->initialize();
+// }
+// else
+// {
+// SCARD_DEBUG("unknown terminal : [%s]", (char *)terminal);
+// }
+
+ /* send all client to refresh reader */
+ msg.message = msg.MSG_NOTIFY_SE_INSERTED;
+ msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+
+ ServerResource::getInstance().sendMessageToAllClients(msg);
+ }
+ break;
+
+ case Terminal::NOTIFY_SE_NOT_AVAILABLE :
+ {
+ /* remove right se reader */
+// if ((term = ServerResource::getInstance().getTerminal((char *)terminal)) != NULL)
+// {
+// SCARD_DEBUG("terminal : [%s]", (char *)terminal);
+//
+// term->finalize();
+// }
+// else
+// {
+// SCARD_DEBUG("unknown terminal : [%s]", (char *)terminal);
+// }
+
+ /* send all client to refresh reader */
+ msg.message = msg.MSG_NOTIFY_SE_REMOVED;
+ msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+
+ ServerResource::getInstance().sendMessageToAllClients(msg);
+ }
+ break;
+
+ default :
+ break;
+ }
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <dlfcn.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServerSession.h"
+#include "ServerReader.h"
+#include "ServerChannel.h"
+#include "APDUHelper.h"
+#include "GPSEACL.h"
+
+namespace smartcard_service_api
+{
+ ServerSession::ServerSession(ServerReader *reader, ByteArray packageCert, void *caller, Terminal *terminal):SessionHelper(reader)
+ {
+ this->caller = NULL;
+ this->terminal = NULL;
+
+ if (caller == NULL || terminal == NULL)
+ {
+ SCARD_DEBUG_ERR("invalid param");
+
+ return;
+ }
+
+ this->caller = caller;
+ this->terminal = terminal;
+ this->packageCert = packageCert;
+ }
+
+ ServerSession::~ServerSession()
+ {
+ if (isClosed() == false)
+ closeSync();
+ }
+
+ ByteArray ServerSession::getATRSync()
+ {
+ /* call get atr to terminal */
+ return atr;
+ }
+
+ void ServerSession::closeSync()
+ {
+ if (isClosed() == false)
+ {
+ closed = true;
+ closeChannels();
+ }
+ }
+
+ void ServerSession::closeChannels()
+ {
+ size_t i;
+
+ for (i = 0; i < channels.size(); i++)
+ {
+ if (channels[i] != NULL)
+ channels[i]->closeSync();
+ }
+
+ channels.clear();
+ }
+
+ Channel *ServerSession::openBasicChannelSync(ByteArray aid)
+ {
+ return openBasicChannelSync(aid, NULL);
+ }
+
+ Channel *ServerSession::openBasicChannelSync(ByteArray aid, void *caller)
+ {
+ ServerChannel *channel = NULL;
+ AccessControlList *acList = NULL;
+ ByteArray command, result;
+ int channelID = 0;
+ int rv = 0;
+
+ SCARD_BEGIN();
+
+ acList = ((ServerReader *)reader)->getAccessControlList();
+ if (acList == NULL)
+ {
+ SCARD_DEBUG_ERR("acList is null");
+
+ return channel;
+ }
+
+ if (acList->isAuthorizedAccess(aid, packageCert) == false)
+ {
+ SCARD_DEBUG_ERR("unauthorized access, aid %s, hash %s", aid.toString(), packageCert.toString());
+
+ return channel;
+ }
+
+ /* select aid */
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelID, aid);
+ rv = terminal->transmitSync(command, result);
+ if (rv == 0 && result.getLength() >= 2)
+ {
+ ResponseHelper resp(result);
+
+ if (resp.getStatus() == 0)
+ {
+ channel = new ServerChannel(this, caller, channelID, terminal);
+ if (channel != NULL)
+ {
+ channel->selectResponse = result;
+
+ channels.push_back(channel);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, result.getLength());
+ }
+
+ return channel;
+ }
+
+ Channel *ServerSession::openBasicChannelSync(unsigned char *aid, unsigned int length)
+ {
+ return openBasicChannelSync(ByteArray(aid, length));
+ }
+
+ Channel *ServerSession::openBasicChannelSync(unsigned char *aid, unsigned int length, void *caller)
+ {
+ return openBasicChannelSync(ByteArray(aid, length), caller);
+ }
+
+ Channel *ServerSession::openLogicalChannelSync(ByteArray aid)
+ {
+ return openLogicalChannelSync(aid, NULL);
+ }
+
+ Channel *ServerSession::openLogicalChannelSync(ByteArray aid, void *caller)
+ {
+ ServerChannel *channel = NULL;
+ AccessControlList *acList = NULL;
+ ByteArray command, result;
+ int channelID = 1;
+ int rv;
+
+ acList = ((ServerReader *)reader)->getAccessControlList();
+ if (acList == NULL)
+ {
+ SCARD_DEBUG_ERR("unauthorized access, aid %s, hash %s");
+
+ return channel;
+ }
+
+ if (acList->isAuthorizedAccess(aid, packageCert) == false)
+ {
+ SCARD_DEBUG_ERR("unauthorized access, aid %s, hash %s", aid.toString(), packageCert.toString());
+
+ return channel;
+ }
+
+ /* open channel */
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
+ rv = terminal->transmitSync(command, result);
+
+ if (rv == 0 && result.getLength() >= 2)
+ {
+ ResponseHelper resp(result);
+
+ if (resp.getStatus() == 0)
+ {
+ channelID = resp.getDataField()[0];
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+
+ return channel;
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, result.getLength());
+
+ return channel;
+ }
+
+ /* select aid */
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelID, aid);
+ rv = terminal->transmitSync(command, result);
+
+ if (rv == 0 && result.getLength() >= 2)
+ {
+ ResponseHelper resp(result);
+
+ if (resp.getStatus() == 0)
+ {
+ channel = new ServerChannel(this, caller, channelID, terminal);
+ if (channel == NULL)
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+
+ return NULL;
+ }
+
+ channel->selectResponse = result;
+
+ channels.push_back(channel);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, result.getLength());
+ }
+
+ return channel;
+ }
+
+ Channel *ServerSession::openLogicalChannelSync(unsigned char *aid, unsigned int length)
+ {
+ return openLogicalChannelSync(ByteArray(aid, length), NULL);
+ }
+
+ Channel *ServerSession::openLogicalChannelSync(unsigned char *aid, unsigned int length, void *caller)
+ {
+ return openLogicalChannelSync(ByteArray(aid, length), caller);
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 "ServiceInstance.h"
+#include "ClientInstance.h"
+#include "ServerResource.h"
+
+namespace smartcard_service_api
+{
+ unsigned int ServiceInstance::openSession(Terminal *terminal, ByteArray packageCert, void *caller)
+ {
+ unsigned int handle = IntegerHandle::assignHandle();
+
+ ServerSession *session = new ServerSession((ServerReader *)0, packageCert, caller, terminal);
+
+ mapSessions.insert(make_pair(handle, make_pair(session, terminal)));
+
+ return handle;
+ }
+
+ ServerSession *ServiceInstance::getSession(unsigned int session)
+ {
+ ServerSession *result = NULL;
+ map<unsigned int, pair<ServerSession *, Terminal *> >::iterator item;
+
+ if ((item = mapSessions.find(session)) != mapSessions.end())
+ {
+ /*if (item->second.first == session)*/
+ result = item->second.first;
+ }
+
+ return result;
+ }
+
+ Terminal *ServiceInstance::getTerminal(unsigned int session)
+ {
+ Terminal *result = NULL;
+ map<unsigned int, pair<ServerSession *, Terminal *> >::iterator item;
+
+ if ((item = mapSessions.find(session)) != mapSessions.end())
+ {
+ result = item->second.second;
+ }
+
+ return result;
+ }
+
+ void ServiceInstance::closeSession(unsigned int session)
+ {
+ map<unsigned int, pair<ServerSession *, Terminal *> >::iterator item;
+
+ if ((item = mapSessions.find(session)) != mapSessions.end())
+ {
+ closeChannelsBySession(session);
+
+ item->second.first->closeSync();
+
+ mapSessions.erase(item);
+
+ IntegerHandle::releaseHandle(session);
+ }
+ }
+
+ void ServiceInstance::closeSessions()
+ {
+ map<unsigned int, pair<ServerSession *, Terminal *> >::iterator item;
+
+ closeChannels();
+
+ for (item = mapSessions.begin(); item != mapSessions.end(); item++)
+ {
+ item->second.first->closeSync();
+
+ IntegerHandle::releaseHandle(item->first);
+ }
+
+ mapSessions.clear();
+ }
+
+ unsigned int ServiceInstance::openChannel(unsigned int session, int channelNum)
+ {
+ Terminal *terminal = getTerminal(session);
+ ServerChannel *channel = NULL;
+ unsigned int handle = -1;
+
+ /* create ServerChannel */
+ channel = new ServerChannel((ServerSession *)session, (void *)parent->getPID(), channelNum, terminal);
+ if (channel != NULL)
+ {
+ handle = IntegerHandle::assignHandle();
+ mapChannels.insert(make_pair(handle, make_pair(session, channel)));
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("alloc failed");
+ }
+
+ return handle;
+ }
+
+ ServerChannel *ServiceInstance::getChannel(/*unsigned int session, */unsigned int channel)
+ {
+ ServerChannel *result = NULL;
+ map<unsigned int, pair<unsigned int, ServerChannel *> >::iterator item;
+
+ if ((item = mapChannels.find(channel)) != mapChannels.end())
+ {
+ /*if (item->second.first == session)*/
+ result = item->second.second;
+ }
+
+ return result;
+ }
+
+ unsigned int ServiceInstance::getChannelCountBySession(unsigned int session)
+ {
+ unsigned int channelCount = 0;
+ map<unsigned int, pair<unsigned int, ServerChannel *> >::iterator item;
+
+ for (item = mapChannels.begin(); item != mapChannels.end(); item++)
+ {
+ if (item->second.first == session)
+ channelCount++;
+ }
+
+ return channelCount;
+ }
+
+ void ServiceInstance::closeChannel(unsigned int channel)
+ {
+ map<unsigned int, pair<unsigned int, ServerChannel *> >::iterator item;
+
+ if ((item = mapChannels.find(channel)) != mapChannels.end())
+ {
+ /* destroy ServerChannel */
+ delete item->second.second;
+
+ mapChannels.erase(item);
+
+ IntegerHandle::releaseHandle(channel);
+ }
+ }
+
+ void ServiceInstance::closeChannelsBySession(unsigned int session)
+ {
+ size_t i;
+ vector<unsigned int> list;
+ map<unsigned int, pair<unsigned int, ServerChannel *> >::iterator item;
+
+ for (item = mapChannels.begin(); item != mapChannels.end(); item++)
+ {
+ if (item->second.first == session)
+ list.push_back(item->second.first);
+ }
+
+ for (i = 0; i < list.size(); i++)
+ {
+ closeChannel(list[i]);
+ }
+ }
+
+ void ServiceInstance::closeChannels()
+ {
+ map<unsigned int, pair<unsigned int, ServerChannel *> >::iterator item;
+
+ for (item = mapChannels.begin(); item != mapChannels.end(); item++)
+ {
+ /* destroy ServerChannel */
+ delete item->second.second;
+
+ IntegerHandle::releaseHandle(item->first);
+ }
+
+ mapChannels.clear();
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 CLIENTINSTANCE_H_
+#define CLIENTINSTANCE_H_
+
+/* standard library header */
+#include <map>
+//#include <hash_map>
+
+/* SLP library header */
+
+/* local header */
+#include "Message.h"
+#include "ServiceInstance.h"
+
+namespace smartcard_service_api
+{
+ class ClientInstance
+ {
+ private:
+ void *ioChannel;
+ int socket;
+ int watchID;
+ int state;
+ int pid;
+ ByteArray certHash;
+
+ map<unsigned int, ServiceInstance *> mapServices;
+
+ inline ByteArray getCertificationHash() { return certHash; }
+
+ public:
+ ClientInstance(void *ioChannel, int socket, int watchID, int state, int pid)
+ {
+ this->ioChannel = ioChannel;
+ this->socket = socket;
+ this->watchID = watchID;
+ this->state = state;
+ this->pid = pid;
+ }
+ ~ClientInstance() { removeServices(); }
+
+ inline bool operator ==(const int &socket) const { return (this->socket == socket); }
+
+ inline void *getIOChannel() { return ioChannel; }
+ inline int getSocket() { return socket; }
+ inline int getWatchID() { return watchID; }
+ inline int getState() { return state; }
+
+ void setPID(int pid);
+ inline int getPID() { return pid; }
+
+
+ bool createService(unsigned int context);
+ ServiceInstance *getService(unsigned int context);
+ void removeService(unsigned int context);
+ void removeServices();
+
+ bool sendMessageToAllServices(int socket, Message &msg);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* CLIENTINSTANCE_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SERVERCHANNEL_H_
+#define SERVERCHANNEL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Channel.h"
+#include "Terminal.h"
+#include "ServerSession.h"
+
+namespace smartcard_service_api
+{
+ class ServerChannel: public Channel
+ {
+ private:
+ Terminal *terminal;
+ void *caller;
+
+ ServerChannel(ServerSession *session, void *caller, int channelNum, Terminal *terminal);
+
+ protected:
+ void closeSync();
+ int transmitSync(ByteArray command, ByteArray &result);
+
+ public:
+ ~ServerChannel();
+
+ int getChannelNumber();
+
+ int close(closeCallback callback, void *userParam) { return -1; }
+ int transmit(ByteArray command, transmitCallback callback, void *userParam) { return -1; };
+
+ friend class ServerReader;
+ friend class ServerSession;
+ friend class ServiceInstance;
+ friend class ServerResource;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERCHANNEL_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SERVERDISPATCHER_H_
+#define SERVERDISPATCHER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "DispatcherHelper.h"
+
+namespace smartcard_service_api
+{
+ class ServerIPC;
+
+ class ServerDispatcher: public DispatcherHelper
+ {
+ private:
+ ServerDispatcher();
+ ~ServerDispatcher();
+
+ void *dispatcherThreadFunc(DispatcherMsg *msg, void *data);
+
+ public:
+
+ static ServerDispatcher *getInstance();
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERDISPATCHER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SERVERIPC_H_
+#define SERVERIPC_H_
+
+/* standard library header */
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "IPCHelper.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class ServerIPC: public IPCHelper
+ {
+ private:
+ ServerIPC();
+ ~ServerIPC();
+
+ bool acceptClient();
+ void restartServerIPC();
+ void releaseClient(void *channel, int socket, int watchID);
+
+ int handleIOErrorCondition(void *channel, GIOCondition condition);
+ int handleInvalidSocketCondition(void *channel, GIOCondition condition);
+ int handleIncomingCondition(void *channel, GIOCondition condition);
+
+ public:
+ static ServerIPC *getInstance();
+
+ friend class ServerResource;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERIPC_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SERVERREADER_H_
+#define SERVERREADER_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "Terminal.h"
+#include "ReaderHelper.h"
+#include "ServerSession.h"
+#include "ServerChannel.h"
+#include "AccessControlList.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class ServerSEService;
+
+ class ServerReader : public ReaderHelper
+ {
+ private:
+ Terminal *terminal;
+ ServerChannel *adminChannel;
+ AccessControlList *acList;
+
+ ServerReader(ServerSEService *seService, char *name, Terminal *terminal);
+
+ int openSession(openSessionCallback callback, void *userData) { return -1; }
+ int openSession(void *caller, openSessionCallback callback, void *userData) { return -1; }
+
+ public:
+ ~ServerReader();
+
+ void closeSessions();
+
+ AccessControlList *getAccessControlList();
+
+ ServerSession *openSessionSync();
+ ServerSession *openSessionSync(ByteArray packageCert, void *caller);
+
+ friend class ServerSEService;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERREADER_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SERVERRESOURCE_H_
+#define SERVERRESOURCE_H_
+
+/* standard library header */
+#include <map>
+#include <vector>
+#include <set>
+
+/* SLP library header */
+
+/* local header */
+#include "Terminal.h"
+#include "Lock.h"
+#include "ServerIPC.h"
+#include "ServerDispatcher.h"
+#include "ServerReader.h"
+#include "ServerSession.h"
+#include "ClientInstance.h"
+#include "ServiceInstance.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class IntegerHandle
+ {
+ private:
+ static unsigned int newHandle;
+ static set<unsigned int> setHandles;
+ static PMutex mutexLock;
+
+ public:
+ static const unsigned int INVALID_HANDLE = (unsigned int)-1;
+
+ static unsigned int assignHandle();
+ static void releaseHandle(unsigned int);
+ };
+
+ class ServerResource
+ {
+ private:
+ /* non-static member */
+ vector<void *> libraries;
+ map<unsigned int, Terminal *> mapTerminals; /* unique id <-> terminal instance map */
+ map<int, ClientInstance *> mapClients; /* client pid <-> client instance map */
+ map<Terminal *, AccessControlList *> mapACL; /* terminal instance <-> access control instance map */
+
+ ServerIPC *serverIPC;
+ ServerDispatcher *serverDispatcher;
+
+ ServerResource();
+ ~ServerResource();
+
+ Terminal *createInstance(void *library);
+ bool appendSELibrary(char *library);
+ void clearSELibraries();
+
+ static void terminalCallback(void *terminal, int event, int error, void *user_param);
+
+ public:
+ /* static member */
+ static ServerResource &getInstance();
+
+ /* non-static member */
+ int loadSecureElements();
+ void unloadSecureElements();
+
+ Terminal *getTerminal(unsigned int terminalID);
+ Terminal *getTerminal(const char *name);
+ int getReadersInformation(ByteArray &info);
+ bool isValidReaderHandle(unsigned int reader);
+
+ bool createClient(void *ioChannel, int socket, int watchID, int state, int pid);
+ ClientInstance *getClient(int socket);
+ void setPID(int socket, int pid);
+ void removeClient(int socket);
+ void removeClients();
+
+ bool createService(int socket, unsigned int context);
+ ServiceInstance *getService(int socket, unsigned int context);
+ void removeService(int socket, unsigned int context);
+ void removeServices(int socket);
+
+ unsigned int createSession(int socket, unsigned int context, unsigned int terminalID, ByteArray packageCert, void *caller);
+ ServerSession *getSession(int socket, unsigned int context, unsigned int sessionID);
+ unsigned int getChannelCount(int socket, unsigned int context, unsigned int sessionID);
+ void removeSession(int socket, unsigned int context, unsigned int session);
+ bool isValidSessionHandle(int socket, unsigned int context, unsigned int sessionID);
+
+ unsigned int createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid);
+ Channel *getChannel(int socket, unsigned int context, unsigned int channelID);
+ void removeChannel(int socket, unsigned int context, unsigned int channelID);
+
+ AccessControlList *getAccessControlList(Terminal *terminal);
+
+ bool sendMessageToAllClients(Message &msg);
+
+ friend void terminalCallback(void *terminal, int event, int error, void *user_param);
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERRESOURCE_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SERVERSESERVICE_H_
+#define SERVERSESERVICE_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "SEServiceHelper.h"
+#include "Terminal.h"
+#include "ServerReader.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class ServerSEService : public SEServiceHelper
+ {
+ private:
+ vector<void *> libraries;
+ map<char *, Terminal *> mapTerminals;
+
+ ServerSEService();
+ ~ServerSEService();
+
+ Terminal *createInstance(void *library);
+ bool appendSELibrary(char *library);
+
+ int openSELibraries();
+ void closeSELibraries();
+
+ static void terminalCallback(void *terminal, int event, int error, void *user_param);
+ static bool dispatcherCallback(void *message, int socket);
+
+ public:
+ static ServerSEService &getInstance();
+
+#if 0
+ bool isValidReaderHandle(void *handle);
+#endif
+ friend void terminalCallback(char *name, int event, int error, void *user_param);
+ friend bool dispatcherCallback(void *message, int socket);
+ friend class ServerDispatcher;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERSESERVICE_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SERVERSESSION_H_
+#define SERVERSESSION_H_
+
+/* standard library header */
+#include <vector>
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+#include "Channel.h"
+#include "Terminal.h"
+#include "SessionHelper.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class ServerReader;
+
+ class ServerSession : public SessionHelper
+ {
+ private:
+ void *caller;
+ Terminal *terminal;
+ ByteArray packageCert;
+
+ ServerSession(ServerReader *reader, ByteArray packageCert, void *caller, Terminal *terminal);
+
+ int getATR(getATRCallback callback, void *userData){ return -1; }
+ int close(closeSessionCallback callback, void *userData){ return -1; }
+
+ int openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData){ return -1; }
+ int openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData){ return -1; }
+ int openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData){ return -1; }
+ int openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData){ return -1; }
+ public:
+ ~ServerSession();
+
+ ByteArray getATRSync();
+ void closeSync();
+
+ void closeChannels();
+
+ Channel *openBasicChannelSync(ByteArray aid);
+ Channel *openBasicChannelSync(unsigned char *aid, unsigned int length);
+ Channel *openBasicChannelSync(ByteArray aid, void *caller);
+ Channel *openBasicChannelSync(unsigned char *aid, unsigned int length, void *caller);
+
+ Channel *openLogicalChannelSync(ByteArray aid);
+ Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length);
+ Channel *openLogicalChannelSync(ByteArray aid, void *caller);
+ Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length, void *caller);
+
+ friend class ServerReader;
+ friend class ServerResource;
+ friend class ServiceInstance;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERSESSION_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 SERVICEINSTANCE_H_
+#define SERVICEINSTANCE_H_
+
+/* standard library header */
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "Terminal.h"
+#include "ServerChannel.h"
+#include "ServerSession.h"
+
+namespace smartcard_service_api
+{
+ class ClientInstance;
+
+ class ServiceInstance
+ {
+ private:
+ unsigned int context;
+ ClientInstance *parent;
+ map<unsigned int, pair<ServerSession *, Terminal *> > mapSessions; /* session unique id <-> terminal instance map */
+ map<unsigned int, pair<unsigned int, ServerChannel *> > mapChannels; /* channel unique id <-> (session unique id, channel instance) map */
+
+ public:
+ ServiceInstance(ClientInstance *parent, unsigned int context)
+ {
+ this->parent = parent;
+ this->context = context;
+ }
+ ~ServiceInstance() { closeSessions(); };
+
+ inline bool operator ==(const unsigned int &context) const { return (this->context == context); }
+ inline bool isVaildSessionHandle(unsigned int handle) { return (mapSessions.find(handle) != mapSessions.end()); }
+ inline bool isVaildChannelHandle(unsigned int handle) { return (mapChannels.find(handle) != mapChannels.end()); }
+ inline ClientInstance *getParent() { return parent; }
+
+ unsigned int openSession(Terminal *terminal, ByteArray packageCert, void *caller);
+ ServerSession *getSession(unsigned int session);
+ void closeSession(unsigned int session);
+ void closeSessions();
+
+ Terminal *getTerminal(unsigned int session);
+
+ unsigned int openChannel(unsigned int session, int channelNum);
+ ServerChannel *getChannel(/*unsigned int session, */unsigned int channel);
+ unsigned int getChannelCountBySession(unsigned int session);
+ void closeChannel(unsigned int channel);
+ void closeChannelsBySession(unsigned int session);
+ void closeChannels();
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVICEINSTANCE_H_ */
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <glib.h>
+#include <vector>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Channel.h"
+#include "ServerResource.h"
+#include "ServerSEService.h"
+
+/* definition */
+using namespace std;
+using namespace smartcard_service_api;
+
+/* global variable */
+
+ServerResource *serverResource = NULL;
+
+static void daemonize(void)
+{
+ pid_t pid, sid;
+
+ /* already a daemon */
+ if (getppid() == 1)
+ return;
+
+ /* Fork off the parent process */
+ pid = fork();
+ if (pid < 0)
+ {
+ exit(EXIT_FAILURE);
+ }
+
+ if (pid > 0)
+ {
+ exit(EXIT_SUCCESS); /*Killing the Parent Process*/
+ }
+
+ /* At this point we are executing as the child process */
+ umask(0);
+
+ /* Create a new SID for the child process */
+ sid = setsid();
+ if (sid < 0)
+ {
+ exit(EXIT_FAILURE);
+ }
+
+ /* Change the current working directory. */
+ if ((chdir("/")) < 0)
+ {
+ exit(EXIT_FAILURE);
+ }
+
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+}
+
+int main()
+{
+ GMainLoop* loop = NULL;
+
+ daemonize();
+
+ if (!g_thread_supported())
+ {
+ g_thread_init(NULL);
+ }
+
+ serverResource = &ServerResource::getInstance();
+ ServerIPC::getInstance()->createListenSocket();
+
+ loop = g_main_new(TRUE);
+ g_main_loop_run(loop);
+
+ return 0;
+}
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(smartcard-test-client CXX)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../client/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ SRCS)
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+ SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_test_client REQUIRED glib-2.0 gthread-2.0 gobject-2.0 security-server vconf dlog)
+
+FOREACH(flag ${pkgs_test_client_CFLAGS})
+ SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+MESSAGE("CHECK MODULE in ${PROJECT_NAME} ${pkgs_test_client_LDFLAGS}")
+
+# this for NFC flag
+
+SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -pipe -fomit-frame-pointer -Wall -Wno-trigraphs -fno-strict-aliasing -Wl,-zdefs -fvisibility=hidden")
+
+SET(ARM_CXXFLAGS "${ARM_CXXLAGS} -mapcs -mno-sched-prolog -mabi=aapcs-linux -mno-thumb-interwork -msoft-float -Uarm -fno-common -fpic")
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+ ADD_DEFINITIONS("-DTARGET")
+ MESSAGE("add -DTARGET")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM_CXXFLAGS}")
+ENDIF()
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+#ADD_DEFINITIONS("-DSLP_DEBUG")
+
+ADD_DEFINITIONS("-DLOG_TAG=\"SCARD_TEST\"")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_test_client_LDFLAGS} "-L../common" "-lsmartcard-service-common" "-L../client" "-lsmartcard-service" "-pie -ldl")
+
+#INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
--- /dev/null
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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.
+*/
+
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+
+#include "Debug.h"
+#include "SEService.h"
+#include "Reader.h"
+#include "Session.h"
+#include "APDUHelper.h"
+
+using namespace smartcard_service_api;
+
+typedef struct _user_context_t
+{
+ Session *clientSession;
+ SEServiceHelper *clientService;
+ Channel *clientChannel;
+}
+user_context_t;
+
+/* global variable */
+GMainLoop *loop = NULL;
+user_context_t user_context = { 0, };
+
+void testCloseCallback(int error, void *userData);
+void testTransmitCallback(unsigned char *buffer, unsigned int length, int error, void *userData);
+void testOpenChannelCallback(Channel *channel, int error, void *userData);
+void testGetATRCallback(unsigned char *atr, unsigned int length, int error, void *userData);
+void testCloseSessionCallback(int error, void *userData);
+void testOpenSessionCallback(SessionHelper *session, int error, void *userData);
+void testConnectedCallback(SEServiceHelper *service, void *context);
+
+class TestEventHandler : public SEServiceListener
+{
+ void serviceConnected(SEServiceHelper *service, void *userData)
+ {
+ SCARD_BEGIN();
+ testConnectedCallback(service, userData);
+ SCARD_END();
+ }
+
+ void eventHandler(SEServiceHelper *service, char *seName, int event, void *userData)
+ {
+ SCARD_BEGIN();
+
+ SCARD_DEBUG("event occured service [%p], seName[%p], event [%d]", service, seName, event);
+
+ SCARD_END();
+ }
+
+ void errorHandler(SEServiceHelper *service, int error, void *userData)
+ {
+ SCARD_BEGIN();
+
+ SCARD_DEBUG("error occured service [%p], error [%d]", service, error);
+
+ SCARD_END();
+ }
+};
+
+TestEventHandler testEventHandler;
+
+void testCloseCallback(int error, void *userData)
+{
+ user_context_t *context = (user_context_t *)userData;
+
+ SCARD_DEBUG("result [%d], userData [%p]", error, userData);
+
+ context->clientService->shutdown();
+}
+
+void testTransmitCallback(unsigned char *buffer, unsigned int length, int error, void *userData)
+{
+ ByteArray response(buffer, length);
+ user_context_t *context = (user_context_t *)userData;
+
+ SCARD_DEBUG("buffer [%p], length [%d], error [%d], userData [%p]", buffer, length, error, userData);
+
+ context->clientChannel->close(testCloseCallback, userData);
+}
+
+void testOpenChannelCallback(Channel *channel, int error, void *userData)
+{
+ SCARD_DEBUG("channel [%p]", channel);
+
+ if (error == 0 && channel != NULL)
+ {
+ ByteArray response;
+ ByteArray data, command;
+ int fid = 0x00003150;
+ user_context_t *context = (user_context_t *)userData;
+
+ context->clientChannel = channel;
+
+ response = channel->getSelectResponse();
+
+ SCARD_DEBUG("response : %s", response.toString());
+
+ SCARD_DEBUG("isBasicChannel() = %s", channel->isBasicChannel() ? "Basic" : "Logical");
+ SCARD_DEBUG("isClosed() = %s", channel->isClosed() ? "Closed" : "Opened");
+
+ data.setBuffer((unsigned char *)&fid, 2);
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, data);
+ context->clientChannel->transmit(command, testTransmitCallback, userData);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("openBasicChannel failed");
+ }
+}
+
+void testGetATRCallback(unsigned char *atr, unsigned int length, int error, void *userData)
+{
+// unsigned char MF[] = { 0x3F, 0x00 };
+ unsigned char MF[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
+ ByteArray aid, result(atr, length);
+ user_context_t *context = (user_context_t *)userData;
+
+ SCARD_DEBUG("atr[%d] : %s", result.getLength(), result.toString());
+
+ aid.setBuffer(MF, sizeof(MF));
+ context->clientSession->openLogicalChannel(aid, testOpenChannelCallback, userData);
+}
+
+void testCloseSessionCallback(int error, void *userData)
+{
+
+}
+
+void testOpenSessionCallback(SessionHelper *session, int error, void *userData)
+{
+ SCARD_DEBUG("session [%p]", session);
+
+ if (session != NULL)
+ {
+ user_context_t *context = (user_context_t *)userData;
+
+ context->clientSession = (Session *)session;
+ context->clientSession->getATR(testGetATRCallback, userData);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("openSession failed");
+ }
+}
+
+void testConnectedCallback(SEServiceHelper *service, void *userData)
+{
+ vector<ReaderHelper *> readers;
+ user_context_t *context = (user_context_t *)userData;
+
+ SCARD_BEGIN();
+
+ if (service != NULL)
+ {
+ SCARD_DEBUG("callback called, service [%p]", service);
+
+ context->clientService = service;
+
+ readers = service->getReaders();
+
+ if (readers.size() > 0)
+ {
+ Reader *reader = NULL;
+
+ reader = (Reader *)readers[0];
+
+ SCARD_DEBUG("reader [%p]", reader);
+
+ reader->openSession(testOpenSessionCallback, userData);
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("reader is empty");
+ }
+ }
+ else
+ {
+ SCARD_DEBUG_ERR("service is NULL");
+ }
+
+ SCARD_END();
+}
+
+int main(int argv, char *args[])
+{
+ SEService *service = new SEService((void *)&user_context, &testEventHandler);
+
+ loop = g_main_new(TRUE);
+ g_main_loop_run(loop);
+
+ if (service != NULL)
+ delete service;
+
+ return 0;
+}